Во-первых, я уже рассмотрел эти:
Как многомерные массивы форматируются в памяти?
Карта памяти для двумерного массива в C
Отсюда известно, что 2D-массив не то же самое, что и char**, но в памяти они выглядят точно так же. Это звучит странно, поэтому я исследовал следующее:
#include <stdio.h>
char func(char** m) {
return m[0][0]; //only works for char**, already discussed in the other SO question
}
int main() {
//char a[4][2]; //a 2D char array
int row = 4, col = 2; //char**
char** a = malloc(row * sizeof(char*));
int i;
for (i = 0; i < row; i++) {
a[i] = malloc(col * sizeof(char));
}
//checking the output
printf(" &a = %u\n", &a);
printf(" &a[0] = %u\n", &a[0]);
printf("&a[0][0] = %u\n", &a[0][0]);
printf(" a = %u\n", a);
printf(" a[0] = %u\n", a[0]);
//printf(" a[0][0] = %u\n", a[0][0]); //char value in a[0][0], here a garbage value
//char m = func(a); //only works for char**, already discussed in the other SO question
return 0;
}
Возможный вывод для char** :
&a = 3209288 // &a
&a[0] = 4083720 // &(*(a+0)) = a
&a[0][0] = 4083784 // &(*(*(a+0)+0)) = *a
a = 4083720 // a
a[0] = 4083784 // *(a+0) = *a
Возможный вывод для массива 2D-символов:
&a = 3473104 // &a
&a[0] = 3473104 // a
&a[0][0] = 3473104 // *a
a = 3473104 // a
a[0] = 3473104 // *a
Легко понять вывод char**. Но вывод массива 2D-символов выглядит странно, хотя это обсуждалось в другом вопросе SO. Я не могу придумать указатель x любого типа данных, когда
x = &x = *x
и все три вещи физически находятся в одном блоке памяти. Надеюсь, что мое замешательство понятно. Кто-нибудь может объяснить загадку?
Отсюда известно, что 2D-массив не совпадает с char**
, но в памяти они выглядят точно так же. Это не так. — person arnobpl schedule 10.05.2014
@self: я только что сослался на утверждение из других упомянутых вопросов SO. Я смущен. — person arnobpl schedule 10.05.2014
Не могу найти эту цитату, можете указать? — person arnobpl schedule 10.05.2014
@self: Не совсем цитата, но похожая вещь. — person arnobpl schedule 10.05.2014
Когда вы используете в качестве имени массива любое выражение, кроме
&array
иsizeof array
, это имя будет автоматически преобразовано в указатель на первый элемент массива (char [5][10]
будет преобразовано вchar (*)[10]
). Адрес этого указателя будет равен адресу всего массива.Итак, «sizeof (char [5][10]) == 50», дополнительных указателей нет.
Хороший ответ, хотя и не такой ясный, как я ожидал. Прочитав несколько статей, я понял, что массивы не являются указателями, и наоборот. Определенные особенности языка, кажется, сговорились, чтобы заставить меня думать, что они эквивалентны. На самом деле это не так. — person arnobpl; 12.05.2014