结构体、位段、枚举、联合体大小的正确计算方式

文章详细介绍了C语言中结构体、位段、枚举和联合体的大小计算规则,包括对齐原则和实例分析。结构体的大小受成员对齐影响,位段不跨平台,枚举大小通常为4个字节,而联合体大小至少为其最大成员的大小。文章提供了相关例题供读者练习和理解这些概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

结构体、位段、枚举、联合体大小的计算

前言

对于结构体、位段、枚举、联合体大小的计算,这里先给出四道题目,如果你都做对了,说明你对自定义类型大小的计算没什么问题了,就没有继续看这篇文章的必要了。

注:对齐数默认为8

(一)结构体

struct s1{
	double d1;
	char c1;
	int i;
};
struct s2{
	char c2;
	struct s1 s;
	double d2;
};
printf("%d %d\n", sizeof(struct s1), 
	sizeof(struct s2));

(二)位段

struct s3{
	char a:2;
	char b:4;
	char c:5;
	char d:4;
};
struct s3 s3={0};
s3.a=10;
s3.b=12;
s3.c=3;
s3.d=4;
char *i=(char*)&s3;
printf("%d %d\n",sizeof(struct s3),*i);

()枚举

enum s4{
	RED,
	BLUE,
	GREEN=INT_MAX+1;
};
printf("%d\n",sizeof(enum s4));

()联合体

union s5{
	short s[7];
	int i;
};
printf("%d\n",sizeof(union s5));

下面直接公布答案
(一)
16 32
(二)
3 50
(三)
4
(四)
16

正文

结构体

结构体对齐原则:
1.第一个成员在结构体偏移量为0的地址处

2.其他结构体成员要对齐到对齐数的整数倍处
对齐数为编译器默认的对齐数与该结构体成员的较小值

· VS默认对齐数的值为8
· 对齐数的大小可以通过以下指令修改

#pragma pack(4)  //修改对齐数的值为4

· linux没有默认对齐数,默认对齐数就是结构体成员自身的大小

3.结构体总大小为最大对齐数(因为每个成员都有一个对齐数)的整数倍

4.嵌套的结构体对齐到自己最大对齐数的整数倍处,结构体的总大小是所有最大对齐数(包括嵌套结构体的对齐数)的整数倍

规则看上去有点多且难以理解,不过没有关系,下面通过分析一些例子,等你在返回来看时就会很容易理解了

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

struct s2
{
	short s;
	struct s1 s1;
	char c;
};

在这里插入图片描述

相信通过以上例题,你已经基本了解了结构体大小的计算
这里需要注意的是,对数组类对齐数要取数组的成员(可以看作数组类型大小)与默认值的较小者,如结构体中int arr[7]这个成员的对齐数是4

位段

位段的声明与结构体类似,但有两点不同:
1.位段的结构体成员必须是整型家族
2.位段成员后面有一个冒号和数字(代表比特位)

这里需要注意的是位段是不跨平台的,不同平台对位段的处理不同,我这里使用的是VS2022

位段大小计算原则:
1.当前一个成员还有剩余没有使用的比特位时,如果可以容下下一个成员,则直接使用上个成员未使用的比特位,否则直接使用下一个完整的字节
2.其余规则与结构体类似,也有对齐数

直接看例题就行了

struct s3
{
	char c1 : 2;
	char c2 : 4;
	char c3 : 5;
	int i;
}s3;

s3.c1=1;
s3.c2=24;
char *c=(char*)&s3;
printf("%d",sizeof(s3));
printf("%d",*c);

![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/5e195fe7394321ec9b6546d88621074b.png

枚举

枚举变量的大小,实质是常数所占内存空间的大小(常数为int类型,当前主流的编译器中一般是32位机器和64位机器中int型都是4个字节),枚举类型所占内存大小一般就是4个字节

enum s4 {
	GREEN = 6,
	RED,
	BLACK
};
printf("%d",sizeof(enum s4));

这个直接就是4了

联合体

联合体大小计算为:

  1. 选取占用字节最大的成员
  2. 联合体大小为对齐数的整数倍
union s5
{
	char c[5];
	int i;
};

union s6
{
	char c[5];
	short i;
};
printf("%d %d\n",sizeof(s5),sizeof(s6));

在这里插入图片描述
打印:8 6

结语

相信通过上面的例题,你自己也可以算出答案。如果本文写得有什么不对的地方,恳请指正。最后,如果你觉得本文对你有帮助,不要忘记点赞收藏加关注哦!

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值