变长数组和柔性数组
絮絮叨叨: 让人不开心的事,不去做就好
数组的变种
我们常规使用的数组大部分都是C89标准的功能,在C99标准中添加了对变长数组和零长度数组的支持。
这两种新的特性有时会给开发带来不错的效果。
变长数组
变长数组(variable-length array)并不是长度可以变化的数组。
在最开始学习C语言时,基本都强调过数组的长度是不可变的,同样这句话依然适用。
这里指的变长,是在定义数组的时候长度可变,而不是在使用数组时长度可变。
即定义数组时的数组长度可以是变量。
例如:
int cpy(int num)
{
char src[]="hello wolrd";
char *offset = strchr(src,' ');
int len = offset - src;
char dest[len];
strncpy(dest, src, len);
printf("%s\n",dest);
}
不过在使用中还是有些限制条件:
- 数组类型必须时自动存储类型; (不能定义或者声明为extern 和static)
- 变成数组不能进行初始化
零长度数组
你没看错,就是零长度为0的数组,或者也可以叫做柔性数组。
先看零长数组的用法:
struct pack{
uint32_t length;
uint32_t crc32;
char data[0]; //与 char data[]; 等价
};
在一个结构体的最后一个元素中声明一个数组,数组的大小不定义或者定义0,最后这个数组则为零长度数组。
需要明确的零长度数组只是一个声明或者标识符,而不存在一个实体(内存)与之对应。
它在结构体中, 只是代表了一个偏移量, 代表一个不可修改的地址常量,其本身并不占空间。
sizeof(struct pack)的值为8字节。
这个也是在许多面试中,和字节对齐一起,常考的一个知识点。
这种方式的声明和下面的声明有本质区别
//64位平台
struct pack2{
uint32_t length;
uint32_t crc32;
char *data;
};
sizeof(struct pack2)的值为16字节。
在struct pack2中,data是一个指针其有一个自己的内存空间。
下面是使用零长度数组构造的一个简单通信协议示例
int pack_data(char *data)
{
struct pack *p;
uint32_t pack_size;
p->len = strlen(data);
p->crc32 = crc32(data,p->len);
pack_size =sizeof(struct pack) + p->len;
malloc(pack_size);
memcpy(p->data, data, p->len);
send_pack(p, pack_size);
free(p);
return pack_size;
}
本文介绍了C99标准引入的变长数组和零长度数组特性。变长数组允许在定义时使用变量作为数组长度,但不支持初始化。零长度数组在结构体中占用0字节,常用于协议包结构定义。这些特性提供了更多灵活性,但也存在使用限制。在实际应用中,如通信协议构造,它们能有效节省内存并简化代码。
1038

被折叠的 条评论
为什么被折叠?



