Является ли 2-мерный массив двойным указателем? [дубликат]

37
задан Jason Orendorff 27 September 2012 в 11:56
поделиться

4 ответа

Является ли двумерный массив двойным указателем?

Нет. Эта строка вашей программы неверна:

int **ptr = (int**)matrix;

Этот ответ касается той же темы

Если вы хотите конкретное изображение, как реализованы многомерные массивы:

Правила для многомерных массивов не отличаются от правил для обычных массивов, просто замените «внутренний» тип массива на тип элемента. Элементы массива хранятся в памяти непосредственно друг за другом:

matrix: 11 22 33 99 44 55 66 110
        -----------               the first element of matrix
                    ------------  the second element of matrix

Поэтому для адресации элемента matrix[x][y] берется the base address of matrix + x*4 + y (4 - размер внутреннего массива).

Когда массивы передаются функциям, они распадаются на указатели на их первый элемент. Как вы заметили, это будет int (*)[4]. Затем 4 в типе сообщит компилятору размер внутреннего типа, поэтому он работает. При выполнении арифметики с указателем на аналогичном указателе компилятор добавляет кратные размеры элемента, поэтому для matrix_ptr[x][y] вы получите matrix_ptr + x*4 + y, что в точности соответствует описанному выше.

Таким образом, приведение ptr=(int**)matrix неверно. На этот раз *ptr будет означать значение указателя, сохраненное по адресу матрицы, но его нет. Во-вторых, в памяти программы нет указателя на matrix[1].

Примечание: вычисления в этом посте предполагают sizeof(int)==1, чтобы избежать ненужной сложности.

40
ответ дан 27 November 2019 в 04:52
поделиться

Нет. Многомерный массив - это один блок памяти. Размер блока - это произведение размеров, умноженное на размер типа элементов, и индексация в каждой паре скобок смещений в массиве на произведение размеров на оставшиеся измерения. Так ..

int arr[5][3][2];

является массивом, который содержит 30 int с. arr[0][0][0] дает первое, arr[1][0][0] дает седьмое (смещение на 3 * 2). arr[0][1][0] дает третий (смещения на 2).

Указатели, на которые распадается массив, будут зависеть от уровня; arr затухает до указателя на массив 3x2 int, arr[0] затухает до указателя на массив из 2 элементов int, а arr [0] [0] затухает до указателя на int.

Однако, вы также можете иметь массив указателей и рассматривать его как многомерный массив - но это требует некоторой дополнительной настройки, потому что вы должны установить каждый указатель на его массив. Кроме того, вы теряете информацию о размерах массивов в массиве (sizeof даст размер указателя). С другой стороны, вы получаете возможность иметь подразборы различного размера и менять место расположения указателей, что полезно, если их нужно изменить или переставить. Массив таких указателей может быть проиндексирован как многомерный массив, даже если он размещен и расположен по-разному, и sizeof не всегда будет вести себя с ним одинаково. Статически распределенным примером такой установки будет:

int *arr[3];
int aa[2] = { 10, 11 }, 
    ab[2] = { 12, 13 }, 
    ac[2] = { 14, 15 };
arr[0] = aa;
arr[1] = ab;
arr[2] = ac;

После вышеупомянутого arr[1][0] равно 12. Но вместо того, чтобы выдавать int, найденный в 1 * 2 * sizeof(int) байтах после начального адреса массива arr, он дает int, найденный в 0 * sizeof(int) байтах после адреса, на который указывает arr[1]. Кроме того, sizeof(arr[0]) эквивалентно sizeof(int *) вместо sizeof(int) * 2.

10
ответ дан 27 November 2019 в 04:52
поделиться

В C нет ничего особенного, что вам нужно знать, чтобы понимать многомерные массивы. Они работают точно так же, как если бы они никогда не упоминались специально. Все, что вам нужно знать, это то, что вы можете создать массив любого типа, включая массив.

Итак, когда вы видите:

int matrix [2] [4];

Просто подумайте: «matrix - это массив из 2 вещей - эти вещи являются массивами из 4 целых чисел ". Все нормальные правила для массивов применяются. Например, matrix может легко превратиться в указатель на его первый член, как и любой другой массив, который в этом случае является массивом из четырех целых чисел. (Который может, конечно, сам по себе разлагаться.)

2
ответ дан 27 November 2019 в 04:52
поделиться

Если вы можете использовать стек для этих данных (небольшой объем), тогда вы обычно определяете матрицу:

int matrix[X][Y]

Когда вы хотите разместить его в куче (большой объем), вы обычно определяете a:

int** matrix = NULL;

и затем выделите два измерения с помощью malloc / calloc. Вы можете рассматривать 2d массив как int **, но это не очень хорошая практика, так как это делает код менее читабельным. Другое то что

**matrix == matrix[0][0] is true
0
ответ дан 27 November 2019 в 04:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: