结构体的大小计算规则

一、结构体内存实际对齐单位(自定义)计算
(1) CPU周期
WIN (win32/x64) vs qt 默认8字节对齐
Linux 32位 默认4字节对齐,64位默认8字节对齐
(2) 结构体最大成员(基本数据类型变量(包括嵌套的内部结构体中的基本数据类型变量))
(3) 预编译指令#pragma pack(n)手动设置 n–只能填1 2 4 8 16
上面三者取最小的 , 就是实际对齐单位(这里的“实际对齐单位”是我为了方便区分定义的)
二、除结构体的第一个成员外,其他所有的成员的地址相对于结构体地址(即它首个成员的地址)的偏移量必须为实际对齐单位或自身大小的整数倍(取两者中小的那个)

三、结构体的整体大小必须为实际对齐单位的整数倍。

四、综上三点原则, 在计算时可以按照:
对齐原则:每一成员的结束偏移量需对齐为后一成员类型自身大小或实际对齐单位的整数倍(取两者中小的那个)
补齐原则:最终大小补齐为实际对齐单位的倍数
注意:嵌套结构体计算不管嵌套多少层,都从内部往外计算,将内部结构体看成一个整体对象计算其字节大小后再参与父结构体计算,有一点是父结构体的实际对齐单位计算要包括子结构体的基本数据类型大小,但是子结构体实际对齐单位计算不需要父结构体基本数据类型参数参与,另外计算子结构体上面变量相对该结构体整体偏移量时要以子结构体中实际对齐单位为准,计算完后偏移量加上子结构体大小做为子结构体下面变量的偏移量的计算基础
例如:
#pragma pack(16)
struct test {
char ch;
int j;

struct s {
	char ch1;
	 double i;
}a;
char f;

};
#pragma pack
大小:32
#pragma pack(16)
struct test {
char ch;
int j;

struct s {
	char ch1;
	 char i;
}a;
char f;

};
#pragma pack
大小:12
#pragma pack(8)
struct s4{
char ch;
char i;
struct s{
char ch1;
double j;
}sub;
char f;
};
#pragma pack
大小:32
五、成员包含联合体的结构体
#pragma pack(16)
struct test {
char ch;
int j;

struct s {
	char ch1;
	char i;
}a;
union MyUnion
{
	char ch1;
	int i;
}b;
char f;

};
#pragma pack
大小:20
联合体大小就是成员中最大类型的大小4
六、一道微软的笔记题
#include “stdafx.h”
#include <stdio.h>
#pragma pack(8)

struct S1
{
short a;
long b;
};

struct S2
{
char c;
struct S1 d;
double e;
};

#pragma pack()
int main()
{
struct S2 s2;
printf("%d\n", sizeof(struct S1));
printf("%d\n", sizeof(struct S2));
printf("%d\n", (int)&(s2.d) - (int)&(s2.c));
return 0;
}
结果:
8
24
4

#include “stdafx.h”
#include <stdio.h>
#pragma pack(4)

struct S1
{
short a;
long b;
};

struct S2
{
char c;
struct S1 d;
double e;
};

#pragma pack()
int main()
{
struct S2 s2;
printf("%d\n", sizeof(struct S1));
printf("%d\n", sizeof(struct S2));
printf("%d\n", (int)&(s2.d) - (int)&(s2.c));
return 0;
}
结果:
8
20
4

#include “stdafx.h”
#include <stdio.h>
#pragma pack(2)

struct S1
{
short a;
long b;
};

struct S2
{
char c;
struct S1 d;
double e;
};

#pragma pack()
int main()
{
struct S2 s2;
printf("%d\n", sizeof(struct S1));
printf("%d\n", sizeof(struct S2));
printf("%d\n", (int)&(s2.d) - (int)&(s2.c));
return 0;
}
结果:
6
16
2

#include “stdafx.h”
#include <stdio.h>
#pragma pack(1)

struct S1
{
short a;
long b;
};

struct S2
{
char c;
struct S1 d;
double e;
};

#pragma pack()
int main()
{
struct S2 s2;
printf("%d\n", sizeof(struct S1));
printf("%d\n", sizeof(struct S2));
printf("%d\n", (int)&(s2.d) - (int)&(s2.c));
return 0;
}
结果:
6
15
1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值