在C语言中,如果不限制第二个维度,就不可能将2D数组声明为参数,而第一个维度可能没有边界。 我想知道编译器如何跟踪第一个维度的长度,以及为什么它在后续维度上不一样?
由于无法编译以下代码:
int func(int array[][]) {
return 0;
}
会产生
error: declaration of ‘array’ as multidimensional array must have bounds for all dimensions except the first
答案 0 :(得分:2)
通常,编译器不会跟踪数组参数/参数的第一维。 (如果需要,这是对C标准要求的扩展,可能是提供边界检查的功能的一部分。)实际上,不可能将数组作为C中的参数传递,并且例程也无法声明一个数组作为参数。
当函数参数声明为数组时,根据C 2018 6.7.6.3 7,它会自动调整为指针:
将参数声明为“ 类型的数组”声明调整为“指向 type 的合格指针”,其中类型限定符(如果有)是指定的在数组类型派生的
[
和]
中……
按照C 2018 6.3.2.1 3:将数组作为函数参数给出时,它将自动转换为指向其第一个元素的指针
除非它是
sizeof
运算符或一元&
运算符的操作数,或者是用于初始化数组的字符串文字,否则表达式的类型为“ 的数组” type ”转换为类型为“指向 type 的指针”的表达式,该表达式指向数组对象的初始元素……
因此,数组永远不会作为参数传递,也不会作为参数接收。仅传递指针。
C实现从不需要数组的长度即可提供任何标准的C行为。例如,假设一个参数声明为int x[3][4]
。它会自动调整为int (*x)[4]
。然后,如果函数中的代码使用x[i][j]
,则C实现需要在内存中找到该元素。 i*4+j
个元素超出x
指向的位置。该实现需要第二维来进行计算,因为它必须增加i
个子数组才能找到元素x[i][j]
。由于它是按子数组递增的,因此需要知道子数组的大小。
但是,C实现不需要知道数组有多大。没有表达式会要求它使用数组的大小。因此,仅具有指向数组第一个元素的指针就足够了。