Введение

Указатели широко распространены в C++, и важно понимать их, чтобы воспользоваться преимуществами многих функций, существующих в C++. Однако для новичка их может быть довольно сложно понять, особенно с учетом того, насколько запутанным может быть синтаксис. В этой статье делается попытка облегчить изучение указателей, объясняя, что они из себя представляют, как их использовать и зачем их использовать.

Что такое указатель?

Указатель — это переменная, которая хранит место в памяти вместо самих данных. Основной синтаксис указателя выглядит следующим образом:

Приведенный выше синтаксис показывает типичный пример объявления указателя. Оператор адреса «&» используется для получения адреса данных, хранящихся в переменной a, и именно этот адрес хранится в ptr. Хотя наш указатель хранит адрес памяти, все же необходимо объявить тип данных, которые хранит адрес памяти, чтобы указатель можно было использовать для управления данными.

Примечание. Оператор '*' используется для объявления того, что переменная является указателем, позиция '*' может располагаться как int* pointer или int *pointer, однако предыдущее объявление может немного сбивать с толку. поскольку он имитирует синтаксис, необходимый для разыменования (объяснено далее) указателя.

Разыменование указателя

Как упоминалось ранее, указатель хранит место в памяти, а не данные, поэтому указатель довольно бесполезен при использовании этих данных, если вы не можете получить к ним доступ. Разыменование делает именно это и предоставляет вам способ доступа к данным, хранящимся в ячейке памяти указателя. Разыменование ptr выглядит следующим образом:

В этом примере мы используем оператор разыменования '*' (да, это тот же самый оператор, используемый для объявления указателя), чтобы получить доступ к данным, хранящимся по адресу, на который он указывает, в данном случае это значение 12. Значение сохраняется в переменной b и затем используется в простом выражении.


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

Указатель объекта

До сих пор указатели описывались с использованием фундаментальных типов C++, однако указатели можно использовать для хранения адреса объекта. Синтаксис немного сложнее при доступе к данным или методам членов. В следующем примере показан один из способов использования указателя с объектом типа Student.

Второй оператор разыменовывает указатель, содержащий адрес объекта, а затем использует оператор точки для доступа к функции-члену GetMathMark(). Без круглых скобок инструкция сначала попытается получить доступ к методу объекта, а затем попытается разыменовать его из-за приоритета операций, определенного в C++. Учитывая, что указатель хранит адрес, а не тип Student, это не сработает. Синтаксис может быть довольно проблематичным, поэтому существует альтернативный способ, использующий оператор «-›», который разрешает доступ к члену с помощью указателя и устраняет необходимость в круглых скобках.

Указатель на указатель

Другой аспект указателей заключается в том, что они могут хранить адреса других указателей. Да, указатели могут хранить адрес указателя, который указатель адреса, который он хранит, указывает на адрес некоторых данных. Ниже показан пример с использованием основ C++, но он также работает с пользовательскими типами.

В этом случае pptr инициализируется адресом ptr, а не адресом переменной a, и доступ к a можно получить либо путем разыменования ptr с помощью одной «*», либо через pptr с использованием двух «*». Как видите, синтаксис указателя на указатель аналогичен синтаксису обычного указателя, за исключением дополнительного «*» как в объявлении указателя, так и при разыменовании.

Когда требуется указатель

Итак, теперь основы указателей объяснены, следующий вопрос: зачем нам нужны указатели? Указатели широко используются в C++, и ниже приведены несколько примеров без акцента на описании какого-либо конкретного варианта использования, поскольку каждый из них может быть отдельной статьей.

  • Полиморфизм
  • Динамическое размещение
  • Эффективная передача параметров (хотя лучше использовать ссылки)
  • Указатели функций

Поэтому, как вы можете видеть, указатели необходимы, если вы хотите максимально использовать C++ и использовать определенные функции языка, такие как полиморфизм, который является важной концепцией в любом объектно-ориентированном языке.

Резюме

Подводя итог, можно сказать, что эта статья представила указатели в C++ и дала общее представление о том, что они собой представляют, как они используются и для чего они используются.

  • Указатель содержит адрес переменной, а не сами данные.
  • Доступ к данным, хранящимся по адресу памяти, который хранит указатель, можно получить, разыменовав указатель.
  • Указатель может использоваться для хранения адреса объекта и требует заключения разыменованного объекта в скобки перед использованием оператора доступа к члену или использования оператора «-›».
  • Указатели могут хранить адреса других указателей и обозначаются цифрой «*», используемой при объявлении и разыменовании указателя.