跳转至

零长数组

https://blog.csdn.net/gatieme/article/details/64131322

(注意 : 数组名永远都不会是指针!), 但对于这个数组的大小, 我们可以进行动态分配 注意 :如果结构体是通过calloc、malloc或 者new等动态分配方式生成,在不需要时要释放相应的空间。 优点 :比起在结构体中声明一个指针变量、再进行动态分 配的办法,这种方法效率要高。因为在访问数组内容时,不需要间接访问,避免了两次访存。 缺点 :在结构体中,数组为0的数组必须在最后声明,使 用上有一定限制。

对于编译器而言, 数组名仅仅是一个符号, 它不会占用任何空间, 它在结构体中, 只是代表了一个偏移量, 代表一个不可修改的地址常量!

ANSI C 标准规定:定义一个数组时,数组的长度必须是一个常数,即数组的长度在编译的时候是确定的

C99 新标准规定:可以定义一个变长数组。 但必须是运行时才能确定的,结构体中必须是常量

int len;
int a[len];

GNU C 可能觉得变长数组还不过瘾,再来一个实锤:支持零长度数组。这下没有其它编译器比我狠吧!

零长度数组有一个奇特的地方,就是它不占用内存存储空间

零长度数组一般单独使用的机会很少,它常常作为结构体的一个成员,构成一个变长结构体

由于它是结构体的一个成员,使用的时候提供了一个便利

struct buffer{
    int len;
    int a[0];
};
int main(void)
{
    struct buffer *buf;
    buf = (struct buffer *)malloc(sizeof(struct buffer) + 20);

    buf->len = 20;
    strcpy(buf->a, "hello world!\n");

    puts(buf->a);

    free(buf);
    return 0;
}

为什么不使用指针来代替零长度数组?

数组名在作为函数参数进行参数传递时,就相当于是一个指针。

但,数组名 != 指针

数组名用来表征一块连续内存存储空间的地址

而指针是一个变量,编译器要给它单独再分配一个内存空间,用来存放它指向的变量的地址

"菜刀有时候可以当武器用,但是你不能说菜刀就是武器"

所以,指针作为结构体成员时,它占用的内存空间是固定的,而零长度数组不占用内存空间