2010-12-14 4 views
0

2次元配列を関数に渡すときに問題が発生したが、後でAとBのような解決法が見つかった。2次元配列が連続したメモリ1dとして。だから、私の意見では、実際に2次元の点はありません、コンパイラは、この連続数を分割し、 '2次元'の概念を作った。関数のポインタの2D配列を渡す方法が異なる

私の質問は、明示的にコンパイラにパラメータを 'int **'と伝えた後、なぜ2次元の点を渡さなかったのですか?

誰かが "コンパイラにグループ長を教えていない"と指摘するかもしれませんが、私はこの情報を知っていると思います。なぜなら、12要素のプレーンメモリをarr [2] [6] "void printArr(int _arr [] [6]、int _columns、int _rows)"のようにエラーになります。

助けてください少し混乱...

int arr[][3]={{1,2,3},{5,6,7},{9,10,11},{13,14,15}}; 

void printArr(int _arr[][3], int _columns, int _rows){ //----->A 
void printArr(int (* _arr)[3], int _columns, int _rows){//---->B 
void printArr(int** _arr, int _columns, int _rows){//--------->C 
    for(int r=0; r< _rows; r++){ 
     for (int c=0; c<_columns; c++) 
      //printf("%4d,", _arr[r][c]); 
      printf("%4d,", *(*(_arr+r)+c)); 
    } 
} 
int main(){ 
    printArr(arr, columns, rows); 
} 
+0

http://c-faq.com/aryptr/index.htmlが質問に答えているかどうかを確認してください。読むべきことはたくさんありますが、実際には適切なCコードを書くための配列とポインタの理解が必要です。誰も簡単なことは誰も言わなかった。 –

答えて

0

のint **はintへのポインタへのポインタではなく、2次元の配列へのポインタです。

2

配列がポインタに崩壊すると、配列の配列がint arr[x][y]の場合、配列int (*arr)[y]へのポインタに崩壊する可能性があります。

int ** arrは、配列の互換性のないタイプのポインタint *arr[x]の崩壊した配列のバージョンになります。

0

スタイルノート:識別子の先頭にアンダースコアを使用しないでください。そのような名前は実装のために予約されています。

解決策Bは、何が起こっているかを明示的にキャプチャします。 printArrの呼び出しでは、の式arrが「3要素配列のintの4要素配列」から「3要素配列のintへのポインタ」に暗黙的に変換されます。

ただし、関数パラメータ宣言の文脈では、T a[]という表記はT *aと同義語です。したがって、ソリューションAは、ソリューションBと事実上同じです。

-1

コンパイラが連続したメモリブロックを予約しているので、私の例のようなことをすることができます。また、1d配列、すなわちprintArr((int *)arr、1、10);で動作します。

void printArr(int *_arr, int _columns, int _rows) { 
    for(int r = 0; r < _rows; r++) { 
     for (int c = 0; c < _columns; c++) { 
      printf("%4d,", _arr[r * _columns + c]); 
     } 
    } 
} 

int arr[][3]={{1,2,3},{5,6,7},{9,10,11},{13,14,15}}; 
printArr((int*)arr, 3, 4); 

私は二つの変更がint * int型ではなく、**でパラメータ化されており、あなたのオフセット計算が間違っていたC.と非常に接近していたと思います。

関連する問題