Особенности применения указателей
Обращение к объектам любого типа в языке C может проводиться по имени, как мы до сих пор делали, и по указателю (косвенная адресация).
Указатель – это переменная, которая может содержать адрес некоторого объекта в памяти компьютера, например, адрес другой переменной. Через указатель, установленный на переменную, можно обращаться к участку оперативной памяти (ОП), отведенной компилятором под ее значение.
Указатель объявляется следующим образом:
тип * ID указателя;
Перед использованием указатель должен быть инициирован либо конкретным адресом, либо значением NULL (0) – отсутствие указателя.
С указателями связаны две унарные операции: & и *. Операция & означает «взять адрес», а операция разадресации * – «значение, расположенное по адресу», например:
int x, *y; // х – переменная типа int , у – указатель типа int
y = &x; // y – адрес переменной x
*y = 1; // по адресу y записать 1, в результате x = 1
При работе с указателями можно использовать операции сложения, вычитания и сравнения, причем выполняются они в единицах того типа, на который установлен указатель.
Операции сложения, вычитания и сравнения (больше/меньше) имеют смысл только для последовательно расположенных данных – массивов. Операции сравнения «==» и «!=» имеют смысл для любых указателей, т.е. если два указателя равны между собой, то они указывают на одну и ту же переменную.
Связь указателей с массивами
Указатели и массивы тесно связаны между собой. Идентификатор массива является указателем на его первый элемент, т.е. для массива int a[10], выражения a и a[0] имеют одинаковые значения, т.к. адрес первого (с индексом 0) элемента массива – это адрес начала размещения его элементов в ОП.
Пусть объявлены – массив из 10 элементов и указатель типа double:
double a[10], *p;
если p = a; (установить указатель p на начало массива a), то следующие обращения: a[i] , *(a+i) и *(p+i) эквивалентны, т.е. для любых указателей можно использовать две эквивалентные формы доступа к элементам массива: a[i] и *(a+i). Очевидна эквивалентность следующих выражений:
&a[0] « &(*p) « p
Декларация многомерного массива:
тип ID[размер 1][размер 2]…[размер N];
причем быстрее изменяется последний индекс, т.к. многомерные массивы размещаются в ОП в последовательности столбцов, например, массив целого типа, состоящий из двух строк и трех столбцов (с инициализацией начальных значений)
int a[2][3] = {{0,1,2},{3,4,5}};
в ОП будет размещен следующим образом:
a[0][0]=0, a[0][1]=1, a[0][2]=2, a[1][0]=3, a[1][1]=4, a[1][2]=5.
Если в списке инициализаторов данных не хватает, то соответствующему элементу присваивается значение 0.