38

パラメータを変更できないのはなぜですか

void example(int Array[][]){ /*statements*/}

配列の列サイズを指定する必要があるのはなぜですか? たとえば、3

void example(int Array[][3]){/*statements*/}

私の教授はそれが必須だと言いましたが、私は学校が始まる前にコーディングしていて、これを自分のパラメーターにしたときに構文上または意味上のエラーがなかったことを思い出しました? それとも私は何かを逃しましたか?

4

6 に答える 6

12

C/C++ では、2 次元配列であっても、1 行ずつメモリに順次格納されます。したがって、(単一の関数で)次の場合:

int a[5][3];
int *head;

head = &a[0][0];
a[2][1] = 2; // <--

あなたが実際にアクセスしている要素a[2][1]*(head + 2*3 + 1)、その要素が0行の3つの要素、行の3つの要素1、そしてさらにもう1つのインデックスの後にあります。

次のような関数を宣言すると:

void some_function(int array[][]) {...}

構文的には、エラーにはなりません。しかし、array[2][3]今アクセスしようとすると、どの要素にアクセスする必要があるのか​​ わかりません。一方、次の場合:

void some_function(int array[][5]) {...}

を使用すると、関数が 2 番目の次元のサイズを知っているためarray[2][3]、メモリ アドレスの要素に実際にアクセスしていると判断できます。*(&array[0][0] + 2*5 + 3)

前に提案したように、次のような関数を宣言できます。

void some_function(int *array, int cols) { ... }

このようにして、前と同じ「情報」で関数を呼び出しているため、列の数です。次に、配列要素へのアクセス方法が少し異なり*(array + i*cols + j)ます。通常は と書く場所にを書く必要がありますarray[i][j]。原因arrayは、(ポインターではなく) 整数へのポインターになりました。

このような関数を宣言するときは、使用されるだけでなく、配列に対して実際に宣言されている列の数で呼び出すように注意する必要があります。たとえば、次のようになります。

int main(){
   int a[5][5];
   int i, j;

   for (i = 0; i < 3; ++i){
       for (int j=0; j < 3; ++j){
           scanf("%d", &a[i][j]);
       }
   }

   some_function(&a[i][j], 5); // <- correct
   some_function(&a[i][j], 3); // <- wrong

   return 0;
}
于 2012-10-10T07:19:09.197 に答える
0

これについては、同様の投稿があります。以下のリンクから参照できます。 Cで配列を作成し、その配列へのポインタを関数に 渡す

一方、コンパイラは、メモリ全体が線形に配置されているため、「配列」をあるポインターから次のポインターに移動できるように、2 番目の次元を必要とします。

于 2012-10-10T06:57:31.213 に答える