Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.55/75: Рейтинг темы: голосов - 75, средняя оценка - 4.55
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32

Ссылки vs указатели - в чем разница?

21.11.2015, 20:04. Показов 17079. Ответов 150
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Навеяно соседней темой. Не понимаю в чем разница, хотя несколько раз честно пробовал почитать на эту тему, правда без должного внимания и усердия. Зато программировал на ассемблере и чистом С, понимаю абстракцию "адрес ячейки памяти" и "размер типа в байтах", с арифметикой указателей и указателями на указатели сложностей вроде не испытываю Есть переменная, если она не регистровая - то лежит в какой-то ячейке памяти (или нескольких, зависит от разрядности памяти и структуры типа переменной), адрес этой ячейки (ака указатель) я могу запоминать в другую переменную типа указателя, передавать/возвращать ее из функций, инкрементировать/декрементировать для движения по массиву переменных (если я его предварительно нарезал в той области памяти конечно), разыменовывать и получать/изменять значение. Вроде все. При чем тут термин "ссылки"? А еще оказывается бывают смартпоинтеры, умные указатели и прочие страшные слова
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
21.11.2015, 20:04
Ответы с готовыми решениями:

Указатели и ссылки: в чем разница
Здравствуйте, объясните, пожалуйста, в чем разница между "ссылается" и "указывает"?

Указатели и ссылки: в чём их разница и сходство?
Я начал учить с++ и не могу кое в чём разобраться. Кто знает ответы на эти вопросы может ответить или скинуть какую нибудь ссылку где это...

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

150
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
30.11.2015, 15:56
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Evg Посмотреть сообщение
Тут есть важный момент из разряда "под капотом": обе функции (та, куда инлайнят и та, кого инлайнят) должны находиться в одной единице компиляции.
Если константа внешняя, например, то и не повезёт наверное.

Добавлено через 14 минут
Цитата Сообщение от IGPIGP Посмотреть сообщение
Он похож на ссылку, но в отличие от неё может быть неинициализирован в объявлении:
Нашёл!
DrOffset,

Действительно досочинялся... Сам запутался!
Константный указатель и ссылка по поведению в данном контексте равны и я написал в том месте чушь. Прошу модераторов убрать:

Цитата Сообщение от IGPIGP
Он похож на ссылку, но в отличие от неё может быть неинициализирован в объявлении:
C++
1
 int * const ptr;
а потом где-то:
C++
1
ptr = &a;//а - ранее созданная константа
ссылка таких вещей не допускает и это важное отличие!
DrOffset, ещё раз спасибо, - действительно серьёзная неточность.
отличие инициализации ссылок и указателей есть, но если сравнивать с константным, то нет.
1
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
30.11.2015, 16:02
Цитата Сообщение от IGPIGP Посмотреть сообщение
Я говорил о константной ссылке (ссылке на константу если строго) и указателе на константу. Указатель на константу это не константа.
В таком случае код и комментарии к нему не соответствуют тому, о чем говорилось.
Так как в коде написан имено КОНСТАНТНЫЙ УКАЗАТЕЛЬ, а не указатель на константу.

Вот слова:
Можно также объявить константный указатель:
C++
1
int * const ptr = &a;
Он похож на ссылку, но в отличие от неё может быть неинициализирован в объявлении:
C++
1
int * const ptr;
а потом где-то:
C++
1
ptr = &a;//а - ранее созданная константа
Вот эти слова "может быть неинициализирован ... константный указатель".
Цитировал как есть.

Добавлено через 51 секунду
Цитата Сообщение от IGPIGP Посмотреть сообщение
Нашёл!
Слава богу Я уже думать начал, что надо мной издеваются
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
30.11.2015, 16:04
Цитата Сообщение от DrOffset Посмотреть сообщение
Я уже думать начал, что надо мной издеваются
Да, перемкнуло на ходу когда сочинял...
там комент про заранее созданную константу и это должна то была идти речь о сравнении константной ссылки и указателя на константу а не константного указателя! Короче, сам попался там, где хотел газету расстелить.
Может так ещё понятней будет?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
03.12.2015, 00:24
Цитата Сообщение от Nosey Посмотреть сообщение
еслиб мы могли написать int& const r = v;
для ссылок не существует квалификатора const и точка.

вижал студия сделает предупреждение, что квалификатор пошел лесом.
другие компили могут просто послать.
например, гцц

Добавлено через 6 минут
Цитата Сообщение от daslex Посмотреть сообщение
fr(x)+=fr(x);

здесь - ub
0
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,886
03.12.2015, 00:26
В Microsoft Visual Studio существует много чего существовать не должно. Там, например, такой квалификатор существует и он пропускается как устаревший. Т.е. он на мгновение есть во время компиляции. Но студия ему делает "аборт".
такой код в студии валиден, но квалификатор как раз лишний, во время выполнения программы его не будет.
C++
1
2
const int a = 100;
    const int& const x = a;
Добавлено через 1 минуту
Цитата Сообщение от hoggy Посмотреть сообщение
здесь - ub
да. ub.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
03.12.2015, 01:34
Цитата Сообщение от hoggy Посмотреть сообщение
для ссылок не существует квалификатора const и точка.
Он у неё внутри.
Цитата Сообщение от hoggy Посмотреть сообщение
вижал студия сделает предупреждение, что квалификатор пошел лесом.
Псевдо код:
C++
1
const int a=....
и
C++
1
const (const a)=...
одно const избыточно, но сути оно не меняет. Ничего в основании мироздания не дрогнет если компилятор, это понимает. Может чуть-лучше станет, хотя дело вкуса.
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
03.12.2015, 08:44
Цитата Сообщение от IGPIGP Посмотреть сообщение
Ничего в основании мироздания не дрогнет если компилятор, это понимает.
В основании мироздания от наших мелких проблем вообще ничего не дрогнет.

Однако, если программист думал, что это не повредит и писал таким образом код. А потом через 3 года проект решили перенести на другую платформу, где компилятор не допускает таких вольностей, то проблему это определенно создаст.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
03.12.2015, 11:41
Цитата Сообщение от DrOffset Посмотреть сообщение
Однако, если программист думал, что это не повредит и писал таким образом код.
А кто говорил, что это нужно писать? Я говорил, что из-за того что ссылка константна по природе и для облегчения произношения ссылку на константу называют константной ссылкой, чего с указателем никогда, будучи в своём уме, не делают, так как указатель бывает и указателем на константу и константным указателем. Причём, эта вольность, так глубоко укоренилась, что никому странной не кажется. Однако ошибка, которую я допустив механически попутав константный указатель с указателем на константу показывает, что вольности тут, действительно излишни.
Я пытался как раз и сказать о различии константности ссылок как таковой и поведения ссылок на константу. О путанице и о том, что запись для ссылки-константы (настоящей константной ссылки) не имеет смысла так как они и так константы. Мой компилятор допускает такую запись.
Что касается переносимости, то люди которые пишут кроссплатформенно, обычно имеют значительно более высокий уровень, чем тот что требуется для понимания пагубности записи:
C++
1
Type & const refName;
Иначе говоря, те кто не понимает не напишут такого кода (хотя бы по объёму) который за 15 минут нельзя пробежать на компиляторе который заругался и навсегда понять, что делать так больше не нужно.
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
03.12.2015, 11:55
IGPIGP, я объяснил почему плохо. когда компилятор пропускает нестандартные конструкции.
Вы, допустим, не предлагали так писать, но и не утверждали обратного. Я вот утверждаю обратное, безотносительно ваших слов. Просто потому, что это опасно. Это форум, вы высказали мнение, что ничего страшного нет, если компилятор это поддерживает, а я говорю, что страшное есть, т.к. всегда есть такая вещь, как человеческий фактор. Пусть тот, кто это потом прочитает, сам делает выводы из сказанного.

Про человеческий фактор:
Был реальный пример, когда человек насмотрелся на код стандартной библиотеки и писал имена параметров функций начиная с двух подчеркиваний. Ну вот стиль такой, говорил он. Вроде бы ничего страшного, да вот только стандарт запрещает такое использование в пользовательском коде, т.к. имена с подчеркиваний зарезервированы для внутренних нужд. И вот в один прекрасный момент, при переносе его кода на другой компилятор все развалилось, т.к. среди имен, которые он таким образом давал, оказалось пара ключевых слов из состава расширений компилятора.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
03.12.2015, 18:22
Цитата Сообщение от DrOffset Посмотреть сообщение
я объяснил почему плохо. когда компилятор пропускает нестандартные конструкции
Я совершенно согласен. Но тут Вы обобщаете. Майкрософт это конечно не показатель. У них полно нестандартного, но я уже проклинаю себя за то, что обронил фразу о безвредности такого положения дел. Это был ответ на возражение и не имеет отношения к теме ссылок, указателей и того чём шла речь.
Цитата Сообщение от DrOffset Посмотреть сообщение
вы высказали мнение, что ничего страшного нет, если компилятор это поддерживает, а я говорю, что страшное есть, т.к. всегда есть такая вещь, как человеческий фактор
Хех... Есть совсем немного языков которые реализуют ввод-вывод на уровне библиотек. С/С++ позволяют такое, что человеческий фактор, это пожалуй главное. От него нельзя абстрагироваться. Любой подгузник это накладные расходы и ограничение свободы. Я считаю, что главный фактор безопасности, это человеческий.
Давайте так: Вы правы. Точка.

Добавлено через 6 часов 7 минут
Ещё хочу вспомнить, что параметр объявленный как константная ссылка кроме подсказки компилятору о возможности оптимизации, кроме получения возможности передачи константы и строкового литерала, в частности, позволяет ещё строго выдержать контракт "конструктор не возвращает значений". В случае конструктора преобразования константная ссылка защищает передаваемый параметр от модификации. В то же время такая возможность существует (на правах хака)).
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
struct A
{
int a;
A (int & a_)
//A (const int & a_)//такое объявление параметра заставит переписать код
//защитив переменную переданную через параметр
{
a=++a_;
//a=1+a_;//это для A (const int & a_)
}
};
 
#include <iostream>
using namespace std;
int main()
{
int a=0;
A obj_a=a;
cout << "obj_a.a= " << obj_a.a << " " << " a= " <<a<< " !";
cout << endl;
    system("pause");
    return 0;
}
0
Игогошка!
 Аватар для ct0r
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
03.12.2015, 19:16
Цитата Сообщение от IGPIGP Посмотреть сообщение
Ещё хочу вспомнить, что параметр объявленный как константная ссылка кроме подсказки компилятору о возможности оптимизации
На данный момент компилятору в смысле оптимизации по барабану стоит вообще где const или нет. Но работы в этом направлении ведутся. По крайней мере в LLVM.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
03.12.2015, 20:54
Цитата Сообщение от ct0r Посмотреть сообщение
На данный момент компилятору в смысле оптимизации по барабану
Тут есть только три случая:
1) легче;
2) по барабану;
3) тяжелее.
По идее если компилятор не умеет отслеживать:

C++
1
2
3
int a = 123;
//и в следующей же строке:
a_mass[a];//ошибка - "требуется константное выражение"
то ожидать что такой вызов:
C++
1
2
3
4
5
6
7
8
9
void foo(int a)
{
if(a>123)cout<<"aga!";
else
cout<<"not aga..."
}
 
//------------------где-то
foo(124);
скомпилится в вывод на экран "aga!" в месте вызова не приходится. Впрочем, я не уверен.
Как бы не было, а мне было бы легче.
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
03.12.2015, 21:43
Цитата Сообщение от IGPIGP Посмотреть сообщение
скомпилится в вывод на экран "aga!" в месте вызова не приходится.
Подставит.

Цитата Сообщение от IGPIGP Посмотреть сообщение
если компилятор не умеет отслеживать
Это другое. Здесь не "не умеет", а "не положено", т.к. статическая типизация.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
03.12.2015, 21:55
Цитата Сообщение от IGPIGP Посмотреть сообщение
Он у неё внутри.
внутри вообще нет никаких квалификаторов если что.
квалификаторы нужны людям, а не компилятору.

у ссылок их не существует в принципе, потому что она - псевдоним оригинального объекта,
и не обладает идентичностью
(у неё нет собственных объектов,
которые могли бы хранить состояние ссылки)

будет ошибкой полагать, что ссылка - это "указатель с авторазыменовыванием".
и наделять ссылку свойствами, присущими указателям.
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
03.12.2015, 21:57
IGPIGP, Собственно вот ассемблер твоего примера, я только заменил cout на puts, чтобы получить более читаемый листинг.
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
.LC0:
        .string "aga!"
.LC1:
        .string "not aga..."
foo(int):
        cmp     DWORD PTR [esp+4], 123
        jg      .L4
        mov     DWORD PTR [esp+4], OFFSET FLAT:.LC1
        jmp     puts
.L4:
        mov     DWORD PTR [esp+4], OFFSET FLAT:.LC0
        jmp     puts
main:
        lea     ecx, [esp+4]
        and     esp, -16
        push    DWORD PTR [ecx-4]
        push    ebp
        mov     ebp, esp
        push    ecx
        sub     esp, 16
        push    OFFSET FLAT:.LC0
        call    puts
        mov     ecx, DWORD PTR [ebp-4]
        add     esp, 16
        xor     eax, eax
        leave
        lea     esp, [ecx-4]
        ret
Как видно, в main нет ветвления и сразу осуществляется вызов функции вывода.
Объясняется это просто - после трансляции программы во внутреннее представление, алгоритмы оптимизации в компиляторе смогут крутить ее как бог черепаху. В частности, они вполне способны распознать где у нас константа, а где нет.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
03.12.2015, 22:01
Цитата Сообщение от DrOffset Посмотреть сообщение
Подставит.
Точно? Или "скорее всего"? А если так:
C++
1
2
3
4
5
6
7
8
9
10
 void foo(int a)
{
if(a>123)cout<<"aga!";
else
cout<<"not aga..."
}
 
//------------------ 
 int b=124;
foo(b);

И какова логическая сложность вызова, на которой конкретный компилятор сдастся?
Цитата Сообщение от DrOffset Посмотреть сообщение
Это другое. Здесь не "не умеет", а "не положено", т.к. статическая типизация.
согласен, пример не слишком корректен.
Вообще из примера о параметре в методе (конструкторе тем более, где по возможности не стоит модифицировать внешние переменные побочно) интерес вызвали лишь сомнения в том, что const не облегчает жизнь компилятору. Из вступительной фразы. Жаль.

Добавлено через 2 минуты
Цитата Сообщение от hoggy Посмотреть сообщение
будет ошибкой полагать, что ссылка - это "указатель с авторазыменовыванием".
Так никто, включая Страуструпа, так и не считает. Тут речь идёт о поведении (или о контракте, - удачное слово)).
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
03.12.2015, 22:09
Цитата Сообщение от IGPIGP Посмотреть сообщение
Точно? Или "скорее всего"?
Точно. См. выше.

Цитата Сообщение от IGPIGP Посмотреть сообщение
И какова логическая сложность вызова, на которой конкретный компилятор сдастся?
Можешь сам поэкспериментировать. Вот здесь например: https://gcc.godbolt.org/
Потенциально, если контекст выводим, то сложность может быть очень большой.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
03.12.2015, 22:10
Цитата Сообщение от DrOffset Посмотреть сообщение
Точно. См. выше.
То есть речь идёт о любом компиляторе, независимо от реализации?
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
03.12.2015, 22:18
Цитата Сообщение от IGPIGP Посмотреть сообщение
То есть речь идёт о любом компиляторе, независимо от реализации?
Как правило, все современные компиляторы такое умеют лет 15 как. Даже старый GCC 2.9.x 1999 года выпуска такое вполне может (если написать перед функцией inline).
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
03.12.2015, 22:40
Цитата Сообщение от ct0r Посмотреть сообщение
На данный момент компилятору в смысле оптимизации по барабану стоит вообще где const или нет
Да, так оно и есть. Если компилятор видит тело вызываемой функции, то с точки зрения inline-подстановки ему начхать, передаётся параметр по значению, по ссылке или по указателю

Цитата Сообщение от IGPIGP Посмотреть сообщение
И какова логическая сложность вызова, на которой конкретный компилятор сдастся?
Всё ограничивается, грубо говоря, фантазией разработчиков компилятора. И разумными техническими ограничениями. Типа того, что если функция состоит из 1000 операций (измерение идёт в попугаях), то нет никакого смысла выполнять её inline-подстановку
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
03.12.2015, 22:40

Ссылки и указатели - в чем преимущество одного над другим
Известно, что главной причиной появления ссылок в С++ было дать более безопасную альтернативу указателям в некоторых ситуациях. Ссылка в...

Ссылки и указатели
Добрый день. Возможно было. В чем существенная разница между передачей данных в функцию по ссылке или указателю. В каких случаях вы бы...

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

Ссылки и указатели
Вот есть код в котором я проверял как ведут себя указатели : using namespace std; int* first() { int p = 5; cout &lt;&lt;...

Ссылки и указатели
Здравствуйте, может кто объяснить в чем будет отличие при передаче в функцию по **, *, *&amp;, &amp;(**), желательно на примерах простых


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

Или воспользуйтесь поиском по форуму:
140
Ответ Создать тему
Новые блоги и статьи
Установка нескольких штампов электронной подписи в строго определенных местах файла docx
ВладимирСамохин 19.07.2026
(В!) Работа с Электронной подписью - это неотъемлемая часть современного документооборота. Но что делать, если нужно поставить несколько штампов электронной подписи в строго определенных местах. . .
сукцессия 35. Научная статья о проделанной работе
anaschu 19.07.2026
Написал в формате латекс и пдф
Вангую, что это не пройдёт модерацию, и на неделе я запущу свой сервер.
Hrethgir 19.07.2026
Эта публикация сейчас в песочнице и ждёт приглашения. https:/ / habr. com/ ru/ sandbox/ 295048/ начало и оглавление - Как «пернатого» заставить осваивать новые горизонты опыта через масштабирование. . .
сукцессия 33. открытые вопросы от клауде
anaschu 19.07.2026
"Что накопилось за эту часть А — тринадцать правок, из которых шесть пришли из ваших вопросов и каждая оказалась реальной ошибкой, а не калибровкой: односторонний симбиоз, отсутствующий листопад,. . .
32 сукцессия
anaschu 19.07.2026
сукцессия 28‑мерное ядро стабилизировано Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не «подкручивает» сходимость —. . .
сукцессия 31: модель микоризы - это модель ещё нескольких явлений, социальных и экономических
anaschu 18.07.2026
Теория «Всего»: апдейт v1. 1. 2 — 28‑мерное ядро стабилизировано Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не. . .
сукцессия 30. Массив проверяющих друг друга моделей
anaschu 18.07.2026
Архитектура сети взаимопроверяющих моделей микоризной сукцессии (v2. 0) Развитие тензорного ОДУ-ядра и создание кросс-платформенного калибровочного полигона Уважаемые коллеги! В продолжение. . .
Грибы - это женщины, деревья - это мужчины. Анти инь янь для союза мужчины и женщины.
anaschu 18.07.2026
ГЛАВНЫЙ НАУЧНО-ФИЛОСОФСКИЙ ВЫВОД: Сексуально-Репродуктивный Капитализм против Государства Моногамии Коллеги, мы вышли на финишную прямую 20-мерного ОДУ-моделирования вековой сукцессии (ветка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru