C语言:柔性数组

1. 柔性数组是什么?

struct S1
{
	int num;
	double d;
	int arr[];
};

struct S2
{
	int num;
	double d;
	int arr[0];
};
 

柔性数组是个结构体中大小未知的数据成员。
S1中int arr[],S2中 arr[0],如S2含有数组元素a[0],但是不知道arr大小,所以也是一种柔性数组,以上两种形式在不同编译器下,选择不同

2. 柔性数组的大小

struct S3
{
	int num;
	int arr[];
};

int main()
{
	printf("%d\n", sizeof(struct S3));
	return 0;
}

结果:
请添加图片描述
柔性数组因为有未知大小数据成员,所以结构体中在柔性数组之前必须有如S3中固定大小num,所以结果是大小4字节,但是如果前面没有int num,整个柔性数组就不知道大小多少,为0了

3. 柔性数组使用:用malloc()灵活分配大小

· malloc的使用回忆:
先是malloc(大小),然后它将给什么变量用,给结构体s3,而这是地址,所以前面: struct S3*

(struct S3*)malloc(sizeof(struct S3) + 40);

malloc在stdlib.h包中
malloc初创建时候使用
例子:

int main()
{
	printf("%d\n", sizeof(struct S3));
	struct S3* ps = (struct S3*)malloc(sizeof(struct S3) + 40);
	ps->num = 100;
	int i = 0;
	// 给它赋值
	for (i = 0; i < 10; i++)
	{
		ps->arr[i] = i;
	}
	for (i = 0; i < 10; i++)
	{
		printf("%d", ps->arr[i]);
	}
	free(ps);
	ps = NULL;
	return 0;
}

结果:给柔性数组中赋了10个值
最后不用给它释放掉

realloc二次扩容回忆:
realloc如果申请失败会返回null,这时用旧变量接收会丢失原始值,所以一般使用新变量接收,且可以多加判断是否成功

struct S3* ptr = (struct S3*)realloc(ps, sizeof(struct S3) + 80);
	if (ptr == NULL)
	{
		perror("realloc\n");
		return 1;
	}
	else
	{
		ps = ptr;
	}
	// 继续打印
	for (i = 0; i < 20; i++)
	{
		ps->arr[i] = i;
	}
	printf("\n");
	for (i = 0; i < 20; i++)
	{
		printf("%d ", ps->arr[i]);
	}

	return 0;
}

一般申请空间完,都需要判断指针是否指向NULL

如果不使用柔性数组?

使用指针成员变量也可以实现动态改变空间大小,但是需要两次申请空间,也需要两次释放空间:
请添加图片描述
此外,用柔性数组释放空间时是连续释放,速度更快,利于减少内存碎片。

· 结构体回忆
struct A{}* Env_Alarm_
Env_Alarm是A类型的指针

位段读代码题:
请添加图片描述
创建:char:1, char:2, char:3存到第二个字节中:
p->uc1=2 0010
p->ud0=3 0011
p->ud1=4 0100
p->ud2=5 0101
对ud0、ud1、ud2依次取1、2、3个位
1、00、101,从低到高赋值
101001 =>第二个字节上:
最后输出是按16进制:
0010 1001-> 29
对齐数回忆:
对齐数是结构体中的概念,从每个成员变量类型中去看对齐数是多少,char是1,int是4,编译器是4,所以char对齐数是1,int是4,取本身大小和编译器的对齐数最小值,最终如下图,好像大小结果该为9,但是最后结构体大小结果要被最大对齐数整除,所以为12。

struct s1
{
 
    char c1;
    int i;
    char c2;
}

请添加图片描述
联合体回忆:
考虑结构体中最大的成员大小,但是它的值最终要被全部成员最大对齐数整除,所以下面是16.(1. 第一个是14,第二个是4,所以整体最终大小是16)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值