C语言中,在有些结构体里面,会出现一个“0长度数组”的定义,例如:
typedef struct tag_test
{
int a;
int buf_len;
char p[0];
}test_s;
从对数组的定义上,上面的结构基本等同于如下的结构:
typedef struct tag_test1
{
int a;
int buf_len;
char *p;
}test1_s;
我们都需要用malloc这样的方式为结构体中的p分配一块内存,才能使用p,那么第一种定义和第二种定义相比有什么区别呢?
最关键的区别:第一种定义方式,p指针本身占用的地址空间不计入sizeof的空间,看下面的代码:
main()
{
printf("test sizeof is %d, %d\r\n", sizeof(test_s), sizeof(test1_s));
}
运行结果是:“test sizeof is 8, 12”,说明用0长度数组,p这个指针本身占用的4字节空间不计算在sizeof中。
这样的特点会使得“变长空间”非常容易处理,考虑如下一个编程的逻辑,我们需要存放一个变化的数据块,分别采用test_s和test1_s两种结构来实现,就会发现0长度数组的好处。
当采用test_s的结构获得“变长空间的总长度的时候”,需采用如下的方式获得:
buf_size = sizeof(test_s) + test_s.buf_len;
而采用test1_s的结构则需要如下的方式:
buf_size = sizeof(test_s) + test_s.buf_len - sizeof(char*); //----多了一个sizeof(char*),让人很不爽。。。
最后介绍一下,0长度数组是一个“非标”的C语言定义方式,在C的标准化C99中,定义了“不完整数组”,和0长度数组具有一个意义。例如:
typedef struct tag_test2
{
int a;
int buf_len;
char p[];
}test2_s;
sizeof(test2_s)的长度也是4。
但是,我比较喜欢使用0长度数组,因为这个0和sizeof的使用上非常形象。但是在VC 2005中,0长度数据会有一个warnning。
http://bingo75.blog.163.com/blog/static/191254006201162525429162/