1

a 、 &a 、 &a[0] 、 a[0] はすべて同じアドレスを持っています...ある意味でそれ自体を指しているポインターのようです。 ..そして、それは正しくありません...これは1年近く私を悩ませており、ウェブで検索しても適切な答えが得られませんでした.....助けは本当に感謝しています....ありがとう

enter code here

#include<stdio.h>

int main()
{
    int a[2][3]={10,20,30,40,50,60};

    int row =0,col=0;

    printf("&a = %d ",&a);    
    printf("\na = %d ",a);
    printf("\n&a[0] = %d ",&a[0]);
    printf("\na[0] = %d ",a[0]);
    printf("\n&a[1] = %d ",&a[1]);
    printf("\na[1] = %d ",a[1]);
    printf("\n&a[0][0] = %d ",&a[0][0]);

    int *p;
    printf("\n\n sizeof(p) = %d ",sizeof(p) );

    printf("\n\n sizeof(a) = %d ",sizeof(a) );
    printf("\n\n sizeof(&a) = %d ",sizeof(&a) );
    printf("\n\n sizeof(&a[0]) = %d ",sizeof(&a[0]) );
    printf("\n\n sizeof(a[0]) = %d ",sizeof(a[0]) );
    printf("\n\n sizeof(&a[1]) = %d ",sizeof(&a[1]) );
    printf("\n\n sizeof(a[1]) = %d ",sizeof(a[1]) );
    printf("\n\n sizeof(&a[0][0]) = %d ",sizeof(&a[0][0]) );
}

出力

&a = 2293536
a = 2293536
&a[0] = 2293536
a[0] = 2293536
&a[1] = 2293548
a[1] = 2293548
&a[0][0] = 2293536

sizeof(p) = 4

sizeof(a) = 24

sizeof(&a) = 4

sizeof(&a[0]) = 4

sizeof(a[0]) = 12

sizeof(&a[1]) = 4

sizeof(a[1]) = 12

sizeof(&a[0][0]) = 4

C の 2D 配列のメモリ マップを参照しないでください ... 役に立ちませんでした ...

4

2 に答える 2

5

したがって、配列aはメモリのブロックを占有する 1 つのオブジェクトです。

| a                                                         |

これは長さ 2 の配列なので、それを構成する要素を描画すると、次のようになります。

| a[0]                        | a[1]                        |

a[0]次に、長さ 3 の配列であり、次のようになります。

| a[0][0] | a[0][1] | a[0][2] |

a[1]同じように見えるので、配列aを次のように再描画できます。

| a[0][0] | a[0][1] | a[0][2] | a[1][0] | a[1][1] | a[1][2] |

aa[0]a[0][0]がすべてメモリ内の同じポイント、つまりオブジェクトの開始点にあることに注意してくださいa。ただし、サイズは異なります。a「2D 配列」全体でa[0]あり、通常の配列でありa[0][0]、単一の `int です。

&aこれは、&a[0]とが同じアドレスである理由を説明し&a[0][0]ています (タイプは異なりますが)。これらは、メモリ内の同じポイントにあるもののアドレスです。

さらに、配列が単項演算子&またはsizeof演算子の対象ではない式で評価される場合、最初の要素へのポインターに評価されるという規則があります。つまり、プレーンを使用するaと と同等&a[0]です。a[0]も配列であるため、プレーンを使用することはa[0]と同等&a[0][0]です。これは、 と が、および と 同じアドレスに評価される理由aを説明しています。a[0]&a&a[0]&a[0][0]

配列のアドレスとその配列の最初の要素のアドレスが同じであるという事実は、それほど驚くべきことではありません。同じことがstructにも起こります。与えられた:

struct { int a; int b; } x;

&xとが同じアドレスであることがわかり&x.aます (タイプは異なりますが)。

于 2012-10-18T10:50:07.877 に答える
1

sizeof _Alignof、または単項演算子のオペランドである場合、または&宣言で別の配列を初期化するために使用される文字列リテラルである場合を除いて、「の N 要素配列」型のTは、「へのポインタ」型の式に変換されます。T" 式の値は、配列の最初の要素のアドレスになります。

次のメモリ マップを想定します (リトル エンディアン、4 バイトintの s を想定、アドレスはどこからともなく引き出されます)。

項目 アドレス 00 01 02 03 サブ配列 サブ配列要素
---- ---------- -- -- -- -- ---------- -----------------
   0xfffebc00 00 00 00 0a [0] a[0][0]
             0xfffebc04 00 00 00 14 a[0][1]
             0xfffebc08 00 00 00 1e[0][2]
             0xfffebc0c 00 00 00 28 a[1] a[1][0]
             0xfffebc10 00 00 00 32 a[1][1]
             0xfffebc14 00 00 00 3c [1][2]

上記のルールに従って、 は「 の 3 要素配列の 2 要素配列」から「 の 3 要素配列へのポインタ」a型に変換され、式の値は最初のアドレスになります。配列の要素。の最初の要素はで、アドレスはです。 intintaa[0]a[0]0xfffebc00

同様に、式a[0]は「の 3 要素配列」型から「へのintポインタ」型に変換されint、その値は配列の最初の要素のアドレスになります。の最初の要素a[0]a[0][0]で、そのアドレスは ... です0xfffebc00

この式&aは、上記の規則の例外の 1 つです。この場合、演算子aを適用する前にポインター型に変換されません。&式の型は「3要素配列の2要素配列へのポインタint」( int (*)[2][3])で、その値は のアドレスa、つまり ... です0xfffebc00

同様に、式の&a[0]型は「の 3 要素配列へのポインタint」であり、その値は のアドレスa[0]、つまり ... です0xfffebc00

うまくいけば、の型と値は&a[0][0]明らかであるべきです。

そうです、式a&a*aa[0]&a[0]、および&a[0][0]はすべて同じを生成しますが、それらの型は異なります: int (*)[3]int (*)[2][3]`int *int *int (*)[3]、およびint *、それぞれ。

于 2012-10-18T11:42:19.780 に答える