在一些用C编写的涉及2d数组的程序中,我注意到未提及行大小,并且编译器也不会对此引发任何错误。但是当我通过提及行大小而不是列大小来尝试此操作时,编译器将引发错误。
例如:
int arr[][5]; // correct
int arr[5][]; //compiler throws error
是什么原因?
答案 0 :(得分:1)
我们可以在C语言中定义一个二维数组为:
A [][n];
其中n是一个常数
我们必须在数组中包括列数,因为这指定了每行的大小。二维数组可以看作是行的数组,一旦编译器知道数组中行的大小(由第二个方括号中的值定义,此处为n),便能够正确地确定开始位置每行。 换句话说,需要计算您实际访问的项目的相对偏移量。
我们的偏移量=(row * colwidth + col)
偏移量是由编译器使用行的大小计算的,而行的大小恰好是列的数量/列数。
答案 1 :(得分:0)
6.7.6.2数组声明符
约束
1除了可选的类型限定符和关键字static
外,[
和]
可以定界。 表达式或*
。如果它们定界表达式(指定数组的大小),则 表达式应具有整数类型。如果表达式是一个常量表达式,则应为 值大于零。 元素类型不得为不完整或函数 。可选的类型限定符和关键字static
只能出现在 具有数组类型的函数参数的声明,然后仅在最外面 数组类型派生。
...
语义学
...
4如果不存在大小,则数组类型为不完整的类型...
已添加重点。给定数组声明
T a[];
a
的类型为不完整-它是“ T
的未知大小数组”。但是,根据上述约束,T
本身必须为完整类型。如果T
是数组类型,则必须知道其大小, a R [N]
:
R a[][N]; // a is an unknown-size array of N-element arrays of R
这就是编译器接受的原因
int arr[][5];
因为,虽然我们尚不知道arr
中将有多少个元素,但我们知道每个元素将有多大(5 * sizeof (int)
)。请注意,arr
必须具有一定的大小,然后才能实际使用。相反,
int arr[5][];
说arr
是由int
的未知大小的数组组成的5元素数组。我们知道我们需要多少元素,但我们不知道这些元素将有多大。
现在,为什么进行此限制?我无法提供权威的答案,但我怀疑它与C中数组与指针操作之间的关系有关。请记住,表达式a[i]
被定义为{{ 1}}-也就是说,获取地址*(a + i)
并从该地址偏移a
个元素(不是字节!),然后取消引用结果。仅在知道元素类型的大小的情况下才有效。
应该可以对一个大小未知的N个元素进行建模,但是我怀疑这样的模型很麻烦足够,实现起来比它麻烦得多价值。