2014-05-10 4 views
2

Во-первых, я уже рассмотрел эти:Разница между 2D массив символов и символ ** (OR, 3D массив символов и полукокса *** и т.д.)

How are multi-dimensional arrays formatted in memory?

Memory map for a 2D array in 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; 
} 

Возможный выход для гольца **:

 &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. Я не могу думать о указателе х из каких-либо типа данных, когда,

х = & х = * х

и все 3 вещей, которые физически находятся в тот же блок памяти. Надеюсь, что моя путаница понятна. Может ли кто-нибудь объяснить тайну?

+1

* Оттуда, известно, что 2D-массив не такой же, как '' гольца ** но в памяти они выглядят точно так же * Это не так – this

+0

@self:. Я только реферирована заявление из других упомянутых вопросов SO. Я смущен. – arnobpl

+0

Я не могу найти эту цитату, можете ли вы указать на нее? – this

ответ

0

При использовании имя массива является любое выражение, кроме &array и sizeof array это имя будет автоматически преобразован в указатель на первый элемент массива (char [5][10] будут преобразованы в char (*)[10]). Адрес этого указателя будет равен адресу целого массива.
Итак, «sizeof (char [5] [10]) == 50», дополнительных указателей нет.

char arr[5][10]; 

&a = 3473104 // Address of entire array, (char (*)[5][10]) 
&a[0] = 3473104 // Address of first row, (char (*)[10]) 
&a[0][0] = 3473104 // Address of first char, (char *) 
a = 3473104 // "a", (char [5][10]), converted to "&a[0]", (char (*)[10]) 
a[0] = 3473104 // "a[0]", (char[10]), converted ro "&a[0][0]", (char *) 
+0

Хороший ответ, хотя и не столь ясный, как я ожидал. Читая несколько статей, я понял, что массивы не являются указателями, и наоборот. Некоторые особенности языка, похоже, сговариваются, чтобы заставить меня думать, что они эквивалентны. На самом деле это не так. – arnobpl

Смежные вопросы