变长数组和柔性数组

变长数组和柔性数组

絮絮叨叨: 让人不开心的事,不去做就好

数组的变种

我们常规使用的数组大部分都是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,最后这个数组则为零长度数组。

需要明确的零长度数组只是一个声明或者标识符,而不存在一个实体(内存)与之对应。

它在结构体中, 只是代表了一个偏移量, 代表一个不可修改的地址常量,其本身并不占空间。

pack)```的值为8字节。
这个也是在许多面试中,和字节对齐一起,常考的一个知识点。 这种方式的声明和下面的声明有本质区别 ```c //64位平台 struct pack2{ uint32_t length; uint32_t crc32; char *data; };
pack2)```的值为16字节。
在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/变长数组和柔性数组/
作者
非典型技术宅
发布于
2022年9月4日
许可协议