Указатели в C++
Адрес и указатель
Указатель хранит адрес объекта. Оператор & получает адрес, а * разыменовывает указатель.
int value = 42;int* ptr = &value;std::cout << *ptr << '\n';*ptr = 100;После присваивания через *ptr переменная value становится равной 100.
nullptr
Если указатель пока не указывает на объект, инициализируй его nullptr:
int* ptr = nullptr;if (ptr != nullptr) { std::cout << *ptr;}Разыменование нулевого, висячего или недопустимого указателя приводит к неопределённому поведению.
const и указатели
const int* p1 = nullptr; // нельзя менять int через p1int* const p2 = nullptr; // адрес p2 нельзя переназначить (но так использовать нельзя для полезного объекта)const int* const p3 = nullptr; // и объект через указатель менять нельзя, и адрес неизмененНа практике int* const часто применяется как локальная неизменяемая переменная-указатель, инициализированная адресом настоящего объекта.
Арифметика указателей
При работе с массивами указатель можно перемещать между элементами и на позицию сразу после последнего элемента. Разыменовывать позицию за концом массива нельзя. Арифметика указателей не предназначена для произвольных адресов и требует, чтобы указатели относились к одному массиву или допустимому диапазону.
Указатели и функции
void Reset(int* value) { if (value) { *value = 0; }}Указатель подходит, если аргумент может отсутствовать или если контракт явно оперирует адресом. Для обязательного существующего объекта часто лучше ссылка.
Частые ошибки
- Использовать неинициализированный указатель.
- Разыменовывать
nullptr. - Возвращать адрес локальной переменной.
- Использовать указатель после освобождения памяти или после уничтожения контейнером объекта.
Итог
Указатели дают низкоуровневый контроль, но требуют чёткого понимания владения и времени жизни объектов. Инициализируй указатели и проверяй контракт их использования.
