1

これらの関数プロトタイプが同等ではないのはなぜですか?

void print_matrix(char *name, int SX, int SY, int m[SX][SY])

void print_matrix(char *name, int SX, int SY, int **m)
4

1 に答える 1

6

2つの関数の引数は同じ方法で、つまりを介して使用できますが、m[i][j]まったく異なります。

  • int m[M][N]intの配列のM配列です。N

  • int **mintへのポインタへのポインタです。

配列を関数の引数として渡すことはできないため、「型のK要素の配列」は、配列の最初の要素を指すT「pointer-to-」に減衰します。したがって、値が失われるため、関数の引数のTように最初の形式を記述することは許容され、同等です。ただし、値は失われません。それはタイプの一部です!int m[][N]MN

したがって、最初の形式では次のことが許容/誤っています。

void f(int arr[M][N]);

int a[M][N];
int b[2*M][N];
int c[M][N + 1];

f(a);   // OK
f(b);   // OK; slowest extent is forgotten in the decay
//f(c); // Error! 'c' is not an array of {array of N ints}.

2番目の形式の場合、意味はかなり異なります。

void g(int **p);

int a;
int * pa = &a;

g(&pa);          // fine, pointer to 'pa'

int arr[M][N];

// g(arr);  // Error, makes no sense

式は、整数arrの配列の配列の最初の要素へのポインタを指定します。Nつまり、その型はint (*)[N]です。逆参照すると、整数へのポインタではなくN、整数の配列が得られます。

arr式をポインタへのポインタに変換する方法はありません。

int ** fool = (int**)arr;

次に、ポインタではなく、最初の配列( )*foolの最初の要素を指します。したがって、値はポインタではないため、値をさらに逆参照することはできません。arr[0]int

2次元配列をダブルポインターとして渡す唯一の正しい方法は、中間ヘルパー配列を作成することです。

int * helper[M];   // array of pointers

for (size_t i = 0; i != M; ++i)
{
    helper[i] = arr[i]; // implicit decay
}

g(helper);  // or "g(&helper[0])"
于 2012-09-08T11:29:15.733 に答える