通过阅读这篇文章,你将会知道以下4点:

  1. 柔性数组是什么
  2. 柔性数组怎么声明
  3. 柔性数组如何使用
  4. 为什么不用指针

一、柔性数组是什么

柔性数组其实是结构中的一个结构成员,它只能在结构中使用。

它的英文名为Flexible Array,也就是灵活的数组。

怎么体现灵活呢?

柔性数组在一开始,是不被分配空间的。直到你使用的时候,你想让它变多大,它就变多大。

而且,如果使用过程中,空间又不够了,你可以再次给它增加空间。

这就是柔性数组。

二、柔性数组怎么声明

它虽然本质上是一个结构成员,但相对与其他成员来说,它的使用略有条件:

  1. 必须为结构成员列表中的最后一位
  2. 前面必须有其他元素

现在我们声明一个柔性数组

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;
}

运行结果:

【柔性数组】的使用与特性_结构体_02

我们可以看到,通过使用我们自己分配内存的柔性数组,确实存放与打印出来了0~9

到这,其实柔性数组已经讲完了。

但还有一点,我们为什么要用它?因为如果我们把柔性数组arr[]声明成指针,然后利用指针来分配空间,同样可以开辟一个动态空间,达到一样的效果。

四、为什么不用指针

原因其实很简单:使用柔性数组,可以给结构体内的数据分配一个连续的内存。

  • 在含有柔性数组的结构中,数组的位置就是内容本身。
  • 而在含有指针的结构中,指针的位置是内容的地址。