结构体对齐

目录

成员均为内置类型的结构体

嵌套结构体

修改默认对齐数


成员均为内置类型的结构体

先分析一段代码

#include<stdio.h>
struct A
{
	char c;
    int a;
};

struct B
{
	char a;
	char b;
	char c;
	int d;
};

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

那结构体B是不是比结构体A更大呢?(毕竟B里面的成员更多啊)

运行结果:

很可惜不是的,两者一样大!可是B里面明明比A多了两个char类型啊!这就要谈到结构体对齐了

规则: (3条)

  1. 结构体的第⼀个成员打头,从0位置开始对齐。就比如上述结构体A,第一个成员是char类型
  2. 其他成员要对齐到对齐数的整数倍。对齐数=编译器默认对齐数该变量大小较小者。比如结构体A的第二个变量,是int类型,大小是4字节,我用的VS2022默认对齐数是8,取两者中的较小者就是4,所以结构体A的第二个变量应当对齐至4的整数倍。
  3. 结构体的总大小为最大对齐数的整数倍。(结构体每个成员都有各自的对齐数,取里面最大的那个)。比如结构体A两个成员:char类型占1字节,编译器默认对其数是8,所以char对齐数是1,同理int对齐数是4,取其中的最大值4,所以结构体A的大小应当是4的整数倍。

          

0~7总共有8字节,刚好是4的倍数,所以struct A的大小就是8

那我们再来练习一道

struct C
{
	int a;
	double b;
	char c;
};

1、成员a:从0对齐,占4字节。

2、成员b:大小是8字节,编译器默认对齐数是8,所以b的对齐数是8,从8的整数倍开始对齐

中间4~7是浪费掉的空间

3、成员c:大小是1字节,编译器默认对齐数是8,所以c的对齐数是1,从1的整数倍开始对齐

4、三个成员中对齐数最大的是b,对齐数是8,所以struct C的大小应该是8的倍数,0~16总共是17个字节,不是8的倍数,那就要继续浪费空间,开够24个就可以了,刚好是8的3倍。

所以struct C所占的空间是24字节。

嵌套结构体

下面再来分析一段代码

struct A
{
    int* p;
    int a;
};

struct B
{
    struct A aa;
    int c;
};

struct C
{
    int* p;
    int a;
    int c;
};

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

读者可以先计算一下struct A的大小 (注意64位下指针变量占8字节,32位下占4字节)。 结构体B跟C的大小一样吗?

运行结果(64位,编译器默认对齐数是8)

struct A对齐方式:

嵌套结构体对齐数是自己成员中的最大对齐数。比如struct A中的成员最大对齐数是8,所以struct A的对齐数就是8。

计算struct B可以把 struct A aa 这个成员看成:大小是16字节、对齐数是8的一个东西。

0~23总共24个字节,这样下来struct B的大小就是24字节了。

修改默认对齐数

#pragma pack(1)  //将默认对其数修改为1

#include<stdio.h>
struct A
{
    int a;
    double b;
};

int main()
{
    printf("%d\n", sizeof(struct A));    //输出:12
    return 0;
}

以上就是结构体对齐方式了!

为什么要对齐?

emmm,拿空间换时间!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值