结构体sizeof运算、字节对齐

求结构体sizeof运算

用sizeof求结构体变量所占的字节数,并不是简单的把各个成员的字节数相加。

在计算机存储系统中以字节为单位存储数据,不同的数据类型所占的空间不同,例如:整型数据(int)占4个字节、字符型数据(char)占1个字节、浮点型数据(float)占四个字节…
计算机为了快速的读写数据,默认情况下将数据存放在某个地址的起始位置,例如:整形数据(int)默认存储在地址能被4整除的起始位置、字符型数据(char)可以存放在任意的起始位置(被1整除)、浮点型数据(float)默认存储在地址能被4整除的起始位置。
这样的存储方式称为字节对齐。字节对齐有助于加快计算机的取数速度,减少花费的指令周期。

结构体的字节对齐的细节和具体编译器实现相关,但一般而言满足以下三个准则:

  1. 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
    2)结构体每个成员相对于结构体首地址的偏移量都是当前成员大小的整数倍,如有需要编译器会在成员之间加上填充字节;
    3)结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要,编译器会在最末一个成员之后加上填充字节。
    (注:基本类型是指char、short、int、float、double这样的内置数据类型)
    下面用几个程序来举例说明:
#include<stdio.h>
#include<stdlib.h> 

struct A{
	char c;
	int a;
};

int main(){
	A a;
	printf("A::%d\n",sizeof(a));
}

在这里插入图片描述
对于结构体A,其成员类型有char 和int两种,最宽的是int型,占四个字节。那么系统就会为A分配一个能被4整除的首地址。
分配成员地址时,A的第一个成员就是结构体A的首地址。
接下来分配int型成员时,为满足该成员的首地址能被4 整除,系统会填充三个字节来满足这个要求,使其相对A的首地址偏移量为4。
所以结构体A的字节数为 1(char) + 3(填充字节) + 4(int)= 8;内存分布如下:
在这里插入图片描述

1、数据成员顺序对求sizeof的影响
在给结构体数据成员分配空间时,是按前后顺序依次分配的。因为字节对齐的要求,数据成员的顺序也会对结构体求sizeof有影响。

#include<stdio.h>

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

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

int main(){
	A a;
	printf("A::%d\n",sizeof(a));
	B b;
	printf("B::%d\n",sizeof(b));
}

在这里插入图片描述
可以看到,调换成员顺序后,也会影响对结构体求sizeof的结果。
在这里插入图片描述
A的内存分布如上图,对最宽的double型8个字节对齐,先给int型的数据成员a分配四个字节,在给double分配时,为保证地址可以整除8,需要填充4个字节,在给b分配空间。
在这里插入图片描述
B的内存分布如上图,也是对最宽的double型8个字节对齐,先给double数据成员b分配8个字节,后给int型数据成员a和char型数据成员c分配时不需要填充字节依然满足内存字节的要求。
可见,数据成员的顺序会影响结构体成员的内存分布,合理的顺序可以节省所分配的空间。

2、结构体嵌套

#include<stdio.h>

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

int main(){
	B b;
	printf("B::%d\n",sizeof(b));
}

在这里插入图片描述
在这里插入图片描述
B的内存分布如上图,在类内的结构体变量b分配完后,嵌套的结构体同样会遵循结构体大小是最长内存整数倍的要求,b分配完成员空间后会填充三个字节满足这个要求,然后再去分配B的其他成员。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_200_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值