Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> В чем отличия указателя от ссылки? 
:(
    Опции темы
Wowa
Дата 13.1.2005, 03:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
Group Icon


Профиль
Группа: Админ
Сообщений: 15017
Регистрация: 14.9.2000
Где: Винград

Репутация: нет
Всего: 290



В чем отличия указателя от ссылки?
Добавлено @ 03:27
приведите, пожалуйста, пример указателя и ссылки.
PM WWW   Вверх
chipset
Дата 13.1.2005, 03:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4071
Регистрация: 11.1.2003
Где: Seattle, US

Репутация: 27
Всего: 165



Через указатель к примеру передаются массивы.... Через передачу переменной по ссылке так сделать нельзя.


--------------------
Цитата(Jimi Hendrix)
Well, I stand up next to a mountain
And I chop it down with the edge of my hand
PM MAIL WWW   Вверх
Guest
Дата 13.1.2005, 09:52 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Код

//Указатель
int *ptr = new int;
*ptr = 5; //Разименование указателя
cout << *ptr; //Вывести значение
cout << *ptr; //Вывести адрес


Ссылку можно назвать автоматически разименованным указателем..
Код

int t = 7;
int& k = t;
++k;
cout << t; //Напечатает 8


Ссылки можно использовать например так
Код

void function( const string& t ) //Здесь при передаче обьекта типа стринг функции копия не создается (економия памяти однако)
{

}



  Вверх
azesmcar
Дата 13.1.2005, 09:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



извиняюсь, здесь маленькая ошибка

Код

//Указатель
int *ptr = new int;
*ptr = 5; //Разименование указателя
cout << *ptr; //Вывести значение
cout << ptr; //Вывести адрес
delete ptr;

Добавлено @ 09:58
Если убрать const в примере
Код

void function( const string& t ) //Здесь при передаче обьекта типа стринг функции копия не создается (економия памяти однако)
{

}

можно будет изменять значение строки и в той функции которая вызывает function переданная переменная будет изменена в соответствии с изменениями в функции function...

Тут еще кучу примеров можно привести...
PM   Вверх
bel_nikita
Дата 13.1.2005, 10:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Ссылка - это ссылка smile Т.е. она ссылается на объект в памяти. Т.е. определяя ссылку, необходимо с помощью начального значения определить тот объект(участок памяти), на который указывает ссылка. Функционально ссылка ведет себя подобно обычной переменной того же типа. Для доступа к содержимому участка памяти, на который "смотрит" ссылка, нет необходимости явно выполнять разыменование, как это нужно для указателя.
Код

int L = 777; // Определена и инициализирована переменная L
int& RL = L; // Значение ссылки RL является адрес переменной L
int *ptr = &L; // указатель на объект L типа int

Например:
Код
RL -= 77;
уменьшает на 77 значение переменной L.
Связав ссылку RL с переменной L, получаем возможность изменять значение переммой двумя способами:
Код
RL = 123;
L = 123;

Также через указатель:
Код
*ptr = 456;



--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
sergejzr
Дата 13.1.2005, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 19
Всего: 360



A теперь внимамие, правильный ответ: smile smile smile

Грубо говоря это - одно и тоже. Ссылка - замаскированный указатель.

Вот так мы работаем с указателем:
Код А:
Код

void set( int *func_n)// в переменную  func_n скопируется значение с которым мы функцию вызвали
{
* func_n=3; //изменение содержмого естественно меняет значение нашей n из main'a
}
int main()
{
int n=3;
int * pointer_n=&n;//теперь pointer_n показывает на n. Изменение содержимого будет менять значение n.
* pointer_n=4; // Вот так. Теперь n у нас стала 4.

set(pointer_n);//передаём в функцию указатель на n.
cout<<n<<endl;//теперь n опять 3.
n=4;
set(&n);// по существу тут то же самое. Только здесь компилер для нас создаст указатель
cout<<n<<endl; //теперь n опять 3.
return 0;
}


А что со сылками?
Код В:
Код

void set( int &reference_n){
reference_n=3;
}
int main(){
int n=3;
int &reference_n=n;
reference_n=4;

set(reference_n);
cout<<n<<endl;
n=4;
set(n);
cout<<n<<endl;
return 0;
}

да тоже самое, эти два кода эквивалентны. (в комментарах из A замените указатель на ссылку)
Компилер сделает из кода B код A. строка в строку.

Так зачем эта неразбериха, которая из года в год путает студентов, спросите вы?
Единственный ответ в красоте кода. Кто когда нибуть писал на Си с применение множества указателей, поймёт.
Эти вечные (&n), *n=6, итд. Просто вырубают наповал. Если давать переменным короткие названия, то весь код будет из звездей и & состоять. smile smile smile

Надеюсь, смог помочь разобраться smile


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
DENNN
Дата 13.1.2005, 19:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 3878
Регистрация: 27.3.2002
Где: Москва

Репутация: 1
Всего: 43



Цитата
Единственный ответ в красоте кода.

вот и нетsmile
К примеру если в функцию в качестве параметров передаются ссылки, то это дает дополнительную гарантию, что в при вызове этой функции будут переданны реальные значения, а не указатели "в никуда". Отсюда, в частности следует, что такой способ передачи параметров избавляет нас от проверки указателей на "валидность". Отсюда также следует, что при необходимости передачи в функцию массива неизвестной на этапе компиляции длины указатель может быть более удобен, чем использование ссылки.
Добавлено @ 19:58
Цитата
Эти вечные (&n), *n=6, итд. Просто вырубают наповал.

Ну это уж вообще абсолютно субъективное мнение. Я например предпочитаю смотреть в код и видеть, какие же операции выполнит процессор в каждой строчке.
PM ICQ   Вверх
sergejzr
Дата 13.1.2005, 20:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 19
Всего: 360



Цитата(DENNN @ 13.1.2005, 18:56)
К примеру если в функцию в качестве параметров передаются ссылки, то это дает дополнительную гарантию, что в при вызове этой функции будут переданны реальные значения, а не указатели "в никуда". Отсюда, в частности следует, что такой способ передачи параметров избавляет нас от проверки указателей на "валидность". Отсюда также следует, что при необходимости передачи в функцию массива неизвестной на этапе компиляции длины указатель может быть более удобен, чем использование ссылки.

а так?

Код
int &reference;
set(reference);

Цитата(DENNN @ 13.1.2005, 18:56)
Ну это уж вообще абсолютно субъективное мнение. Я например предпочитаю смотреть в код и видеть, какие же операции выполнит процессор в каждой строчке.

Да я тоже smile когда в свой. А вот чужой код намного читабельней становится(если автор придерживался правила не изменять значение аргументов в функциях).


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Fantasist
Дата 13.1.2005, 20:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Цитата(sergej @ 13.1.2005, 17:04)
а так?

int &reference;
set(reference);



А так ошибка компиляции. Ссылка должны быть инициализированна в месте ее объявления, за исключением того случая, когда ссылка является полем класса - в этом случае она должна быть инициализированна в списки инициализации конструктора. Ссылку невозможно изменить - все операции над ссылкой это операции над объектом на который она ссылается. Несмотря на это ссылка тем не менее может оказатся невалидной, если объект на который она ссылается будет удален. Один из типичных случаев:

Код

std::string& get_str()
{
  std::string new_string;

   ............ делаем новую строку.....

   return new_string;    
}  


С точки зрения синтаксиса все правильно, однако объект new_string будет удален при выходе из функции и ссылка будет возвращена невалидная. Хороший компилятор в этом месте выдает предупреждение, что возращается ссылка на стековый объект. Тем не менее, случай может оказатся более замаскированным, так что компилятор его не заметит:

Код

string& get_str()
{
  auto_ptr<string> new_string=new string();

   ............ делаем новую строку.....

   return *new_string;    
}  


Здесь компилятор не сомжет догадаться, что auto_ptr удалит объект указатель на который он содержит при выходе из функции и ссылка опять таки получится невалидной.


Добавлено @ 20:48
Цитата(sergej @ 13.1.2005, 17:04)
(если автор придерживался правила не изменять значение аргументов в функциях)


В таком случае это должно быть явно указанно модификатором const для параметра функции. Язык С++ весьма гибок, чтобы большинство правил можно было бы выразить средствоми языка, а не на бумаге или в голове.

Это сообщение отредактировал(а) Fantasist - 13.1.2005, 21:23


--------------------
Волны гасят ветер...
PM MAIL   Вверх
sergejzr
Дата 13.1.2005, 21:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 19
Всего: 360



Цитата(Fantasist @ 13.1.2005, 19:44)
Ссылка должны быть инициализированна в месте ее объявления, за исключением того случая, когда ссылка является полем класса - в этом случае она должна быть инициализированна в списки инициализации конструктора.

Ага! Точно smile Это подстраховка компилятора. Сорри, не подумал. Хотя встречались компилеры, которые разрешали, но это нестандартные конечно, а "рукописные" smile
Но всмысле обьяснения отличия указателя от ссылки это всё равно smile Если предварительные проверки ОК, код В переводится в код А.
Цитата(Fantasist @ 13.1.2005, 19:44)
В таком случае это должно быть явно указанно модификатором const для параметра функции.

Ну да smile Ho это ведь к красоте кода отношения не имеет smile. Красота имхо именно из за отсутсвия "лишних" *&.


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Fantasist
Дата 13.1.2005, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Цитата(sergej @ 13.1.2005, 18:08)
Это подстраховка компилятора.


Это не подстраховка а принцип понятия ссылки. Обрати внимание на выделенную мной фразу - если ты ссылку не инициализируешь сразу у тебя не будет возможности сделать это потом.




--------------------
Волны гасят ветер...
PM MAIL   Вверх
DENNN
Дата 14.1.2005, 10:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 3878
Регистрация: 27.3.2002
Где: Москва

Репутация: 1
Всего: 43



Цитата
Ну да  Ho это ведь к красоте кода отношения не имеет . Красота имхо именно из за отсутсвия "лишних" *&.

Я минуту улыбался smile

Цитата
Но всмысле обьяснения отличия указателя от ссылки это всё равно

Как же это "все равно"?

Цитата
Цитата (DENNN @ 13.1.2005, 18:56)
Ну это уж вообще абсолютно субъективное мнение. Я например предпочитаю смотреть в код и видеть, какие же операции выполнит процессор в каждой строчке.

Да я тоже когда в свой. А вот чужой код намного читабельней становится(если автор придерживался правила не изменять значение аргументов в функциях).

Давайте все же проясним это туманное понятие "код становится читабельней". А то сейчас это философские рассуждения. Вот ты несколькими постами выше сказал:
Цитата
Эти вечные (&n), *n=6, итд. Просто вырубают наповал.

А я например невижу ничего особенного как в опреаци доступа по указателю, так и в операции взятия адреса. Такая же операция, как к примеру + - %
PM ICQ   Вверх
Tripl-X
Дата 24.1.2005, 23:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 29.12.2004

Репутация: 1
Всего: 1



'&' - получение адреса памяти, по которому находится переменная, а '*' - получение значения из адреса.

Вот тебе пример:

Код

int main(void)
{
int target, source;
int *m;

source=10;
m=&source;
target=*m;
printf("[%i][%i]", m, target);

return 0;


Это выведет на экран два разных числа...
Вобщем, если тебе нужно использовать значения переменной - используй *, а если адрес переменной - &.
PM MAIL ICQ   Вверх
PashaLost
Дата 29.10.2011, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 18.1.2008

Репутация: нет
Всего: нет



По-моему мнению, ветка не содержит ИСЧЕРПЫВАЮЩЕГО ответа на поставленный вопрос. И поэтому: 

УКАЗАТЕЛЬ - это АДРЕС переменной в чистом виде (00 12 FF 60) 
ССЫЛКА - это НЕИЗМЕННЫЙ скрытый указатель, являющийся ещё одним именем для переменной. 

В отличие от указателя, независимые ссылки ДОЛЖНЫ быть инициализированы. 
   Type &ID_ссылки=ID_объекта;

Ссылка должна быть явно инициализирована при её описании (если только она не является параметром функции (в этом случае инициализация произойдёт при замене формальных параметров фактическими) или не описана как extern - в этом случае она будет инициализирована в другом месте)

В отличие от указателя, мы не можем изменять значение ссылки (значение скрытого адреса). 

В отличие от указателя, операции над ссылкой приводят к изменению величины, на которую она ссылается. (для указателя, операции над указателем изменяют значение его адреса, а не содержимого по адресу)

Не существует указателей на ссылки (но существуют указатели на указатели), 
Не существует массивов ссылок (но существуют массивы указателей)
Не существует ссылок на ссылки

Функция не может быть перегружена, если описание её параметров отличается только наличием ссылки ( fun(int a), fun(int &a) )

Преимущества ссылок: 
  Не нужно работать с адресом переменной, он подразумевается автоматически
  Со ссылками работаем как с переменной (а не как с адресом переменной)
  Копия объекта не передаётся в функцию (при передаче параметров функции), а только скрытый адрес.
PM MAIL   Вверх
borisbn
Дата 29.10.2011, 17:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(PashaLost @  29.10.2011,  15:29 Найти цитируемый пост)
Преимущества ссылок: 

Сказал "А"...

Недостатки ссылок:
  • Если в ф-цию нужно передать объект по ссылке, а он по каким-либо причинам не может быть создан, но в случае с указателем принято передавать NULL (или 0 или nullptr). В случае со ссылкой такого сделать нельзя
  • Невозможно сделать вектор ссылок (без доп.обёрток). Вектор же указателей - самое обычное дело

Частая ошибка при использовании ссылок:
Код
A objA;
A objB;
A & refA = objA;
...
refA = objB;

В последней строке refA не начинает ссылаться на objB, а objB копируется в objA, как-будто мы написали objA = objB;

Я для себя установил одно простое правило: использовать указатели только в случае, когда использовать ссылки невозможно.
Есть, правда, одно исключение - const char * - да и то, если в заголовочном файле ещё не включен <string> smile


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1675 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.