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

Рассмотрим i. Объявите p, q и r как указатели на целые числа. Укажите все их на i. Код выглядит следующим образом:

Довольно просто. Но что происходит под капотом?

Указатели — это просто адреса

В приведенном выше примере r не указывает на p. Он указывает на то, на что указывает p. А именно на i.

Когда вы присваиваете один указатель другому, адрес копируется. Значение правой части перемещается в переменную левой части. После выполнения у i появляется четыре имени. i. *p. *q. *r.

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

Почему это важно

Это поведение изменяет способ управления данными. Если вы передаете указатель в функцию, любые изменения, внесенные через этот указатель, влияют на исходную переменную. Если несколько функций хранят указатели на один и тот же адрес, они все видят одни и те же изменения.

Это создает общее состояние. Полезно для кэширования. Опасно, если вы теряете контроль над тем, кто и куда записывает.

Нет ограничений на количество указателей, которые могут хранить и указывать на один и тот же адрес.

Эта гибкость мощна. Она также сложна. Один указатель изменяет значение. Все остальные видят его немедленно. Синхронизация не требуется. Просто прямой доступ к памяти.

Подумайте о отладке. Если переменная неожиданно изменяется, проверьте все указатели. Любой из них может быть виновником. У всех них одинаковая сила. И одинаковая ответственность.

Это не сложная логика. Это простая арифметика указателей. Но последствия распространяются на всю вашу программу. Один адрес. Много имен. Все связаны.