Подтвердить что ты не робот

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

int main()
{
    matrix[2][4] = {{11,22,33,99},{44,55,66,110}};
    int **ptr = (int**)matrix;
    printf("%d%d",**matrix,*ptr);
}

Но когда 2-й массив передается как параметр, он вводится в (* matrix) [2]. какой тип компилятор хранит этот массив, поскольку... он хранится как 2-мерный массив или двойной указатель или указатель на массив. Если он хранит в виде массива, как он интерпретируется по-разному в разных ситуациях, таких как выше, Пожалуйста, помогите мне понять.

4b9b3361

Ответ 1

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

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

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, чтобы избежать ненужной сложности.

Ответ 2

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

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

- массив, содержащий 30 int s. 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.

Ответ 3

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

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

int matrix [2] [4];

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

Ответ 4

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

int matrix[X][Y]

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

int** matrix = NULL;

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

**matrix == matrix[0][0] is true