Одинарный указатель – это одномерный массив



 

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

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; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!