Связь указателей и массивов.

Идентификатор массива указывает адрес памяти, начиная с которого он расположен, т.е. адрес его первого элемента. Работа с массивами тесно связана с применением указателей.

Пусть объявлен массив a из 5 целочисленных элементов:

 

int a[5];

 

a

a[0] a[1] a[2] a[3] a[4]

4000 4004 4008 4012 4016

Здесь приведено символическое изображение оперативной памяти, выделенной компилятором для объявленного целочисленного массива а[5]. Адрес массива выбирается компилятором в зависимости от размера доступной памяти, наличия других переменных и массивов и др. Для конкретности, здесь положено значение адреса, равное 4000. В реальной программе вместо 4000 может быть другое значение, но относительное положение элементов массива всегда остается постоянным.

В языке С идентифи­каторы массивов считаются константными указателями (т.е. в данном примере а "имеет значение" 4000). Такую константу можно присвоить переменной типа указатель, но нельзя подвергать преобразованиям, например:

 

int a[5], *q;

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

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

 

Именно потому, что имена массивов считаются константными указателями, в языке Си нельзя непосредственно присваивать массивы друг другу (хотя структуры, включающие массивы как поля, целиком присваивать друг другу можно!)

Однако операция sizeof для массивов все же дает размер массива, а не указателя:

 

int n = sizeof(a) / sizeof(*a);

// n=5, т.к. sizeof(a)=20, sizeof(int)=4

 

int m = sizeof(q) / sizeof(*q);

// m=1, т.к. sizeof(int*)=4, sizeof(int)=4