如果我只有一个元素的数组,可以说它与指针相同。 但是在内存中如何表示大小为零的数组?
当我声明变量int * table[0]
时会发生什么?
答案 0 :(得分:4)
如果我只有一个元素的数组,我们可以说它与a相同 指针
不,我们不能。数组和指针是不同的类型,它们在内部的表示方式也不同。无论数组大小如何,都是如此。现在,在某些情况下(实际上是大多数情况),数组也会衰减为指向其第一个元素的指针。
大小为0
的数组按照标准是非法的,但是某些主要的编译器(例如gcc)允许它们作为扩展名。
阅读此问题,以了解数组的内部表示与指针之间的区别:Difference between dereferencing pointer and accessing array elements
答案 1 :(得分:2)
C标准在技术上不支持零长度数组。但是,某些编译器(例如gcc)允许它们作为扩展。
它们是C99之前创建灵活数组成员的方法,如下所示:
typedef struct {
int len;
int contents[0];
} arr;
然后,您可以为数组末尾初始化所需的任意空间:
arr* a = malloc(sizeof(*a) + sizeof(a->contents) * 10); /* for a length-10 array */
a->len = 10;
答案 2 :(得分:1)
严格来说,数组的大小不允许为0。这在C standard的6.7.6.2p1节中有规定:
除了可选的类型限定符和关键字static之外,[ 和]可以分隔表达式或 *。如果它们定界表达式(指定数组的大小),则该表达式应具有整数类型。 如果表达式 是一个常量表达式,其值应大于零。 元素类型不得为不完整或函数类型。的 可选的类型限定符和关键字static将出现 仅在带有数组的函数参数声明中 类型,然后仅在最外层数组类型推导中
某些编译器确实支持此扩展,例如GCC:
在GNU C中允许声明零长度数组作为扩展。一种 零长度数组可用作结构的最后一个元素 这实际上是一个可变长度对象的标头:
struct line { int length; char contents[0]; }; struct line *thisline = (struct line *) malloc (sizeof (struct line) + this_length); thisline->length = this_length;
尽管零长度数组的大小为零,但其中的一个数组成员 这种情况可能会增加封闭类型的尺寸 尾巴填充。零长度数组成员与的偏移量 封闭结构的开头与的偏移量相同 具有一个或多个相同类型元素的数组。一个的对齐 零长度数组与其元素的对齐方式相同。