Что, почему и как использовать указатели.
В этой статье делается попытка познакомить с основными понятиями указателей тех, кто может быть новичком в программировании или нуждается в повторении основ ручного управления памятью.
Что такое указатель?
Указатель — это адрес памяти другой переменной. Напомним, что адрес памяти — это просто место, где находится переменная в памяти. Все переменные имеют ячейку памяти, и каждая ячейка имеет соответствующий адрес памяти, по которому к ней можно получить доступ. C++ использует эти адреса памяти для ссылки на то, где они существуют. Адрес, который называет переменную, называется указателем, потому что он «указывает» на переменную.
Надеюсь, это имело смысл. Если нет, несите меня через несколько примеров. 😅
Вот как вы создаете указатель:
int *ptr;
Это объявляет переменную ptr, которая может содержать указатель на целые типы. Чтобы он на что-то указывал, мы можем установить ptr на адрес памяти другой переменной:
int *ptr; int var; ptr = &var; // Have ptr "point" to var
Прохладный. Итак, что это значит? Оператор & получает адрес переменной. Это позволяет нам присвоить адрес указателю. Теперь мы можем ссылаться на var двумя разными способами:
int *ptr; int var; var = 23; ptr = &var; *ptr = 50; cout << var << endl; // Outputs 50 cout << *ptr << endl; // Outputs 50
Чтобы объяснить, *ptr это то же самое, что «переменная, на которую указывает ptr». * в этом контексте известен как оператор разыменования. Кроме того, переменная-указатель «разыменована» — это означает, что мы получаем доступ к необработанному значению указателя/адреса памяти. Это означает, что *ptr и var одинаковы, и любые изменения в одном будут распространяться на другой.
Впоследствии мы можем даже установить указатели на указатели:
int *ptr, *ptr1; int var; var = 123; ptr = &var; ptr1 = ptr; // Point ptr1 to the same thing ptr is pointing to cout << var << endl; // Outputs 123 cout << *ptr << endl; // Outputs 132 cout << *ptr1 << endl; // Outputs 132
Внимание! Помните о различиях между ptr = ptr1 и *ptr = *ptr1. Первый устанавливает по ссылке, а второй устанавливает по значению:
Установка по ссылке установит ptr1 на тот же адрес памяти, что и ptr, что означает, что изменения в ptr будут распространяться на ptr1.
Установка по значению даст *ptr значение *ptr1 (в данном случае 123), но они не будут указывать на один и тот же адрес памяти.
Подробнее об этом здесь:
Резюме:
ptr (переменная) против * против &. В чем именно разница между этими тремя?
ptr— переменная-указатель, адрес памяти другой переменной.*– это оператор разыменования. Когда вы разыменовываете указатель, вы получаете доступ к значению по адресу памяти.&- это оператор адреса, при префиксе переменной с этим вы получите доступ к адресу памяти указанной переменной. Это полезно для установки указателя на эту переменную.
В части 2 (подлежит уточнению) мы обсудим основные преимущества использования указателей и более концептуальные основы работы с памятью.