Язык С


Указатели и адреса


Так как указатель содержит адрес объекта, это дает воз- можность "косвенного" доступа к этому объекту через указа- тель. Предположим, что х - переменная, например, типа INT, а рх - указатель, созданный неким еще не указанным способом. Унарная операция & выдает адрес объекта, так что оператор

рх = &х;

присваивает адрес х переменной рх; говорят, что рх "ука- зывает" на х. Операция & применима только к переменным и элементам массива, конструкции вида &(х-1) и &3 являются не- законными. Нельзя также получить адрес регистровой перемен- ной. Унарная операция * рассматривает свой операнд как адрес конечной цели и обращается по этому адресу, чтобы извлечь содержимое. Следовательно, если Y тоже имеет тип INT, то

Y = *рх;

присваивает Y содержимое того, на что указывает рх. Так пос- ледовательность

рх = &х; Y = *рх;

присваивает Y то же самое значение, что и оператор

Y = X;

Переменные, участвующие во всем этом необходимо описать:

INT X, Y; INT *PX;

с описанием для X и Y мы уже неодонократно встречались. Описание указателя

INT *PX;

является новым и должно рассматриваться как мнемоническое; оно говорит, что комбинация *PX имеет тип INT. Это означает, что если PX появляется в контексте *PX, то это эквивалентно переменной типа INT. Фактически синтаксис описания перемен- ной имитирует синтаксис выражений, в которых эта переменная может появляться. Это замечание полезно во всех случаях, связанных со сложными описаниями. Например,



DOUBLE ATOF(), *DP;

говорит, что ATOF() и *DP имеют в выражениях значения типа DOUBLE.

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

Y = *PX + 1

присваивает Y значение, на 1 большее значения X;

PRINTF("%D\N", *PX)

печатает текущее значение X;

D = SQRT((DOUBLE) *PX)


получает в D квадратный корень из X, причем до передачи фун- кции SQRT значение X преобразуется к типу DOUBLE. (Смотри главу 2). В выражениях вида

Y = *PX + 1

унарные операции * и & связаны со своим операндом более крепко, чем арифметические операции, так что такое выражение берет то значение, на которое указывает PX, прибавляет 1 и присваивает результат переменной Y. Мы вскоре вернемся к то- му, что может означать выражение

Y = *(PX + 1)

Ссылки на указатели могут появляться и в левой части присваиваний. Если PX указывает на X, то

*PX = 0

полагает X равным нулю, а

*PX += 1

увеличивает его на единицу, как и выражение

(*PX)++

Круглые скобки в последнем примере необходимы; если их опус- тить, то поскольку унарные операции, подобные * и ++, выпол- няются справа налево, это выражение увеличит PX, а не ту пе- ременную, на которую он указывает. И наконец, так как указатели являются переменными, то с ними можно обращаться, как и с остальными переменными. Если PY - другой указатель на переменную типа INT, то

PY = PX

копирует содержимое PX в PY, в результате чего PY указывает на то же, что и PX.




    Содержание раздела