MyTetra Share
Делитесь знаниями!
Отличие ссылок от указателей в языке C++
Время создания: 21.03.2022 14:04
Автор: xintrea
Текстовые метки: C++, Си++, ссылка, указатель, различия, отличия
Раздел: Компьютер - Программирование - Язык C++ (Си++)
Запись: xintrea/mytetra_syncro/master/base/16478606714kdi8gxbwj/text.html на raw.github.com

Очень часто, у тех кто успешно освоил указатели, при изучении ссылок возникает вопросы: а чем ссылки отличаются от указателей? Только синтаксисом использования и невозможностью сущестования неинициализованной ссылки? Каким образом сделаны ссылки и как они работают?


Пролить свет на этот вопрос поможет следующее, достаточно удачное объяснение:



Ссылка - это переменная, которая указывает на другую переменную, хранящуюся в той же памяти.



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


Переменная - это по-сути, именованная ячейка (либо именованный набор соседних ячеек) в памяти компьютера. Когда работает компилятор, он для текущего контекста создает таблицу используемых переменных. Таблица выглядит примерно так:




Имя переменной

Тип

Адрес расположения переменной

1

first

int

0x50A5B7F2

2

second

long

0x50A5B804



Значение переменной компилятор не хранит - все значения переменных существуют только в момент исполнения программы. Компилятор может только сгенерировать команды инициализации и изменения значений переменных. Поэтому в этой таблице нет столбца со значением переменной.


Теперь если добавить переменную-указатель на first, то в таблице переменных появится еще одна запись:




Имя переменной

Тип

Адрес расположения переменной

1

first

int

0x50A5B7F2

2

second

long

0x50A5B804

3

pointer_first

int*

0x50A5BA08



То есть, указатель pointer_first - это переменная, у которой есть свой адрес 0x50A5BA08, и по этому адресу (в момент выполнения программы) будет находиться значение, равное 0x50A5B7F2. То есть, указатель указывает не на переменную first, а на значение переменной, которое расположено в памяти по адресу 0x50A5B7F2. Переменная first может даже перестать существовать, и в месте, где лежали ее данные могут быть размещены другие данные. А указатель pointer_first так и будет указывать на ту же самую ячейку (ячейки) памяти с адресом 0x50A5B7F2. И в этом проблема "сырых" указателей, приводящая к обращениям по неправильным адресам.


Чтобы в каком-то виде решить эти проблемы, и заодно упростить синтаксис, были придуманы ссылки. Для объяснения работы ссылок, можно создать ссылку на переменную second. В таблице переменных появится еще одна запись:




Имя переменной

Тип

Адрес расположения переменной

1

first

int

0x50A5B7F2

2

second

long

0x50A5B804

3

pointer_first

int*

0x50A5BA08

4

link_second

long&

0x50A5BA10



Чтобы было проще, можно сказать, что переменная-ссылка link_second - это переменная, у которой, как и у любой другой переменной, есть свой адрес 0x50A5BA10, в котором хранится некое значение. Но это значение - не адрес, по которому находятся данные переменной second. Нет! В этом значении хранится ссылка на переменную second. Можно считать, что там хранится номер строки таблицы, в данном случае 2.


Из предыдущего абзаца следует, что невозможно создать ссылку на несуществующую переменную, так как ее просто не будет в таблице переменных. Компилятору очень легко контролировать, на какую переменную ссылается переменная-ссылка. Невозможна ситуация, чтобы переменная-ссылка оказалась неинициализирована: ссылка всегда указывает на какую-то другую переменную (т. е. содержит номер уже существующей переменной).


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


Так же в этом разделе:
 
MyTetra Share v.0.60
Яндекс индекс цитирования