О важности базового типа указателя



 

На примере предыдущей программы была показана возможность присвоения переменной value значения переменной balance посредством операции непрямого доступа, т.е. с использованием указателя. Возможно, при этом у вас промелькнул вопрос: "Как С++‑компилятор узнает, сколько необходимо скопировать байтов в переменную value из области памяти, адресуемой указателем balptr?" . Сформулируем тот же вопрос в более общем виде: как С++‑компилятор передает надлежащее количество байтов при выполнении операции присваивания с использованием указателя? Ответ звучит так. Тип данных, адресуемый указателем, определяется базовым типом указателя. В данном случае, поскольку balptr представляет собой указатель на целочисленный тип, С++‑компилятор скопирует в переменную value из области памяти, адресуемой указателем balptr , четыре байт информации (что справедливо для 32‑разрядной среды), но если бы мы имели дело с double ‑указателем, то в аналогичной ситуации скопировалось бы восемь байт.

Переменные‑указатели должны всегда указывать на соответствующий тип данных. Например, при объявлении указателя типа int компилятор "предполагает", что все значения, на которые ссылается этот указатель, имеют тип int . С++‑компилятор попросту не позволит выполнить операцию присваивания с участием указателей (с обеих сторон от оператора присваивания), если типы этих указателей несовместимы (по сути не одинаковы).

Например, следующий фрагмент кода некорректен.

 

 

Некорректность этого фрагмента состоит в недопустимости присваивания double ‑указателя int ‑указателю. Выражение &f генерирует указатель на double ‑значение, а р – указатель на целочисленный тип int . Эти два типа несовместимы, поэтому компилятор отметит эту инструкцию как ошибочную и не скомпилирует программу.

Несмотря на то что, как было заявлено выше, при присваивании два указателя должны быть совместимы по типу, это серьезное ограничение можно преодолеть (правда, на свой страх и риск) с помощью операции приведения типов. Например, следующий фрагмент кода теперь формально корректен.

 

 

Операция приведения к типу (int * ) вызовет преобразование double ‑ к int ‑указателю. Все же использование операции приведения в таких целях несколько сомнительно, поскольку именно базовый тип указателя определяет, как компилятор будет обращаться с данными, на которые он ссылается. В данном случае, несмотря на то, что p (после выполнения последней инструкции) в действительности указывает на значение с плавающей точкой, компилятор по‑прежнему "считает", что он указывает на целочисленное значение (поскольку р по определению – int‑указатель).

Чтобы лучше понять, почему использование операции приведения типов при присваивании одного указателя другому не всегда приемлемо, рассмотрим следующую программу.

 

 

Как видите, в этой программе переменной p (точнее, указателю на целочисленное значение) присваивается адрес переменной х (которая имеет тип double). Следовательно, когда переменной y присваивается значение, адресуемое указателем р , переменная y получает только четыре байт данных (а не все восемь, требуемые для double‑значения), поскольку р – указатель на целочисленный тип int. Таким образом, при выполнении cout‑инструкции на экран будет выведено не число 123.23 , а, как говорят программисты, "мусор" . (Выполните программу и убедитесь в этом сами.)

 

Присваивание значений с помощью указателей

 

При присваивании значения области памяти, адресуемой указателем, его (указатель) можно использовать с левой стороны от оператора присваивания. Например, при выполнении следующей инструкции (если р – указатель на целочисленный тип)

 

 

число 101 присваивается области памяти, адресуемой указателем р . Таким образом, эту инструкцию можно прочитать так: "по адресу р помещаем значение 101" . Чтобы инкрементировать или декрементировать значение, расположенное в области памяти, адресуемой указателем, можно использовать инструкцию, подобную следующей.

 

 

Круглые скобки здесь обязательны, поскольку оператор "*" имеет более низкий приоритет, чем оператор "++" .

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

 

 

Вот такие результаты генерирует эта программа.

 


Дата добавления: 2018-09-22; просмотров: 274; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!