声明数组而不指定行大小? [英] Declaring array without specifying the row size?
问题描述
a[][3]
声明如何正确,而 a[3][]
在 C 中是错误的?
How can a[][3]
declaration is right where as a[3][]
is wrong in C?
推荐答案
您可以为不完整类型的对象声明标识符.例如,考虑以下声明:
You may declare identifiers for objects of incomplete types. For example, consider this declaration:
extern int a[][3];
这告诉编译器,当使用a
时,它指的是一个由三个int
组成的数组.如果使用它,则必须在其他地方定义该数组.但是,要使用这个数组,编译器不需要知道它的大小.如果a
有起始地址x且int
是四个字节,我们可以计算元素a[i][j的地址]
以 x 开头,加上 i
三个 int
数组的大小(每个数组 3•4 字节)和j
int
的大小(每个 4 字节).所以a[i][j]
的地址是x + 3•4•i
+ 4•j
>.
This tells the compiler that when a
is used, it refers to an array of arrays of three int
. If it is used, that array must be defined somewhere else. However, to use this array, the compiler does not need to know its size. If a
has starting address x and int
is four bytes, we can calculate the address of the element a[i][j]
by starting with x, adding the size of i
arrays of three int
(3•4 bytes for each array) and the size of j
int
(4 bytes each). So the address of a[i][j]
is x + 3•4•i
+ 4•j
.
在定义这个数组的地方,不能不完整;编译器需要知道完整的大小才能知道要保留多少内存.
At the place where this array is defined, it cannot be incomplete; the compiler needs to know the complete size in order to know how much memory to reserve.
虽然可以为不完整类型的对象声明标识符,但数组元素必须具有完整类型.此规则在 C 2018 6.7.6.2 1 中说明:元素类型不得为不完整或函数类型."在上面的计算中,如果不知道子数组的大小,就无法计算a[i][j]
的地址.所以声明 a[3][]
是不允许的.
Although you can declare an identifier for an object of incomplete type, the elements of arrays must have complete type. This rule is stated in C 2018 6.7.6.2 1: "The element type shall not be an incomplete or function type." In the calculation above, we could not calculate the address of a[i][j]
if we did not know the size of the subarrays. So the declaration a[3][]
is not allowed.
注意,在定义带有初始化器的数组时,我们可以省略第一维.但是,它仍然是通过初始化器指定的;编译器检查初始值设定项并找出第一个维度必须是什么.所以,当数组被定义时,它的类型是完整的.例如,在:
Note that when defining an array with initializers, we can omit the first dimension. However, it is still specified through the initializers; the compiler examines the initializers and figures out what the first dimension must be. So, when the array is defined, its type is complete. For example, in:
int a[][3] = {
{ 0, 1, 2 },
{ 3, 4, 5 }
};
编译器会看到有两个子数组并且知道a
的类型是int [2][3]
.这对于其他维度是不允许的,因为它会造成复杂性.尽管我在上面使用了结构良好的大括号,但该语言允许省略它们,如下所示:
the compiler will see there are two subarrays and know that the type of a
is int [2][3]
. This is not allowed for the other dimensions because it creates complications. Although I have used well-structured braces above, the language permits omitting them, as in:
int a[][3] = { 0, 1, 2, 3, 4, 5 };
如果省略第一个维度之外的任何维度,那么初始化器初始化哪些元素以及它们暗示维度是什么就会产生歧义.
If any dimensions other than the first were omitted, there would be ambiguity in which initializers initialized which elements and what they implied the dimensions were.
这篇关于声明数组而不指定行大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!