C为什么可以用可变大小的二维数组(但是固定列)声明一个函数

时间:2017-11-02 15:04:08

标签: c arrays multidimensional-array

我知道在C语言中,不允许声明大小未知的2D数组。例如,如果我声明#define DIM 10 void func(int array[][DIM]){ //...someting } int main(int argc, char const *argv[]) { int array[DIM][DIM]; func(array); return 0; } 它将无法编译。我的问题是为什么在将“数组”声明为函数参数时进行编译。例如:

synthesisDocument.AddHyperlink("Link",new Uri("file:///path/to/doc/file.doc#MY_BOOKMARK"));
synthesisDocument.Paragraphs[0].InsertHyperl‌​ink(h)

2 个答案:

答案 0 :(得分:1)

来自thread on RStudio community

§6.7.6.3函数声明符(包括原型),第7页:

  

参数声明为'' type ''的数组应调整为''限定指针    type '',其中类型限定符(如果有)是在]void func(int array[][DIM]){ 内指定的类型限定符。   数组类型推导。 [...]

所以,以下内容:

void func(int (*array)[DIM]){
调整发生后

实际上就是这个:

split(src,BGRChannels); // split the BGR channesl
BGRChannels[1]=Mat::zeros(src.rows,src.cols,CV_8UC1);// removing Green channel
merge(BGRChannels,3,src); // pack the image 

这通常称为数组衰减为指针。由于只传递指针,编译器不需要知道整个数组的大小。但类型信息必须包括数组元素的大小(在本例中为第二维),以便索引和指针算术可以正常工作。

另一方面,当你定义一个数组时,必须知道整个大小(希望)明显的原因:编译器必须为它保留存储空间。

答案 1 :(得分:0)

功能参数是一种特殊情况。无论何时将数组声明为函数参数列表的一部分,它都会被调整为"由编译器指向第一个元素的指针。因此,如果您将函数声明为:

void func (int x[5])

然后编译器在编译时将其静默调整为:

void func (int* x)

这种语言功能可以将数组传递给函数,而无需在堆栈上复制整个数组,这样会很慢并占用大量内存。

现在,此调整仅适用于一个间接层。当您使用2D数组作为函数的一部分时,您将获得指向第一个元素的指针。 2D阵列的第一个元素是1D阵列。因此,在您的情况int (*array)[DIM]中,您将获得数组指针

由于从数组到指针的这种调整总是发生,所以最左边的维度具有什么大小并不重要,因为编译器无论如何都会将它转换为指针。这就是为什么你可以输入int array[][DIM]作为函数参数而不是其他任何地方。

您是否会在函数参数列表中键入int array[][],然后您会收到编译器错误,因为编译器会将此调整为不完整类型的数组指针:int (*)[]