Указатели

Указатель – это переменная, которая может содержать адрес некоторого объекта. Указатель объявляется следующим образом:

<тип> *< ID переменной-указателя>;

Например: int *a; double *f; char *w;

С указателями связаны две унарные операции & и *.

Операция & означает «взять адрес» операнда. Операция * имеет смысл - «значение, расположенное по указанному адресу».

Обращение к объектам любого типа как операндам операций в языке C может проводиться:

- по имени (идентификатору - ID);

- по указателю (операция косвенной адресации):

указатель = &ID_объекта;

Пример 1:

int x, // переменная типа int

*y; // указатель на элемент данных типа int

y=&x; // y - адрес переменной x

*y=1; // косвенная адресация указателем поля x, т.е.

// по указанному адресу записать 1 ® x=1;

 

Пример 2:

int i, j=8,k=5, *y;

y=&i;

*y=2; // i=2

y=&j;

*y+=i; // j+=i ® j=j+i ® j=j+2=10

y=&k;

k+=*y; // k+=k ® k=k+k = 10

(*y)++; // k++ ® k=k+1 = 10+1 = 11

При вычислении адресов объектов следует учитывать, что идентифи­каторы массивов и функций являются константными указателями. Такую константу можно присвоить переменной типа указатель, но нельзя подвергать преобразованиям, например:

int x[100], *y;

y = x; // Правильно - присваивание константы переменной

x = y; // Ошибка: в левой части - указатель-константа

Указателю-переменной можно присвоить значение другого указателя, либо выражения типа указатель с использованием, при необходимости, операции приведения типа. Приведение типа необязательно, если один из указателей имеет тип "void *".

int i,*x;

char *y;

x=&i; // x ® поле объекта int

y=(char *)x; // y ® поле объекта char

y=(char *)&i; // y ® поле объекта char

 

Значение указателя можно вывести на экран с помощью спецификации %p (pointer), результат выводится в шестнадцатеричном виде.

Рассмотрим фрагмент программы:

int a=5, *p, *p1, *p2;

p=&a; p2=p1=p;

++p1;p2+=2;

printf(“a=%d, p=%d, p=%p, p1=%p, p2=%p.\n”, a, p, p, p1, p2);

Результат выполнения: a=5, *p=5, p=FFC8, p1=FFCC, p2=FFD0.

Графически это выглядит так (адреса взяты символически):

 

   
  p p1 p2 400A  
                           

 

p=4000, p1=4002=(4000+1*sizeof(*p)) -> 4000+2 (int)

р2=4004=(4000+2*sizeof(*p)) -> 4000+2*2