C语言内存地址对齐和位域

#pragma pack(8)
int main()
{
	struct data
	{
		int dog;			
		double cat;
		int cow;
	} too;
printf("%d\n", sizeof(struct data));
return 0;
}

首先

#pragma pack(8)

代表该文件强制执行8位对齐,可以看出总共占用了24个内存(字节Byte)大小

dogdogdogdognullnullnullnull
catcatcatcatcatcatcatcat
cowcowcowcownullnullnullnull

#pragma pack(4)

代表该文件强制执行4位对齐,可以看出总共占用了16个内存(字节Byte)大小

dogdogdogdog
catcatcatcat
catcatcatcat
cowcowcowcow

若是不加#pragma pack(4)则会以字节最长的类型来确定位数,该结构体最长的是double,8位。

其次

#pragma pack(8)
int main()
{
	struct data
	{
		int dog;			
		int cat;
		int cow;
	} too;
printf("%d\n", sizeof(struct data));
return 0;
}
dogdogdogdog
catcatcatcat
cowcowcowcow

此时虽然定义了#pragma pack(8),但是该结构体最大的字节类型是int,所以实际是4字节对齐,最终结果是12(字节Byte).

int main()
{
	struct data
	{
		char a;			
		short b;
		int c;
		char d;
		long long e;
	} too;
printf("%d\n", sizeof(struct data));
return 0;
}

注意:该表格第一列的数据为序号,并非有效数据

01234567
anullbbcccc
dnullnullnullnullnullnullnull
eeeeeeee

该结构体内存分布如下,

因为有long long 类型,所以是8字节对齐;

蓝色的null,说明每个类型的首位地址都是以该类型字节的倍数来定的;

也就是,char 是以1的倍数;short是2的倍数;int是以4的倍数;long long 是以8的倍数,来作为首位地址。

因此short b 要从如图所示位置,作为起始点;long long e 同样道理 ,总共需要24个内存(字节Byte)大小;

位域

定义等见百科

struct MyStruct
{
    unsigned int a : 31;
    unsigned int b : 2;
    unsigned int c : 31;
}s1;
struct MyStruct
{
    unsigned int a : 30;
    unsigned int b : 2;
    unsigned int c : 31;
}s2;
int main()
{
	printf("s1 = %d\n", sizeof(s1));//12
	printf("s2 = %d\n", sizeof(s2));//8
	return 0;
}

注意在C语言中一个int占4个字节,每个字节是8bit,总共就是32位,
在上面的示例中结构体s1中a是31位,b是2位,相加以后超过了32,
所以b需要占用下一块内存空间,b和c之间同样的关系,
最终需要3个int,结果为12。
而在s2中,a+b为32,刚好等于一个int,故可以共用一个int,
最终需要2个int,结果为8

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值