C/C++中常用char a[0]来定义一个占位符,用以指示一个内存地址。例如,柔性数组的定义:
struct Array{
int len;
int data[0];
}
结构体Array用来标识一个数组,len为其长度,数据存在data中。因为数组的长度是动态的,所以经常在程序中动态分配数组的内存:
int len = 100;
struct Array * pa = malloc( sizeof(Array) + sizeof(int) * len);
pa->len = len;
//访问数组元素
pa->data[0];
这里结构体中的data就是一个占位符,编译器不会给它分配内存。
pa->data或&pa->data表示的是len的下一个地址单元,这里是一个int。
sizeof( Array ) 与sizeof( int ) 相等都是4.
因为sizeof( pa->data ) 的值是0.
当把data当着指针使用时,有以下注意事项:
pa->data + 10 等于&pa->data + 10 * sizeof(int). 但是
&pa->data + 10 等于&pa->data + 10 * sizeof( int [0] ), 因为sizeof( int [0] ) 等于0 ,所以 &pa->data + 10 与 &pa->data的值相等!!
可以这样理解typeof( pa->data) 是int,因为C语言中数组名就是数组第一个元素的地址。
而 &pa->data是取data的地址,data的类型是 int [0], 即0长度的int数组,所以它的size为0.
在0长度的数组上,指针无论怎么移动,其仍然在原来的位置。
另外:
gcc中,可以根据需要指定结构的字节对齐方式:
typedef struct{
char * name;
int ag;
char score;
int id;
}__attribute__((packed)) Person1;
Person1是字节对齐的。
typedef struct{
char * name;
int age;
char score;
int id;
}__attribute__((aligned (4))) Person2;
Person2是4字节对齐的。注意(4)前面有个空格。