变长数组和柔性数组
变长数组和柔性数组
絮絮叨叨: 让人不开心的事,不去做就好
数组的变种
我们常规使用的数组大部分都是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,最后这个数组则为零长度数组。
需要明确的零长度数组只是一个声明或者标识符,而不存在一个实体(内存)与之对应。
它在结构体中, 只是代表了一个偏移量, 代表一个不可修改的地址常量,其本身并不占空间。
这个也是在许多面试中,和字节对齐一起,常考的一个知识点。
这种方式的声明和下面的声明有本质区别
```c
//64位平台
struct pack2{
uint32_t length;
uint32_t crc32;
char *data;
};
在struct pack2中,data是一个指针其有一个自己的内存空间。
下面是使用零长度数组构造的一个简单通信协议示例
```c
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;
}
变长数组和柔性数组
https://gary-hobson.github.io/2022/09/04/变长数组和柔性数组/