我们知道,在传递数组作为函数参数时,只有第一个维度的大小可以为空,其他的必须指定。
void my_function(int arr[5][10][15]); // OKAY!
void my_function(int arr[][10][15]); // OKAY!
void my_function(int arr[][][15]); // WRONG!!!
void my_function(int arr[][][]); // WRONG!!!
这背后的逻辑是什么?谁能解释一下主要原因?
最佳答案
将数组传递给函数是一种错觉:当您使用数组时,数组会立即衰减为指针。也就是说,在这个例子中:
int foo[10];
foo[1];
这是编译器解释的方式,在 foo[1]
中,foo
首先被转换为指向 foo
的元素 0 的指针>,然后下标就和*(pointer_to_foo + 1)
一样了。
但是,这仅适用于数组的第一维。假设这样:
int foo[5][5];
这会将 25 个整数元素连续放入内存中。它和int** foo
不一样,不能转换成int** foo
,因为int** foo
代表了一些数指向一些指针的指针,它们在内存中不必是连续的。
虽然使用数组类型作为函数参数是合法的,但编译器构建它的方式与指定指向数组元素类型的指针相同:
int foo(int bar[10]); // identical to `int foo(int* bar)`
但是如果你传递一个多维数组会发生什么?
int foo(int bar[5][5]); // identical to what?
只有数组的第一维可以衰减。此处 int foo
的等效签名为:
int foo(int (*bar)[5]); // identical to `int foo(int bar[5][5])`
其中 int (*bar)[5]
是指向 5 个整数数组的指针。堆叠更多维度不会改变想法,只有第一个维度会衰减,其他维度需要具有已知大小。
换句话说,您可以跳过第一个维度,因为编译器不关心它的大小,因为它会立即衰减。但是,后续维度不会在调用点衰减,因此您需要知道它们的大小。
关于c - 将多维数组作为函数参数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52120700/