4

次のコードを検討してください

#include <stdio.h>
#define ROW_SIZE 2
#define COL_SIZE 2

int main()
{
   int a[ROW_SIZE][COL_SIZE]={{1,2},{3,4}};

   // Base address:Pointer to the first element a 1D array
   printf("Base address of array:%p\n",a);

   //The value at the base address: should be the address of 1st 1D array
   printf("Value at the Base address:%p\n",*a);

   return 0;
}

得られた出力:

Sample Output:
Base address of array:0xbff77434
Value at the Base address:0xbff77434

どういうわけか、2D配列のベースアドレスの概念と、1D配列へのアドレスが同じであるベースアドレスの値を理解できていません。説明してください。

4

4 に答える 4

7

配列はポインターではありません。Cでは、多次元配列は単なる配列の配列です。多くの場合、配列の名前を使用すると、その配列の最初の要素へのポインタに「減衰」します。これが、両方の印刷ステートメントで発生することです。最初のケースでは:

printf("Base address of array:%p\n",a);

a配列の最初の要素へのポインタ、つまり配列の最初の行へのポインタになります。あなたの場合、それはあなたがタイプのポインタを取得することを意味しますint (*)[2]

2番目の場合:

printf("Value at the Base address:%p\n",*a);

同じ減衰が発生しますが、そのポインタを逆参照します。つまり、そのint (*)[2]ポインタを最初の行に逆参照して、再び配列(最初の行)を残します。その配列自体が最初の要素へのポインターに減衰し、結果として(最初の行の最初の要素への)ポインターが得られます。int *

どちらの場合も、アドレスは同じです。これは、配列がメモリに配置される方法だからです。2D配列がアドレスで開始されたとすると、次のようになります(4バイト型0を想定)。int

 Address       Value
    0            1
    4            2
    8            3
   12            4

最初の行のアドレスと最初の行の最初の要素のアドレスは両方とも0です。

于 2012-10-12T22:41:51.927 に答える
7

質問の図を再構成し、以前の回答からの情報を統合して、次の回答を作成しています。

配列とポインタ

一次元配列

  • 4つの整数の配列aを次のように考えます。a[4]
  • 基本的なルールは両方aであり&a、同じ場所を指しますが、同じタイプを指しているわけではありません。
  • &aである配列全体を指しint[]ます。ポインタの種類はint(*)[]
  • a、ポインタに減衰すると、配列の最初の要素である。を指しますint。ポインタの種類はint *

二次元配列

  • それぞれが2つの要素を持つ2つの1D配列を含む配列を考えてみましょう。a[2][2]
  • ディメンションの数が増えるため、階層のレベルがもう1つあります。つまり、&a同じ場所を指しますが、同じタイプを指しているわけではありません。a*a
  • &aである配列全体を指しint[][]ます。ポインタの種類はint(*)[][]です。
  • a、ポインタに減衰すると、2D配列の最初の要素である。を指しますint[]。ポインタの種類はint(*)[]
  • を使用*aして、1D配列へのポインターを逆参照しています。したがってint *、2D配列の最初の整数値を指すようになります。
于 2012-10-13T01:46:41.900 に答える
0

私はあなたの出力のフォーマットがあなたを投げていると思います。そうです、最初の配列要素(0xbff77434)のアドレスは値(1)とは異なります。%pは、両方を「ポインタ」形式に強制しようとすると混乱します。

そして、はい、カールも正しいです。

最初の要素に何があるかを確認したい場合は、次のいずれかを言います。

printf("%i", a[0][0]);

int* p = &a[0][0];    // point 'p' to the beginning of 'a'
// (or)
int* p = a;           // saying "&a[0][0]" is the same as saying "a"
printf("%i", *p);     // here, the dereference is what you want

1Dアレイと2Dアレイに関しては、解釈の問題です。両方

int x[4];

int x[2][2];

4つの「intサイズ」要素の連続したブロックを作成します。また、どちらの場合も、式'x'は0番目のエントリのアドレス(たとえば、配列のアドレス)を参照します。

于 2012-10-12T22:54:54.130 に答える
0

2次元配列a[2][2]は、4つの要素を持つ1次元配列と見なすことができます。ポインタにキャストaするとどうなるか考えてみてください。int*

int a[2][2] = {{ 1, 2 }, { 3, 4 }};
int* p = (int*) a; // == { 1, 2, 3, 4 }

assert(a[1][0] == p[2] == 3); // true

int* a0 = a[0];  // the first row in the bidimensional array
int* p0 = &p[0]; // the first element in the monodimensional array

assert(*a0 == *p0 == 1); // true

// Or the long version:
assert(a[0][0] == *a0 == a0[0] == p[0] == *p0 == p0[0] == 1); // true

// And for the second array in a:
int* a1 = a[1]; // the second row in the bidimensional array
int p2 = &p[2]; // the third element in the monodimensional array

assert(a[1][0] == *a1 == a1[0] == p[2] == *p2 == p2[0] == 3); // true

配列aa[0]は基本的に同じアドレスを指しますが、それらの型はそれらがどのように操作されるかについての情報を伝えます。

于 2012-10-12T23:20:17.607 に答える