c语言 柔性数组的使用

先说c++吧

typedef struct _node {
        int num;
	int age[];
}node;

这个就是所谓的柔性数组。结构中最后一个元素允许是未知大小的数组。(必须是最后一个,这很重要,下面解释)

可以试一下,sizeof(node)是4,若将num去掉,sizeof(node)就是1,我们知道空的struct,sizeof是1。有此可发现,柔性数组并不占有空间,这是为了动态的储存,后续可扩大空间。需要注意的是,结构中的柔性数组前面必须至少一个其他成员,柔性数组成员允许结构中包含一个大小可变的数组,sizeof返回的这种结构大小不包括柔性数组的内存。包含柔数组成员的结构用malloc函数进行内存的动态分配,且分配的内存应该大于结构的大小以适应柔性数组的预期大小。

如果改成c语言,c语言不允许空struct,而只有一个柔性数组的空结构体,sizeof是4。这个是因为编译器的规定。我用的是gcc和g++。

如果将例子中的age[]改为age[0]也是可以的,虽然意义有点不一样。

还有一点,这种变长的数组例如age[]或者说写age[0]这种,在结构体外是不允许的。我的想法是,因为struct是本身就占用空间的,分配了地址的。因此在struct里的变长数组是有一个索引的,也就是在系统中有归属。而struct外的普通数组,如果写成name[]或者name[0],那么系统不知道去哪里寻找数组,没法定义。所以不允许。换个思路,age[]这样其实就相当于声明了一个指针char* name。而这个指针没有分配空间,自然也是不行的。虽然出错的环节不一样,但我想还是可以类比下的。

然后说回前面说的,柔性数组必须是结构中最后的元素。这个是因为,如果申请一定长度的空间,比如说这个例子,有10个age。

node* tmp = (node*)malloc(sizeof(node) + 10*sizeof(int));

可以发现,是在malloc时候申请了10个int的大小,这个空间储存储存10个age。这10个地址和node本身是malloc一起申请的,所以是连着的。因此,如果不是最后面的,空间就混乱了,放在最后面才能处理嘛。

当然那些就是个讨论,现在不重要,知道咋搞就行了。还是看个柔性数组的使用吧。

假设有一个小组,现在需要输入每个的名字和年龄。而这个结构体是需要复用的啊,预先声明的太大也不好,这个时候这柔性数组就有用了。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct _Info {
	char name[10];
	int age;
}Info;

typedef struct _Group {
	int num;
	int counter;
	Info staff[];
}Group;


int main() {
	int Len = 10;
	int Size = sizeof(Group) + Len * sizeof(Info);
	Group* org = (Group*)malloc(Size);
	memset(org, 0, Size);
	org->num = Len;
	for (int i = 0; i < org->num; i++) {
		org->counter++;
		org->staff[i].age = i + 1;
		strcpy(org->staff[i].name, "zhangsan");
	}

	for (int j = 0; j < org->counter; j++)
		printf("name is %s, age is %d\n", org->staff[j].name, org->staff[j].age);
	return 0;
}

我在结构体Group里多加了个counter,我是想到有这种情况可以用,就是一次建立20个Info的空间,在添加时候,counter计数发现要到20个了,这时候可以realloc一下,这就和c++ vector一样用了。

具体情况具体说吧,总归这个柔性数组还是有用的。

发布了19 篇原创文章 · 获赞 1 · 访问量 928

猜你喜欢

转载自blog.csdn.net/tjw316248269/article/details/104791911