Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
SAOD_Konspekt-I.doc
Скачиваний:
14
Добавлен:
03.11.2018
Размер:
2.32 Mб
Скачать

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

Любое действие, которое достигается индексированием массива, может быть выполнено также с помощью указателей, причём последний вариант будет быстрее.

Объявление

int a[5];

определяет массив из 5 элементов. Если объект *y объявлен как

int *y;

то оператор

y = &a[0];

присваивает переменной y адрес элемента a[0]. Если переменная y указывает на очередной элемент массива a, то y+1 указывает на следующий элемент, причём здесь выполняется масштабирование для приращения адреса с учётом длины объекта. Поскольку имя массива есть адрес его нулевого (начального) элемента (и указатель на этот элемент), то инструкцию y = &a[0] можно записать в виде

y = a;

Тогда элемент a[i] можно представить как *(a+i). Если у – указатель, следующие записи эквивалентны:

a[i] ~ *(a+i)

y[i] ~ *(y+i)

Таким образом, любой массив (и индексное выражение) можно представить при помощи указателей.

a[5] // массив

a – имя массива

y = &a[0] – адрес нулевого элемента массива

a – адрес нулевого элемента массива

x0 – содержимое 0-го элемента массива

a[0] = x0;

a[1] = x1;

x0 = *y = *a = a[0]

x1 = *(y+1) = *(a+1) = a[1]

В то же время между именем массива и соответствующим указателем есть одно существенное различие. Указатель – это переменная и y = a; или y++; – допустимые операции. Имя массива – это константа. Поэтому конструкции вида

a = y; a++;

использовать нельзя, т.к. значение константы постоянно и не может быть изменено.

Если указатели адресуют элементы одного массива, то их можно сравнивать (в операциях отношения). В то же время нельзя сравнивать, либо применять в арифметических операциях указатели на разные массивы. Указатели на элементы одного массива можно вычитать, результатом будет число элементов массива, расположенных между уменьшаемым и вычитаемым указателями.

Доступ к элементам многомерных массивов также возможен с помощью указателей:

b[i][j][k] ~ *(*(*(b+i)+j)+k)

Допускается комбинировать обе формы доступа к элементам многомерного массива:

b[i][j][k] ~ *(b[i][j]+k)

Обращение к элементу массива в языке C++ относится к постфиксному выражению вида

PE[IE]

Постфиксное выражение PE должно быть указателем на нужный тип, выражение IE должно быть одного из целых типов. Таким образом, если PE – указатель, адресующий массив, то PE[IE] – индексированный элемент этого массива. Выражение

*(PE+IE)

– другой способ доступа к этому же элементу массива. Возможна эквивалентная запись

*(IE+PE)

т.к. операция «+» – коммутативна, и следовательно

IE[PE]

адресует тот же элемент, что и PE[IE].

int m[] = {1,2,3,4,};

m[0] ~ 1

0[m] ~ 1

Иногда индексы могут иметь отрицательные значения. В этом случае указатель PE должен указывать не на начало массива.

Можно определить указатель, инициализированный именем массива, т.е. адресом начального элемента этого массива.

int m[] = {1,2,3,4,};

int *mp = m;

mp[0] ~ 1, *(mp+3) ~ 4

Иногда для такого указателя используется термин «указатель на массив». Следует внимательно относится к употреблению этого термина. Его применение для указателя, используемого в рассмотренном примере, является, в сущности, программистским жаргоном, не вполне оправданно и совсем не правильно с точки зрения типов данных. В дальнейшем будем для обозначения указателя, адресующего массив, применять термин «указатель на массив» в кавычках, для того, чтобы не путать его с типами данных указателей на массив.

«Указатель на массив», в отличие от имени массива, является обычным указателем, не константным, со всеми вытекающими последствиями. Операция sizeof, примененная к такому указателю, даёт количество байт, занятых именно указателем, а не адресуемым им массивом. Операция получения адреса & позволяет получить адрес указателя, а не адрес начала массива. Наконец, значение такого указателя может быть изменено, и он уже не будет адресовать массив.

Однако такой указатель, также как и имя массива, может использоваться для доступа к элементам массива с помощью операций [ ] и *, как в рассмотренном примере.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]