Одинарный указатель – это одномерный массив
Одинарный указатель можно рассматривать, как одномерный массив и применять к нему операцию индексации.
int n=10, *pi;
pi = &i;
Тогда pi[0] – это переменная i, . pi[1] – это переменная типа int, расположенная справа от i, pi[-1] – это переменная типа int, расположенная слева от i.
Одномерный массив – это одинарный указатель
Имя одномерного массива, взятое само по себе, является константным указателем на начальный элемент этого массива. К имени массива можно применять операции указательной арифметики, не изменяющие содержимое указателя.
int A[5];
Тип А – это int *, базовый тип - int.
Значение А является адресом элемента A[0], поэтому *A – это начальный элемент массива А.
А+1 – это адрес элемента A[1], а разыменование *(А+1) – это A[1], *(А+4) – это последний элемент A[4], использование выражения *(А+5) в любой части операции присваивания является логической ошибкой выхода индекса массива за диапазон.
Внимание. Существенное различие между указателем и именем массива состоит в том, что указатель является переменной, размещаемой в ОЗУ. Указатель сам имеет адрес и занимает 2 или 4 байта в зависимости от того, ближний это указатель или дальний. Имя массива является адресной константой, не имеет адреса и не занимает места в ОЗУ.
Двумерный массив – это двойной указатель
Рассмотрим определение двумерного массива
int A[3][5];
Массив имеет три строки по пять элементов типа int. При этом A[0] – это начальная, строка из 5 элементов типа int, то есть одномерный массив из 5 элементов типа int. Но тип имени одномерного массива не содержит размера этого массива. Поэтому тип указателя A[0] – это int*, а базовый тип int.
|
|
Соответственно, А[1] – это первая строка массива, тип А[1] – это int*. Фактически A[0] – это адрес начального элемента нулевой строки, A[1] – это адрес начального элемента первой строки и т.д.
Обратите внимание, тип A[0] не содержит размера 5.
Рассмотрим имя двумерного массива А, взятое само по себе. Идентификатор А – это адрес начальной строки из 5 элементов типа int. Тип А – это int(*)[5]. В данном выражении участвуют три операции: круглые скобки (), индексация [] и разыменование*. Перечисление операций здесь идет по убыванию приоритета. Читать выражение int(*)[5] нужно следующим образом: указатель на массив из пяти элементов типа int.
Таким образом, тип указателя А содержит один из размеров двумерного массива, а именно количество столбцов. Отсюда вытекает, что два массива
int B[10][5], C[3][20];
имеют разные типы. Указатель В имеет тот же тип int(*)[5], а указатель С имеет другой тип int(*)[20].
Далее, применим к двойному константному указателю А указательные операции.
A+1 – это адрес первой строки из 5 элементов типа int. Тип A+1 – это int(*)[5], базовый тип – одномерный массив из пяти элементов типа int, то есть int*.
|
|
В общем случае, A+i это адрес i-ой строки из 5 элементов типа int. Тип A+i – это int(*)[5], базовый тип – одномерный массив из пяти элементов типа int, то есть int*.
*(A+i) – это сама i-ая строка из 5 элементов типа int, то есть адрес нулевого элемента первой строки. Тип *(A+i) – это int*, базовый тип *(A+i) – это int.
*(A+i) + j – это адрес j-го элемента i-ой строки. Тип *(A+i) + j – это int*, базовый тип int.
*(*(A+i) + j) – это сам j-й элемент i-ой строки. Тип *(*(A+i) + j) – int
Таким образом, двойная индексация A[i][j] равносильна записи
*(*(A+i) + j).
Двойной указатель – это двумерный массив
Двойные указатели не так часто используются в качестве двумерного массива.
Пример. Рассмотрим двойной указатель
int n=5;
int* pi = &n;
int **ppi = π
Построим схему ОЗУ для всех трех переменных
Рис.1.
Оператор
ppi[1][1] = 10;
синтаксически правильный, но логически ошибочен. В данном случае число 10 записано в наугад выбранной ячейке ОЗУ, что может приводить время от времени к фатальным ошибкам.
Оператор
ppi[0][1] = 20;
также синтаксически правильный, но логически ошибочен.
Пример. Рассмотрим массив строк
char *Arr[] = {“Hello”, “ ”, “World!”};
В соответствии с приоритетом операций тип Arr – это char*[], то есть массив типов char*, другими словами массив строк. Но строка – это одномерный массив элементов типа char, то есть тип строки – это char*. Поэтому тип Arr – это также и char**. Таким образом, мы показали, что Arr – двойной указатель.
Дата добавления: 2020-01-07; просмотров: 172; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!