Массивы и указатели
В языке C массивы и указатели тесно связаны друг с другом. Например, когда объявляется массив в виде int a[25], то при этом не только выделяется память для 25 элементов массива, но и формируется указатель с именем a, значение которого равно адресу первого по счету (нулевого) элемента массива. Доступ к элементам массива может осуществляться через указатель с именем a. С точки зрения синтаксиса языка указатель a является константой, значение которой можно использовать в выражениях, но изменить это значение нельзя.
Поскольку имя массива является указателем-константой, допустимо, например, такое присваивание:
int a[25];
int *ptr;
ptr=a;
В этом примере в переменную-указатель ptr записывается адрес начала массива a, т. е. адрес первого элемента массива.
Также справедливы следующие соотношения: например, имеется массив a[N], тогда истинными будут следующие сравнения:
a==a[0];
*a==a[0].
Указатели можно увеличивать или уменьшать на целое число:
ptr=a+1;
Теперь указатель ptr будет указывать на второй элемент массива a, что эквивалентно a[1].
При увеличении указателя на единицу адрес, который он представляет, увеличивается на размер объекта связанного с ним типа, например:
int a[25];
int *ptr=a;
ptr+=3;
Первоначально указатель ptr указывал на начало массива a. После прибавления к переменной ptr числа 3 значение указателя увеличилось на 3*sizeof(int), а указатель ptr теперь будет указывать на четвертый элемент массива a. Указатель можно индексировать точно так же, как и массив. На самом деле компилятор преобразует индексацию в арифметику указателей, например, ptr[3]=10 представляется как *(ptr+3)=10.
К указателям типа void арифметические операции применять нельзя, так как им не ставится в соответствие размер области памяти.
Таким образом, в языке C для доступа к элементам массива существует два различных способа. Первый способ связан с использованием обычных индексных выражений в квадратных скобках, например, a[7]=3 или a[i+2]=5. При таком способе доступа записываются два выражения, причем второе выражение заключается в квадратные скобки. Первое из этих выражений должно быть указателем, а второе – выражением целого типа. Указатель, используемый в индексном выражении, не обязательно должен быть константой, указывающей на какой-либо массив, это может быть и переменная-указатель. В частности, после выполнения присваивания ptr=a доступ к седьмому элементу массива можно получить как с помощью константы-указателя a в форме a[7], таки переменной-указателя ptr в форме ptr[7].
Второй способ доступа к элементам массива связан с использованием адресных выражений и операции косвенной адресации в форме *(a+3)=10 или *(a+i+2)=5.
При реализации на компьютере первый способ приводится ко второму, т. е. индексное выражение приводится к адресному. Для приведенных примеров обращение к элементу массива a[3] преобразуется в *(a+3).
Для доступа к начальному элементу массива, т. е. к элементу с нулевым индексом, можно использовать просто значение указателя a или ptr, поэтому любое из присваиваний
*a=2;
a[0]=2;
*(a+0)=2;
*ptr=2;
ptr[0]=2;
*(ptr+0)=2;
присваивает начальному элементу массива значение 2.
Многомерные массивы в языке C – это массивы массивов, т. е. массивы, элементами которых, в свою очередь, являются массивы. При объявлении таких массивов в памяти компьютера создается несколько различных объектов. Например, при выполнении объявления двумерного массива int a2[4][3] в программе создается указатель a2, который определяет в памяти местоположение первого элемента массива и, кроме того, является указателем на массив из четырех указателей. Каждый из этих четырех указателей содержит адрес одномерного массива, представляющего собой строку двумерного массива и состоящего из трех элементов типа int, и позволяет обратиться к соответствующей строке массива.
Таким образом, объявление a2[4][3] порождает в программе три разных объекта: указатель с идентификатором a2, безымянный массив из четырех указателей и безымянный массив из двенадцати чисел типа int. Для доступа к безымянным массивам используются адресные выражения с указателем a2. Доступ к элементам массива указателей осуществляется с указанием одного индексного выражения в форме a2[2] или *(a2+2). Для доступа к элементам двумерного массива чисел типа int должны быть использованы два индексных выражения в форме a2[1][2] или эквивалентных ей *(*(a2+1)+2) и (*(a2+1))[2]. Следует учитывать, что с точки зрения синтаксиса языка C указатель a2 и указатели a2[0], a2[1], a2[2], a2[3] являются константами, и их значения нельзя изменять во время выполнения программы.
Размещение трехмерного массива происходит аналогично. Так, например, объявление float a3[3][4][5] порождает в программе, кроме самого трехмерного массива из 60 чисел типа float, массив из четырех указателей на тип float, массив из трех указателей на массив указателей на float и указатель на массив массивов указателей на float.
При размещении элементов многомерных массивов они располагаются в памяти подряд по строкам, т. е. быстрее всего изменяется последний индекс, а медленнее – первый. Такой порядок дает возможность обращаться к любому элементу многомерного массива, используя адрес его начального элемента и только одно индексное выражение.
Например, обращение к элементу a2[1][2] можно осуществить при помощи указателяptr2, объявленного в форме int *ptr2=a2[0], как обращение ptr2[1?3+2] (здесь 1 и 2 – это индексы используемого элемента, а 3 – число элементов в строке) или какptr2[5]. Заметим, что внешне похожее обращение a2[6] выполнить невозможно, так как указателя с индексом 6 не существует.
Для обращения к элементу a3[2][3][4] из трехмерного массива тоже можно использовать указатель, описанный как float *ptr3=a3[0][0], с одним индексным выражением в форме ptr3[2?20+3?5+4] или ptr3[59].
Статьи к прочтению:
- Все отчеты собираются в отдельную папку – альбом лабораторных работ, для которого нужен титульный лист.
- Все задания составлены на основе школьной программы. поэтому каждый из вас может успешно справиться с работой.
Основы ООП C++. Урок 9 — Указатели
Похожие статьи:
-
Типы данных Программы оперируют с различными данными, которые могут быть простыми и структурированными. Простые данные — это целые и вещественные числа,…
-
Используя указатели и операции над ними выполнить следующие задания
Часа Методические материалы Указатели и Массивы. В С++ существует тесная связь между указателями и массивами. Любой доступ к элементу массива,…