众所周知,当将数组作为函数参数传递时,只有第一维的大小可以为空,其他维必须指定。
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
首先转化为一个指向元件的0 foo
,然后下标是相同的*(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个整数的数组的指针。堆叠更多的尺寸并不会改变想法,只有第一个尺寸会衰减,而其他尺寸则需要具有已知的尺寸。
换句话说,您可以跳过第一维,因为编译器并不关心它的大小,因为它会立即衰减。但是,后续尺寸在呼叫站点不会衰减,因此您需要知道其尺寸。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句