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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Указатели и ссылки 
:(
    Опции темы
feodorv
Дата 19.9.2015, 08:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Цитата(_zorn_ @  19.9.2015,  07:05 Найти цитируемый пост)
Ты ведь так и не сказал, что с ним не так )))

Бог ты мой, мало кто не знаком с этим примером, и что он с собой несет; неважно как он при этом выглядит, хоть просто i = i++. Я же хотел вернуть Вас в русло темы, не более. Если уж Вы такой занудный, то давайте я начну.

  • Ссылка как тип введена в C++ (в С её нет). Ссылка и указатель - разные типы. Соответственно
    Код
    void func( int *ptr);
    и
    Код
    void func( int &ptr);
    разные функции.
  • Для указателя определена операция разыменования. Казалось бы мелочь в данном вопросе, а масса последствий. Например, для указателей можно спутать *ptr++ и (*ptr)++. С использованием ссылок можно писать такой код:
    Код
    func() = 0;
  • Указатель может указывать в любую область памяти процесса, его значение может быть изменено так, чтобы он указывал в другую область памяти. Ссылка всегда ссылается на одну и ту же область памяти, она обязана быть проинициализированной, к ней не может быть применена адресная арифметика.
  • Можно объявить указатель на указатель и т.д. Ссылки на ссылку не существует. Ссылка может указывать на указатель. Указатель не может указывать на ссылку.
  • В другой поток ссылку просто так не передашь. Указатель можно.
  • Константная ссылка может продлевать время жизни временного объекта, на который она указывает, константный указатель - нет.

И тут самое время задуматься над тонкостями rvalue/lvalue и &&. Но это уж Вы как-нибудь сами. Итого: хотя я и согласен с точкой зрения xvr, но когда я всё это описывал, моя уверенность в её справедливость сильно пошатнулась)))


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
feodorv
Дата 19.9.2015, 09:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Ещё. Никогда над этим не задумывался)))
  • Можно иметь массив указателей, массив ссылок - нет.
  • Размер (sizeof) указателя на массив естественно совпадает с размером указателя в системе, а размер ссылки на массив выдаёт честный размер массива.


Это сообщение отредактировал(а) feodorv - 21.9.2015, 09:35


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
drug007
Дата 21.9.2015, 11:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(feodorv @  18.9.2015,  12:02 Найти цитируемый пост)
Есть тонкости. Хотя бы. 

Ну я бы отнес это к нюансам выведения типов в шаблонах. Почему-то думается, что вряд ли имелось что-то вроде этого при вопросе "чем указатель отличается от ссылки". Но пример хороший.
PM MAIL   Вверх
baldina
Дата 21.9.2015, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

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



_zorn_, в вашем примере не только нет ссылок, но и вообще может быть что угодно в зависимости от типа i.

а то, что код не компилируется - понятно, лексический анализатор жаден, и код интерпретируется как i++ ++ +i, а постфиксные выражения группируются слева направо, так что для скалярных типов будет попытка изменить rvalue

основной "тонкостью" в ссылках vs указателях думаю стоит считать разницу в смысле выражений:
Код

type *p1=&x;
type *p2=&y;

type& r1=x;
type& r2=y;

p1 = p2; // указатель p1 изменился и указывает на y. 
r1 = r2;  // ссылка r1 не изменилась (по-прежнему ссылается на x), изменился x (стал равным y)

что является следствием главной особенности ссылки: она связывается со ссылаемым объектом единожды в момент инициализации.

Добавлено через 5 минут и 27 секунд
имхо удобно говорить о ссылках как об алиасах (альтернативных именах) уже объявленных переменных, тогда становится понятно и как работает, и искушения сравнивать с указателями не возникает. в этом русле и понимание rvalue reference мне кажется проще.
PM MAIL   Вверх
xvr
Дата 21.9.2015, 15:50 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(feodorv @  19.9.2015,  08:12 Найти цитируемый пост)
Итого: хотя я и согласен с точкой зрения xvr, но когда я всё это описывал, моя уверенность в её справедливость сильно пошатнулась))) 

Давайте переформулируем: указатель от ссылки отличается всем - это разные сущности языка С++. Можно с тем же успехом спрашивать чем отличается указатель и указатель на член класса (pointer & member pointer).
И то, что компилятор использует указатель для физической реализации ссылки дела не меняет.
Так что вопрос об отличии указателя и ссылки попросту некорректен  smile 

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


Бывалый
*


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

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



Цитата(xvr @  21.9.2015,  15:50 Найти цитируемый пост)
Так что вопрос об отличии указателя и ссылки попросту некорректен

И я такого же мнения. Если бы вопрос был о том, где лучше применять указатели, а где ссылки и почему - это уже совсем другой расклад.

@feodorv, а не проясните про этот код?
Код

func() = 0;

Функция возвращает ссылку и мы этой ссылке присваиваем значение?

Это сообщение отредактировал(а) drug007 - 22.9.2015, 10:16
PM MAIL   Вверх
volatile
Дата 22.9.2015, 12:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(drug007 @  22.9.2015,  10:11 Найти цитируемый пост)
Функция возвращает ссылку и мы этой ссылке присваиваем значение?

не ссылке (ссылке вообще нельзя присвоить значение, ее можно только инициализировать), а переменной на которую ссылается эта ссылка

Код

int a = 0;

int & func () {return a;}

int main ()
{
   printf ("a=%d\n", a);
   func () = 42;
   printf ("a=%d\n", a);
}


Добавлено через 3 минуты и 48 секунд
http://codepad.org/D2bBVPu2
PM MAIL   Вверх
drug007
Дата 22.9.2015, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(volatile @  22.9.2015,  12:21 Найти цитируемый пост)
не ссылке (ссылке вообще нельзя присвоить значение, ее можно только инициализировать), а переменной на которую ссылается эта ссылка

Я это и имел в виду. В принципе все просто, просто непривычная запись. В свое время сбил с толку default в switch'е вида:
Код

switch(foo)
{
    default:
    case 1:
    ....
}

Настолько привык, что default всегда последний. Привычки они не всегда полезные)
PM MAIL   Вверх
konshyn
Дата 23.10.2015, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(drug007 @  22.9.2015,  10:11 Найти цитируемый пост)
Цитата

Так что вопрос об отличии указателя и ссылки попросту некорректен

И я такого же мнения. Если бы вопрос был о том, где лучше применять указатели, а где ссылки и почему - это уже совсем другой расклад.


по-моему, вопрос более чем корректен. Ссылку на указатель можно создать, а вот указатель на ссылку - нет. 
Но что касается основного вопроса:
Цитата(drug007 @  15.9.2015,  11:37 Найти цитируемый пост)
Вот у меня вопрос - действительно ли есть эти самые подводные камни, что только опытные разработчики критически важных компонентов и владеют ими или все-таки это просто показывает уровень разработки в отдельно взятой организации? 

Считаю, что чтобы разрабатывать критически важные системы нужно знать и понимать все тонкости языка и все подводные камни, даже если их не используешь.
Так что это вполне закономерный вопрос для отсеивания кандидатов ниже определенного уровня.

Добавлено @ 14:07
Код

#include <iostream>

int main() {
    int a = 11;
    int &b = a;
    int *p = b; //  Указатель на ссылку не работат. error: invalid conversion from ‘int’ to ‘int*’ [-fpermissive]
    int *p = &b; // а так все хорошо
    int *&c = p; // Делаем ссылку на указатель
    std::cout << b << " " << *c << std::endl;
    return 0;
}


Главное не путать ссылки и операцию взятия адреса. Хоть для этого и требуется один и тот же символ - амперсант. &

Это сообщение отредактировал(а) konshyn - 26.10.2015, 11:24


--------------------
«Потому что ценность акта действия в этой стране возрастает в несколько раз».
PM MAIL Skype   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0620 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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