2016-07-12 23 views
1

私は "新しいアプローチ"を読んで素敵な理論に会いました。 a[0]&a[0]の違いは、2次元配列a[i][j]です。多次元配列とポインタ

それは次のように次の:

int a[NUM_ROWS][NUM_COLS], *p, i; 

for(p = a[i]; p < a[i] + NUM_COLS; p++) 
*p = 0; 

他の事は次のようになります:

int a[NUM_ROWS][NUM_COLS], (*p)[NUM_COLS], i; 

for(p = &a[0]; p < &a[NUM_ROWS]; p++) 
(*p)[i] = 0; 

いただきましa[0]&a[0]の違いは?

答えて

1

にカラムi内の各要素は、宣言

T a[N][M]; // for any type T 

を考えると、次の該当する:

Expression  Type   Decays to   Value 
----------  ----   ---------   ----- 
     a  T [N][M]  T (*)[M]    Address of a[0] 
     &a  T (*)[N][M]  n/a     Address of a 
     *a  T [M]   T *     Address of a[0][0] 
     a[i]  T [M]   T *     Address of a[i][0] 
    &a[i]  T (*)[M]  n/a     Address of a[i] 
    *a[i]  T    n/a     Value of a[i][0] 
    a[i][j]  T    n/a     Value of a[i][j] 
    &a[i][j]  T *    n/a     Address of a[i][j] 

a&aa[0]&a[0]、及び&a[0][0]全て(配列のアドレスは、arの最初の要素のアドレスと同じです。 X線)のタイプのが異なります。

したがって、上記の宣言が与えられ、式a[0]は、sizeof演算子のオペランドでない限りT *を入力するために「崩壊」は、T [M]TM -element配列)を入力しています。式&a[0]は、タイプT (*)[M]ポインタM〜要素配列T)です。

が宣言最初

T a[N][M]; 
T *p0 = a[0]; 
T (*p1)[M] = &a[0]; 

を想定、p0p1は同じ値(a[0][0]のアドレス)を含みます。私たちは、次のコード実行した場合しかし、:

p0++; 
p1++; 

p1a[1][0]のアドレスが含まれていながら、その後p0は、a[0][1]のアドレスが含まれています。 p0++ の次のオブジェクトを指すようにp0を進める一方で、p1++は、T [M]の次のオブジェクトを指すようにp1を進める。

+0

今私はそれをすべて理解しています。ありがとう! –

4

a[0]は、2D配列の最初の行で、タイプがint [NUM_COLS]です。

&a[0]は、その行のアドレスであり、タイプはint (*)[NUM_COLS]です。

最初のコード例では、pint *です。特定の状況では、配列は最初の要素へのポインタに減衰するため、p = a[i]を実行することはできます。その後p[n]a[i][n]は同じです。

最初のコードセグメントがforループを通過するとき、各反復で1つずつ0を加算して、行内の連続する要素を指すようにします。したがって、最初のコードブロックは、あなたがそれに行のアドレスを割り当てることができるようpは、タイプint (*)[NUM_COLS]であり、第2の例では0

に行iの各要素を設定します。ループが繰り返されると、pがインクリメントされ、次のの行を指すようになります。そのコードブロックセットに0

+1

行と列を混同します。 'a [0]'は最初の行など – Olaf

+0

@Olaf良いキャッチ。一定。 – dbush

+0

修正されていません! 'a [0]'には 'int [NUM_COLS]'などの型があります。 – Olaf