мета-данные страницы
Это старая версия документа!
указатели
Указатели представляют собой объекты, значением которых служат адреса других объектов (переменных, констант, указателей) или функций.
// определение указателя тип_данных* название_указателя;
Указатель должен быть того же типа, что и объект, адрес которого он хранит. Указатель типа int не может указывать на переменную float. Указатель на void может хранить адрес объекта любого типа.
Указателю можно присвоить (=) значение другово указателя (хранимый в нем адрес). Операции сравнения применяются только к указателям одного типа и константе NULL.
Если объект (например int) занимает в памяти больше 1 байта - указатель будет ссылаться на ячейку, где храниться первый байт объекта.
int *pa = NULL;
Иногда требуется присвоить указателю одного типа значение указателя другого типа. В этом случае следует выполнить операцию приведения типов.
Получение адреса
Для получения адреса к переменной применяется операция &
#include <stdio.h> int main(void) { int x = 10; int *p; p = &x; printf("%p \n", p); // например: 0060FEA8 return 0; }
таким же образом (&) можно получить адрес самого указателя.
Разыменование указателя
Для получения значения по адресу применяется операция * или операция разыменования (dereference operator).
#include <stdio.h> int main(void){ int x = 10; int *p; p = &x; printf("Address = %p \n", (void*) p); // Address = 0060FEA8 printf("x = %d \n", *p); // x = 10 return 0; }
Константы
Мы можем манипулировать значениями констант через указатели
#include <stdio.h> int main(void) { const int cx = 10; // получаем адрес константы, преобразуем в указатель типа int* и изменяем по нему значение *(int*) &cx = 20; printf("cx: %d\n", cx); // cx: 20 }
Сам указатель тоже может быть const. Константный указатель может указывать и на обычную автоматическую переменную. Константному указателю нельзя изменить адрес, который в нем храниться, зато можно изменить значение по этому адресу.
Константный указатель на константу не может менять ни свой адрес, ни значение по адресу.
Массивы указателей
Массив указателей определяется одним из трех способов:
int array[] = {1, 2, 3, 4}; int *p1[3]; int *p2[] = { &array[1], &array[2], &array[0] }; int *p3[3] = { &array[3], &array[1], &array[2] };
Вместо *p[i] для доступа к элементу из array мы могли бы написать **(p+i):
p+i- к адресу в указателе p прибавляем число i и таким образом перемещаемся по указателям в массиве p.*(p+i)- разыменовываем i-тый указатель в массиве и в результате получаем адрес одного из элементов из массива array.**(p+i)- получаем значение по полученному на предыдущем шаге адресу элемента из массива array.