Указатели
Благодаря указателям могут работать связанные списки и механизм динамического выделения памяти, в следствии этого функции могут изменять содержимое своих аргументов. Об этом мы поговорим позже, а сейчас разберём основы применения указателей.
Что представляют собой указатели
Указатель - это объект, хранящий в себе некоторый адрес памяти. По этому адресу памяти он может получить значение, которое там хранится, также изменять это значение. Если переменная a содержит адрес переменной b, то говорят, что a указывает на b.
Переменные-указатели должны быть объявлены в следующей форме.
тип *имя_переменной;
Тип означает базовый тип указателя (int, double, char и др.). Тип должен быть такой же, на который переменная-указатель будет ссылаться. Объявим переменную abc указателем с типов int.
int *abc;
В общем случае нужно написать звёздочку (*) перед именем переменной.
Операторы, используемые с указателями
Указатели могут использовать два оператора: "*" и "&". Оператор "&" возвращает адрес переменной. К примеру, следующий код
ptr = &total;
в переменную ptr поместит адрес переменной total. Выполнение этой инструкции никак не повлияло на содержимое переменной total.
Второй оператор "*" работает в паре с "&", он берёт значение по адресу памяти. Например, возьмём значение переменной total по адресу, который храниться в ptr.
ptr = &total;
val = *ptr;
Допустим, в переменной total хранилось значение 100. В первой строке мы сохранили адрес памяти переменной total в переменную ptr, а на второй строке мы взяли значение 100 по адресу в переменной total. На значение переменной total это никак не повлияло. В программе бы это выглядело так.
Вывод программы в консоль
Присваивание значений с помощью указателей
Если вы хотите присвоить какое-то значение по адресу памяти, то нужно поставить слева от равно *имя_переменной_хранящая_адрес, а справа значение;
*ptr = 101;
Число 101 присвоилось переменной total. Эту инструкцию можно прочитать как "по адресу ptr помещаем значение 101".
Чтобы декрементировать или инкрементировать значение по адресу памяти, нужно использовать следующую инструкцию.
(*ptr)++;
Скобки нужны по той причине, что оператор "*" имеет более низкий приоритет чем "++".
Использование указателей в выражениях
Указатели используются в большинстве доступных в C++ выражений, но при этом нужно применять некоторые специальные правила.
Арифметические операции над указателями
С указателями возможно использовать только 4 арифметические операции: ++, --, + и -. Для того, чтобы лучше понять как работают арифметические операции, представим, что переменная p1 - указатель на int-переменную с значением 2000. После выражения
p1++;
содержимое переменной-указателя p1 будет равно 2004, а не 2001. А при p1--; будет 1996. Дело в том, что при каждом инкрементировании указатель p1 будет указывать на следующее int значение.
Переменная char будет увеличиваться/уменьшаться на единицу, т.к. размер его базового типа равен 1 байту (а у int 4 байта). В общем говоря, в результате такой инструкции будет инкрементироваться не единица, а количество байтов типа.
В следующей программе будут выводиться реальные физические адреса, которые содержат указатель на int значение (i) и указатель на double значение (f). Обратите внимание, что int будет меняться на 4, а double на 9.
Вывод программы.
Сравнение указателей
Указатели можно сравнить, используя операторы отношения ==, < и >. Чтобы их результат сравнения поддавался интерпретации, сравниваемые указатели должны быть каким-то образом связаны. Допустим, если они ссылаются на две отдельные и при этом не связанные переменные, то их сравнение не имеет смысла. А если эти элементы находятся внутри одного массива, то имеет (об этом поговорим в одном из следующих уроках). Так же можно сравнить любой указатель с нулевым, который равен нулю.
Подпишитесь на канал, чтобы не потерять курс!
Список всех уроков курса.