Почему две звездочки при доступе к элементу двумерного массива с помощью указателей? - PullRequest
1 голос
/ 21 августа 2010

В C, когда мы обращаемся к a[i][j] с помощью указателей, зачем нам второй * в *(*(a + i) + j)?Используя printf(), я вижу, a + i и *(a + i) выводят одно и то же значение.

Ответы [ 3 ]

9 голосов
/ 21 августа 2010

a + i - указатель на i '-ый подмассив. Если вы разыменуете его, вы получите lvalue для i '-ого подмассива, который распадается на указатель на первый элемент этого массива. Адрес первого элемента массива и его массива совпадают.

Разыменование необходимо для вычисления + j с правильной шириной байта элемента. Если вы не разыменовываете, то вместо получения T* вы получите указатель T(*)[J], к которому добавляете j, который вместе с i перемещается в память, указывая вместо этого на (a + i + j) (продвигаясь на sizeof(T[J]) вместо sizeof(T)).

1 голос
/ 21 августа 2010

Хорошо, для этого требуется немного теории указателей.

Допустим, у нас есть

int** a = malloc(sizeof(int*) * 10);
int** p;
for(p = a; p < a + 10; p++) {
     *p = malloc(sizeof(int) * 15);
}

Это создает массив размером 10 на 15, реализованный с использованием указателей. Обратите внимание, что каждый элемент, содержащийся в блоке памяти, на который указывает a, имеет тип int* (потому что мы неправильно используем блок 15 int с).

Вот неполная диаграмма:

a
|
1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 8 - 9 - 10
|   |
|   1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15
|
1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15

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

0 голосов
/ 21 августа 2010

2D-массивы похожи на массивы.* (a + i) дает вам адрес одномерного массива, который находится в местоположении i от начального адреса.Теперь вам нужен элемент в местоположении j в этом массиве.Следовательно, вы добавляете j к нему и затем отменяете ссылку, используя * для доступа к этому элементу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...