Программирование на C и C++

Онлайн справочник программиста на C и C++

Операторы для работы с указателями

Имеется два специальных оператора для работы с указателями - * и &.

Оператор & - это унарный оператор, возвращающий адрес операнда. Например:

р = #

помещает адрес переменной num в р. Данный адрес соответствует внутреннему положению переменной в компьютере. Он ничего не делает со значением num. Операцию & можно рассматривать как «взятие адреса». Следовательно, предыдущий оператор присваивания можно прочитать как «p получает адрес num».

Предположим, что переменная num использует адрес 2000 для хранения своего значения. Также предположим, что значение num - 100. В результате этих предположений р получит значение 2000.

Следующий оператор * дополняет оператор &. Оператор * - это унарный оператор, возвращающий значение переменной, находящейся по указанному адресу. Например, если р содержит адрес памяти переменной num, то

q=*p;

поместит значение num в q. Следуя вышеприведенным предположениям, q получит значение 100, поскольку 100 хранится по адресу 2000, являющемуся адресом, хранящимся в р. Оператор * можно рассматривать как «по адресу». В данном случае вышеприведенный оператор может быть прочитан как *q получает значение по адресу р».

Следующая программа демонстрирует все вышеперечисленное:

#include <stdio.h>
int main(void)
{
int num, q;
int *p;
num = 100; /* num присваивается 100 */
p = &num; /* p получает адрес num */
q = *p; /* q посредством p присваивается значение num */
printf("%d", q); /* выводит 100 */
return 0;
}

Данная программа выводит значение 100 на экран.

К несчастью, значок для умножения и значок «по адресу» совпадают, впрочем как и значок битового И и значок «взятие адреса». Данные операторы не влияют друг на друга. Как &, так и * имеют более высокий приоритет по сравнению с остальными арифметическими операторами, кроме унарного минуса, приоритет которого совпадает с приоритетом данных операторов.

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

#include <stdio.h>
int main(void)
{
double x, y;
int *p;
x = 100.123;
p = &x;
у = *p;
printf ("%f", у); /* неверно */
return 0;
}

Данная программа не присваивает значение х переменной у. Поскольку р объявляется как целочисленный указатель (предположим, что в системе 16-битное целое), только 2 байта будут перенесены к у, а не 8, как обычно делается для double.