Указатели. Константный указатель и указатель на константу

Освоение указателей обычно сложно даётся новичкам-программистам. Хотя указатель — это только-лишь тип, а указательная переменная только-лишь адрес памяти.
Одной из наиболее запутывающей составляющей оказывается обозначение неизменяемости, применяемое либо к адресу, на который указатель указывает, либо к значению, находящемуся в том адресе.
Выглядит подобное безобразие приблизительно вот так:

Что же это такое? Чтобы разобраться с подобными пакостями, нужно начать с малого.
  • Указатель — это тип.
  • Указательная переменная — это адрес.
  • В адресе есть значение.
Это три кита
  • Прямое значение указательной переменной — это адрес.
  • Косвенное значение указательной переменной — это значение из адреса.

Бывает, что нужно обозначить неизменяемость переменной. В случае с обычными переменными используется квалификатор const или volatile. Новичками в основном используется const. Указательная переменная может изменять непосредственное своё состояние и состояние косвенного своего значения. Изменяющаяся указательная переменная — это бегающий и прыгающий по памяти курсор. Не всегда нужно, чтобы этот курсор мог прыгать и бегать. В таких случаях нужно зафиксировать в указательной переменной адрес.

Такая фиксация адреса делает указательную переменную неподвижной. Т. е. в неё нельзя присваивать никакие адреса.

Указательная переменная помогает читать и изменять значения из хранимого в себе адреса. Т. е. когда указательная переменная указывает на какой-то адрес, то значение из того адреса можно прочитать и изменить. Не всегда нужно, чтобы значения могли изменяться, а иногда нужно просто обозначить, что значения не должны изменяться. В случае использования указательной переменной этого можно добиться вот так:

Простыми словами "Вы используете указательную переменную или как курсор, или используете свойство косвенности указательной переменной для работы со значением, подбирающимся из адреса. Можно зафиксировать или курсор, или значение под курсором. ".
Оба случая можно совместить: зафиксировать адрес в указательной переменной и обозначить запрет на изменение вытаскиваемого из сохранённого адреса значения .

Кто-то может поторопиться и подумать, что всё понятно. Но не тут-то было. Эта тема константых указателей и указателей на константу доставляет определённых проблем. Вы можете сейчас сказать, что такое указатель на константу и что такое константный указатель? Можете распознать в коде, что есть что?

Вы можете сказать, что где? Как читается, что обозначает?
const int мало отличается от int const, это эквивалентны, поэтому p1, p2 и p3 будут вести себя одинаково, p4 и p5 будут вести себя одинаково.
Об остальном уже говорилось в начале статьи.
Сложно, должно быть. Запутывающе. Но не переживайте, здесь легко разрулить ситуацию. Существует особый способ, который помогает правильно воспринимать каждую такую "странную" строчку кода.
  • Читайте справа налево, начиная от имени указательной переменной.
  • const int и int const — эквивалентные способы обозначить int-константу

Обозначение важности неизменяемости, применяемое к указательным переменным, не влияет на переменные, с которыми связан указатель. Т. е. если переменная не обозначена как неизменяемая, то она, логично, сможет меняться.

  • Чтобы меньше путаться, вы можете подменять слово "указатель" словом "адрес"
  • Константный указатель — это когда адрес, хранимый внутри указательной переменной, изменять не положено.
  • Указатель на константу — это когда значение, вытаскиваемое из адреса, воздействием указательной переменной изменять не положено.
  • Константный указатель на константу — это когда нельзя изменить адрес, хранимый в указательной переменной, и нельзя повлиять разыменованной указательной переменной на значение, лежащее в том адресе.
Завершающий пример, показывающий различие использование константного указателя и указателя на константу:

Все три случая бывают нужны. (Указатель на константу, константный указатель и константный указатель на константу)
Если я не смог хорошо объяснить тему, то попробуйте прочитать здесь:

Да, в начале темы был приведён устрашающий пример:

Такие страшные штуки писать едва ли нужно. Но, возможно, какой-нибудь вредный соискатель любит задавать заковыристые вопросы, среди которых может оказаться похожий. Просто читайте справа налево:
x — это указатель на указатель на указатель, на константный указатель на указатель на константный указатель на целое.
Надеюсь, что научились уже различать константные указатели и указатели на константу. В одном случае нельзя менять адрес, в другом значение, вытаскиваемое из адреса.
По количеству звёздочек вы можете определить какому массиву подобна эта страшная штука: звёздочек 6, значит всё это дело похоже на шестимерный массив.

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

То же самое можно посмотреть на уровне указателей:

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

10 комментариев на «“Указатели. Константный указатель и указатель на константу”»

  1. Varelka:

    Когда-то где-то вычитал (у Страуструпа может, не помню) чтобы легче читать код и определятся с синтаксисом при написании (запомнить в общем), нужно читать конструкцию справа налево:

    const int* — указатель(*) на целую(int) константу(const)
    int *const — константный(const) указатель(*) на целое(int)

    как-то так 🙂
    ресурсу и авторам +

  2. Марина:

    «Каждый из трех описанных описанных вариантов » — 2 раза слово «описанных») не по теме с++, но все же (=

    3
    1
  3. Kordan:

    Значение константного указателя на константу можно изменить с помощью другого указателя

    • Ваш пример в упрощённом варианте выглядит так:

      Разумеется, можно изменять переменную, которая не константная, используя указатель.
      Чтобы её не изменять, например случайно, нужно использовать ту самую переменную, которая константный указатель на константу.

  4. Аноним:

    Маша какого хрена я этого не знаю.

  5. Алексей:

    x — это указатель на указатель на указатель, на константный указатель на указатель на константный указатель на целое.

    дык в конце то указатель не на целое, а на константное целое

  6. Александр:

    Здраствуйте.Посмотрите.Почему нельзя создать массив так?

    • Это компилируется, только размер массива будет неопределён, использование неицианилизорванных своими значениями переменных — есть непрогнозируемое поведение программы.
      Поскольку в указатель, который используется для описания размера массива, не записано никакого значения, то по сути в указателе лежит только-лишь неопределённое значение, использование которого даёт непрогнозируемый эффект.

      Порядок нарушен. Сначала надо задать любое значение в адрес, на который ссылается указатель. И только потом на основании этого значения делать массив, а не сначала делать массив, чтобы потом говорить ему о его размере. Поменяйте 9-ю и 10-ю строчки местами и всё будет ОК.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Поиск

 
     

Случайная книга в электронном формате

https://www.litres.ru/d-m-zlatopolskiy/programmirovanie-tipovye-zadachi-algoritmy-metody-6509134/?lfrom=15589587

Последние комментарии

Яндекс.Метрика