Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 34, средняя оценка - 4.82
Ksan
27 / 27 / 4
Регистрация: 02.11.2010
Сообщений: 370
#1

Ссылки vs Указатели - C++

10.07.2012, 18:54. Просмотров 4641. Ответов 81
Метки нет (Все метки)

Почему ссылки считаются более хорошим средством, чем указатели?
Ведь если человек будет использовать сторонние классы, он может не заметить, скажем
int &val
и не будет знать, что передается ссылка, а вовсе не копия. Это может повлечь за собой кучу неприятностей. Даже сам разработчик может спустя время забыть о злополучном знаке &. Так почему ссылки лучше?
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.07.2012, 18:54
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Ссылки vs Указатели (C++):

Указатели и ссылки
Экспериментируя с указателями пришел к вот таким выводам: int a;...

Указатели и ссылки c++
Здравствуйте! Не могли бы вы объяснить как можно использовать ссылки и...

Ссылки, указатели
Доброго времени. Как, используя ссылки, указатели и, возможно, другие приемы...

Указатели и ссылки
Собственно, не могу до конца осознать как это работает, вот пример из...

Указатели и ссылки?
Ниже приведёна программы которая вызывает функцию. В функции происходит...

Указатели и ссылки [С++]
Всем привет. я тут программу делаю. Цель: определить,принадлежит ли точка...

81
Avazart
Эксперт С++
7673 / 5582 / 541
Регистрация: 10.12.2010
Сообщений: 25,044
Записей в блоге: 17
14.07.2012, 11:29 #61
как бы вы тогда назвали const_iterator, если такое название по вашему нелепо?
Не думал об этом...
Но такое название явно не добавляет ясности, как у употребление выражения константная ссылка.
1
ForEveR
В астрале
Эксперт С++
7994 / 4753 / 651
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
14.07.2012, 11:39 #62
Avazart, Дело в привычке, для меня очевидно что если const_iterator - нельзя изменить данные, на которые указывает итератор, если const ссылка - нельзя изменить данные на которые она ссылается.
2
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
14.07.2012, 11:47 #63
Цитата Сообщение от ForEveR Посмотреть сообщение
на которые указывает итератор
Потому что из названия понятно, что сам итератор может изменяться, на то он и итератор. В неизменяемом итераторе просто нет смысла.
0
ForEveR
В астрале
Эксперт С++
7994 / 4753 / 651
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
14.07.2012, 11:49 #64
Deviaphan, Да, согласен, все-таки итератор - это паттерн и предназначен он для обхода коллекции.
0
silent_1991
Эксперт С++
5007 / 3065 / 270
Регистрация: 11.11.2009
Сообщений: 7,043
Завершенные тесты: 1
14.07.2012, 13:38 #65
Цитата Сообщение от IGPIGP Посмотреть сообщение
C++
1
cout<<foo(a, b, 0); //что в месте вызова видно?
В месте вызова видно, что мы передаём массивы (некоторая контекстная зависимость). Так что это другой случай, потому что по значению массив и не передашь.
Цитата Сообщение от IGPIGP Посмотреть сообщение
C++
1
cout<<foo(a, b, 0); //что в месте вызова видно?
А здесь видно (с учётом той же контекстной зависимости), что a и b - сами по себе указатели. Так что сразу ясно, что функция ожидает указатели, а не ссылки, иначе вызов выглядел бы так:
C++
1
cout << foo(*a, *b, 0);
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7002 / 3294 / 448
Регистрация: 04.12.2011
Сообщений: 9,113
Записей в блоге: 5
14.07.2012, 17:12 #66
Цитата Сообщение от silent_1991 Посмотреть сообщение
А здесь видно (с учётом той же контекстной зависимости), что a и b - сами по себе указатели.
Имеете в виду что объявления объектов где то рядом? Но это же не всегда и так. Если в контексте вопроса, то не видно ничего, что бы отличало эту функцию от любой другой принимающей в формальные параметры переменные по именам.
Самый сильный контекст это сигнатура и alex_x_x прав, на мой взгляд. Вопрос [ТС] интересен для меня в широком смысле. Не только при передаче в функцию. Тем более, что и ссылка и указатель в функцию копию не передаёт.
Тут хотелось бы поддержать Avazart, в том, что терминология не только запутана, но и противоречива. Противоречия не в логике, а именно в том как это звучит. Такое наблюдается, кстати, во многих более или менее обособленных отраслях знания. Опытные программисты часто не могут понять, что именно непонятно новичкам. В частности это касается указателей и ссылок. Когда впервые сталкиваешься с этим вопросом волосы встают дыбом. Б. Страуструп постоянно оговаривает, что синтаксис указателей - дань совместимости с С...
C++
1
2
3
4
int * a, *b, c;//объявление
a=&c;// присваивание адреса переменной
*a=c; //доступ c разименованием - присваивание значения
b=a; //присваивание
и это - цветочки, по сравнению с объявлением сложных типов, читаемых изнутри - наружу...
Для устранения, части неудобств работы с указателями при передаче в функцию (в основном) придуман специальный случай - ссылка. О ссылках и указателях выше сказано уже много.
Трудности восприятия синтаксиса, тема уходящая в С и сама по себе интересна, но мне хочется затронуть терминологию связанную с передачей аргументов в функцию, т.к. так поставлен вопрос в теме.
Имя - идентификатор для программиста. Компилятор пользуется целыми числами. То есть простое объявление и определение:
C++
1
int a=1;
связывает с некоторой областью памяти (4 байта на 32 системе) указатель, память заполняется единицей, с указателем связывается имя a. Имя нужно компилятору в исходнике, что бы генерировать код. В коде используется указатель. При этом в зависимости от того rvalue или lvalue представляет из себя а встреченное компилятором в каждом конкретном случае, код генерируется разный.
В C/C++ у программиста есть возможность получить доступ к памяти путём создания отдельной переменной хранящей адрес (номер байта), где расположено значение простой переменной (a). Эта переменная - указатель. Её можно объявить и связать с ней имя:
C++
1
int * pa=&a;//pa - имя переменной "указатель"
Интересно вот,что. Когда в функцию передается a, то принято говорить, что передаётся значение. Хотя передаётся копия! Когда же в функцию передаётся pa, то есть, непосредственно адрес переменной a, позволяющий сделать с a все, что угодно, - говорят, что передача - косвенная! Внутри машины это не так! Эта "косвенная" передача прямее и быстрее чем "по значению"! Она то и передаёт значение, в отличие от передачи по имени! Но есть устоявшаяся терминология и спорить с ней - безумие. Я и не спорю. Боже упаси. Однако для людей которые только начинают учить C++, может оказаться полезным взглянуть на эту терминологию прямо, а не косвенно.
Может и вредно оказаться тоже, - кому как пойдёт. Вот константная ссылка... Пример из той же оперы, - набор слов который не значит того, что слышится. Слава богу, что контекстная сила языка не только в этом. Этот блог - для тех кто только начинает. Опытных прошу не пинать.
0
silent_1991
Эксперт С++
5007 / 3065 / 270
Регистрация: 11.11.2009
Сообщений: 7,043
Завершенные тесты: 1
14.07.2012, 18:17 #67
Цитата Сообщение от IGPIGP Посмотреть сообщение
Самый сильный контекст это сигнатура
Моё мнение таково: если функция должна возвращать значения через изменение фактических параметров, нужно использовать указатели потому, что в общем случае это делает код чуть более самодокументированным. Потому что в общем случае вызов всё же будет выглядеть как foo(&a). Амперсанд как бы уже при вызове намекает "эй, я могу изменить значение параметра, осторожнее!". Ссылка же такого намёка не даёт.
1
ForEveR
В астрале
Эксперт С++
7994 / 4753 / 651
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
14.07.2012, 18:25 #68
silent_1991, В том же бусте много функций принимающих данные по ссылке и я думаю ни у кого с этим проблем не возникает.
1
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7002 / 3294 / 448
Регистрация: 04.12.2011
Сообщений: 9,113
Записей в блоге: 5
14.07.2012, 18:56 #69
Цитата Сообщение от silent_1991 Посмотреть сообщение
Моё мнение таково: если функция должна возвращать значения через изменение фактических параметров, нужно использовать указатели потому, что в общем случае это делает код чуть более самодокументированным.
С этим спорить нельзя. Б. Страуструп подчёркивает, где только возможно, что стиль - святое дело и выбор каждого. Понятно, что преимущества - продолжения недостатков и наоборот. Работая с указателями можно читая запись понять, что именно происходит. Недостаток в том, что запись может быть сложна. С коньяком - проще, - там только звёздочки, а тут ещё и скобки!
Ссылка, - компактнее и контекстно выразительнее. Но и внимания требует.
Запись с указателями бывает сложной. Для тех же, кто легко это читает, - конечно не проблема.
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
14.07.2012, 19:11 #70
Цитата Сообщение от IGPIGP Посмотреть сообщение
Самый сильный контекст это сигнатура
Сигнатура не имеет ничего общего с контекстом.
1
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7002 / 3294 / 448
Регистрация: 04.12.2011
Сообщений: 9,113
Записей в блоге: 5
14.07.2012, 19:37 #71
Цитата Сообщение от Deviaphan Посмотреть сообщение
Сигнатура не имеет ничего общего с контекстом.
Контекст это ситуация, - совокупность обстоятельств позволяющая выделить однозначное понимание, в принципе многозначного выражения. Сигнатура устраняет многозначность в контексте заданного [ТС] вопроса. Именно в этом контексте я и ожидал понимания фразы. Давайте мириться!
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
14.07.2012, 19:52 #72
Давай.)))
0
Avazart
Эксперт С++
7673 / 5582 / 541
Регистрация: 10.12.2010
Сообщений: 25,044
Записей в блоге: 17
14.07.2012, 20:28 #73
Тем более, что и ссылка и указатель в функцию копию не передаёт.
Копию объекта нет, зато передает копию указателя( в случае указателя)
1
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7002 / 3294 / 448
Регистрация: 04.12.2011
Сообщений: 9,113
Записей в блоге: 5
14.07.2012, 22:15 #74
Цитата Сообщение от Avazart Посмотреть сообщение
Копию объекта нет, зато передает копию указателя( в случае указателя)
Указатель на указатель имеете ввиду? Дык вот так мне кажется точнее:
C++
1
//<<Копию объекта нет, зато передает копию указателя( в случае указателя))))>> //cкобок должно быть справа 3n+1 от тех, что слева...
Тогда передаётся не адрес другого указателя, а адрес копии указателя! Ёще 3 скобки и можно передать, даже копию адреса копии, что означает трудно обозримое количество копий адресов на собственные же копии (адресов))).
0
silent_1991
Эксперт С++
5007 / 3065 / 270
Регистрация: 11.11.2009
Сообщений: 7,043
Завершенные тесты: 1
14.07.2012, 22:37 #75
IGPIGP, имеется ввиду, что функция, принимающая указатель, принимает адрес по значению. Отсюда и косвенность (о которой вы писали несколько сообщений назад), косвенность по отношению к объекту, который передаётся по указателю (ссылке), а программист (на языке высокого уровня) всё же должен мыслить объектами, а не ноликами и единичками.
1
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7002 / 3294 / 448
Регистрация: 04.12.2011
Сообщений: 9,113
Записей в блоге: 5
14.07.2012, 22:49 #76
Цитата Сообщение от silent_1991 Посмотреть сообщение
IGPIGP, имеется ввиду, что функция, принимающая указатель, принимает адрес по значению. Отсюда и косвенность
Я понял, что:
Цитата Сообщение от Avazart Посмотреть сообщение
( в случае указателя)
это когда указатель на указатель передаётся. Тогда, что бы не ломать голову, о каком именно указателе идет речь: - ))), то есть если компактнее то :-))).

Цитата Сообщение от silent_1991 Посмотреть сообщение
а программист (на языке высокого уровня) всё же должен мыслить объектами, а не ноликами и единичками.
Тут горячо согласен! Хотя если принять, что заряд в ячеёке - "объект", а разряд - "не объект"? То получается, что объект можно передать последовательностью объектов и необъектов! Мысль пока сырая и требует срочного осмысления... Подумаю и позже добавлю.)))
0
Toshkarik
1148 / 865 / 90
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
14.07.2012, 22:59 #77
IGPIGP, я конечно может быть не до конца понял Ваш ответ, но имеется ввиду любой указатель передается по значению, а не только при указатель на указатель.
1
alex_x_x
бжни
2454 / 1660 / 134
Регистрация: 14.05.2009
Сообщений: 7,162
14.07.2012, 23:10 #78
Цитата Сообщение от silent_1991 Посмотреть сообщение
Отсюда и косвенность (о которой вы писали несколько сообщений назад), косвенность по отношению к объекту, который передаётся по указателю (ссылке), а программист (на языке высокого уровня) всё же должен мыслить объектами, а не ноликами и единичками.
в джаве и шарпе например все объекты передаются по ссылке, и никак по месту вызова не определить меняется там объект или нет
& как раз признак низкоуровневого языка

переходить от высокоуровневой конструкции ссылки (четко закреплена за объектом) к низкоуровневой указателя (вокруг одни violation) с телегой разыменований в самой функции..
это высокоуровневость?
0
Avazart
Эксперт С++
7673 / 5582 / 541
Регистрация: 10.12.2010
Сообщений: 25,044
Записей в блоге: 17
14.07.2012, 23:53 #79
Указатель на указатель имеете ввиду?
Нет,имелся ввиду именно указатель

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int i=5,j=10;
 
int *pi = &i;
int *pj = &j;
 
void f(int *pi)
{
 pi=pj; // pi лишь локальная копия глобального pi
}
 
f(pi); // не изменит i и pi
 
cout<<i<<endl;
cout<<(*pi)<<endl;
1
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7002 / 3294 / 448
Регистрация: 04.12.2011
Сообщений: 9,113
Записей в блоге: 5
15.07.2012, 00:32 #80
Цитата Сообщение от Avazart Посмотреть сообщение
Нет,имелся ввиду именно указатель
Понял. В примере я написал функцию возвращающую указатель того же типа, что и переданные.
Когда я привёл пример с массивами, а потом с объектами, тема уже затихла.
Захотелось поразмышлять о том, что передавая указатели и не знакомясь с сигнатурой вызова, огрести тоже можно.
Функция возвращает такой указатель на тип как и переданный. И если он где то ожидается, то гибель локальных переменных не спасает. Кроме того модифицировать значение указателя (непреднамеренно) и вернуть тоже можно. Но это и плохо, так как компилируется, как раз без проблем. И в месте вызова ничего не видно.
Случай конечно узкий, и подумав признаю: пример когда доступ к значению в функции не предусмотрен, - некорректен.
0
15.07.2012, 00:32
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.07.2012, 00:32
Привет! Вот еще темы с решениями:

Ссылки и указатели
Добрый день, не могу понять чем помогают при использовании указатели и ссылки?...

Указатели и ссылки
Используя вместо самой переменной указатель на нее написать программу в...

Указатели и ссылки
Допустим, что есть функция, в которую мы кидаем массив по указателю и кол-ву...

Указатели и Ссылки
извеняюсь,но никак не могу понять. int sum(int* inLeft, int* inRight) { ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
80
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru