これらの関数プロトタイプが同等ではないのはなぜですか?
void print_matrix(char *name, int SX, int SY, int m[SX][SY])
void print_matrix(char *name, int SX, int SY, int **m)
これらの関数プロトタイプが同等ではないのはなぜですか?
void print_matrix(char *name, int SX, int SY, int m[SX][SY])
void print_matrix(char *name, int SX, int SY, int **m)
2つの関数の引数は同じ方法で、つまりを介して使用できますが、m[i][j]
まったく異なります。
int m[M][N]
intの配列のM
配列です。N
int **m
intへのポインタへのポインタです。
配列を関数の引数として渡すことはできないため、「型のK
要素の配列」は、配列の最初の要素を指すT
「pointer-to-」に減衰します。したがって、値が失われるため、関数の引数のT
ように最初の形式を記述することは許容され、同等です。ただし、値は失われません。それはタイプの一部です!int m[][N]
M
N
したがって、最初の形式では次のことが許容/誤っています。
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])"