(摘自)
在GNU C中是允许0长度数组的,它们是非常有用的,位于一个结构体的最后一个元素位置,这样的结构体作为一个变长对象的head。
-
struct line {
-
int length;
-
char contents[0];
-
};
-
-
struct line *thisline = (struct line *)
-
malloc (sizeof (struct line) + this_length);
-
thisline->length = this_length;
在ISO C90中,你必须给出至少长度为1的数组,这意味着,要么浪费空间,要么使malloc的参数变复杂。
在ISO C90中,你要使用一个可变数组成员,在语法上有一些不同:
可变数组被写成contents[],没有0
可变数组有不完整的类型,所以无法应用sizeof操作,而0长度数组的sizeof值为0
可变数组只能出现在非空struct的最后成员的位置
如果一个structure中包含一个可变数组,或者一个union包含一个structure,那么这个structure或union就不能成为一个structure成员,也不能成为一个数组元素(然而,在GCC extensions中是可以的)
3.0之前的GCC允许0长度数组被静态初始化,只要他们是可变数组。另外,可变数组也是很有帮助的,它允许访问在初始化位置之后的数据。0长度数组没有索引限制,所以不会出现“excess element in array”这样的越界warning。
GCC允许静态初始化可变数组,这和定义一个新的structure包含一个原始structure(中有可变数组)初始化是等价的。比如下面,f1 structure的声明和它在f2中声明的值一样:
-
struct f1 {
-
int x; int y[];
-
} f1 = { 1, { 2, 3, 4 } };
-
-
struct f2 {
-
struct f1 f1; int data[3];
-
} f2 = { { 1 }, { 2, 3, 4 } };
上面的方便之处在于:可以直接使用f1,而不用每次都调用f2.f1
下面是一个规则的静态数据,因为其中包含一个未知大小[]的数组
当然,这个拓展仅在顶层structure的后面有额外数据时有意义,否则会被接下来的数据覆盖这一位置。
为了避免复杂和与邻近数据初始化的混淆,除非是顶层structure,否则不建议这样使用,比如:
-
struct foo { int x; int y[]; };
-
struct bar { struct foo z; };
-
-
struct foo a = { 1, { 2, 3, 4 } }; // Valid.
-
struct bar b = { { 1, { 2, 3, 4 } } }; // Invalid.
-
struct bar c = { { 1, { } } }; // Valid.
-
struct foo d[1] = { { 1 { 2, 3, 4 } } }; // Invalid.
阅读(1841) | 评论(0) | 转发(0) |