通过阅读这篇文章,你将会知道以下4点:
- 柔性数组是什么
- 柔性数组怎么声明
- 柔性数组如何使用
- 为什么不用指针
一、柔性数组是什么
柔性数组其实是结构中的一个结构成员,它只能在结构中使用。
它的英文名为Flexible Array,也就是灵活的数组。
怎么体现灵活呢?
柔性数组在一开始,是不被分配空间的。直到你使用的时候,你想让它变多大,它就变多大。
而且,如果使用过程中,空间又不够了,你可以再次给它增加空间。
这就是柔性数组。
二、柔性数组怎么声明
它虽然本质上是一个结构成员,但相对与其他成员来说,它的使用略有条件:
- 必须为结构成员列表中的最后一位
- 前面必须有其他元素
现在我们声明一个柔性数组
struct A
{
int a;
int arr[];//数组大小直接为空,此时arr即是一个柔性数组
};
上面的代码即创建了一个带有柔性数组的结构。
我们刚刚说,柔性数组一开始是不被分配空间的,我们现在利用sizeof来看看,这个A这个结构,到底有多大:
struct A text = { 0 };//创建了一个布局为A的结构变量text
int sz = sizeof(text);//求这个结构的大小
printf("%d\n", sz);
运行结果:
可以看出来,柔性数组arr,确实没有被分配内存空间。
三、带有柔性数组的结构如何使用
既然是柔性可变,那它必然是分配在堆区的。
既然是在堆区,那就可以用malloc来使用,见下面代码:
struct A text = { 0 };
struct A* p;
struct A* tem;
//malloc结构体其他成员的大小 + 你想给柔性数组分配的大小
tem = (struct A*)malloc(sizeof(text) + 40);
if (tem == NULL)
{
return 1;
}
p = tem;//此时arr数组就被分配了40个字节的大小,可以容纳10个整型
那到底分配没有?
我们尝试去使用arr数组,如果可以使用,那么就代表柔性数组的声明与使用成功,反之亦然。
见代码(可以方便大家复制到自己的机器上尝试,此次没有放局部,而是把整个程序放了上来):
#include <stdio.h>
#include <malloc.h>
struct A
{
int a;
int arr[];
};
int main()
{
int i = 0;
struct A text = { 0 };
struct A* p;
struct A* tem;
tem = (struct A*)malloc(sizeof(text) + 40);
if (tem == NULL)
{
return 1;
}
p = tem;
//尝试向柔性数组中存放数据
for (i = 0; i < 10; i++)
{
p->arr[i] = i;
}
//尝试将柔性数组中的数据打印出来
for (i = 0; i < 10; i++)
{
printf("%d ", p->arr[i]);
}
free(p);
p = NULL;
return 0;
}
运行结果:
我们可以看到,通过使用我们自己分配内存的柔性数组,确实存放与打印出来了0~9
到这,其实柔性数组已经讲完了。
但还有一点,我们为什么要用它?因为如果我们把柔性数组arr[]声明成指针,然后利用指针来分配空间,同样可以开辟一个动态空间,达到一样的效果。
四、为什么不用指针
原因其实很简单:使用柔性数组,可以给结构体内的数据分配一个连续的内存。
- 在含有柔性数组的结构中,数组的位置就是内容本身。
- 而在含有指针的结构中,指针的位置是内容的地址。