11. C/C++ Указатели, ссылки, адреса

Указатели, ссылки, адреса

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

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

Взятие адреса (С/С++)

У памяти есть адресация, следовательно можно получить адрес переменной в памяти, для этого используется амперсанд & (EN shift+7)
int Value=15; //переменная, хранящаяся по какому-то адресу (например 0x000F0010)
int AddrValue=&Value; //теперь в переменной AddrValue хранится значение 0x000F0010

Стоит отметить, что в адресация зависит от разрядности вычислителя.

Указатель (C/C++)

Как уже было сказано у памяти есть некая адресация (смещение относительно начала) за счет чего можно не копировать переменные, массивы и тд в текущие функции, а передавать указатель и «говорить» данные лежат ВООН там! )


Рассмотрим предыдущую таблицу – пусть по адресу 0x013FFF01 лежит переменная типа char Variable=10;

Тогда, мы можем работать с ее адресом
char* pVariable=&Variable; // теперь в pVariable хранится указатель на адрес 0x013FFF01

Что мы сделали
char* – указатель на область в памяти, хранящую переменную типа char
&Variable – тут мы взяли адрес переменной Variable
И просто присвоили одно другому.

Мы можем изменить значение Variable
для этого сделаем операцию разыменования (дописав * перед указателем)
*pVariable=15; //теперь переменная Variable=15

Если создается просто указатель без присвоения значения, то стоит присваивать его NULL/null/nullptr.
NULL/null – просто присвоение к 0
nullptr – ключевое слово, введенное в 11 стандарте С++ для описания нулевого указателя (nullptr !=0)

Указатель – такая же переменная как char, int… и с ней доступны те же самые операции.

Важно! Тип указателя и тип переменной должен быть одинаков, т.е. int* pVariable=&Variable; невозможно сделать.

Стоит отметить, что название массива является указателем на его элемент с индексом [0].

Обычно указатели передаются в функции чтобы не копировать большие объемы данных, например структуры, в этом случае стоит выполнять проверку, что указатель не равен 0!

Можно делать указатель на указатель.
Например: char** pVariable=&pVariable;

Ссылка (C++)

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

Для упрощения работы в C++ были созданы ссылки.

В ссылках таких понятия нет, так как меняя ссылку вы автоматически меняете и переменную. Ссылки напрямую ссылаются к переменной, поэтому их синтаксис проще:

char Data = 10;
char &Value = Data; // Создание ссылки на переменную

Value =15;

По сути ссылка – готовый переход на адрес в памяти, и при этом этот переход не может быть не инициализирован, что избавляет от многих проверок.
Главный минус ссылки – их нельзя изменить!!! Т.е. при создании ссылки она указывает на зону в памяти (например адрес 0x013FFF01) и изменить этот адрес на 0x013FFF02 мы не сможем.

Leave a Reply

Your email address will not be published. Required fields are marked *