struct的内存大小计算

发布时间 2023-07-25 15:47:53作者: 小蠕虫

#include<stddef.h>//引用宏的头文件

//struct
//{
// char a;
// int b;
//
//}x;//匿名创建结构体,后面必须直接创建一个全局结构体变量
//struct
//{
// char a;
// int b;
//}*p;//匿名创建结构体指针,两个声明是不同的类型
//
////结构体的自引用
//struct Node
//{
// int date;//数据域
// struct Node* next;//存放下一个节点的地址 指针域
//};
//typedef struct Node
//{
// int date;//数据域
// struct Node* next;//存放下一个节点的地址 指针域
//}NODE;//结构体重命名,不能省略结构体标签(不能匿名)

//结构体内存对齐
// 1,结构体第一个成员在与结构体变量偏移量为0的地址处(s1) 起点
// 2,其他成员对齐到某个对齐数的整数倍处 起点往后移对齐数整数倍的字节个数 的地址处
// 对齐数 = 编译器默认的一个对齐数与该成员大小的较小值 vs默认对齐是8
// 3,结构体总大小为最大对齐数(结构体成员的最大对齐数)的整数倍 不够倍数 补够倍数
// 4,如果嵌套了结构体,嵌套的结构体对齐到自己最大对齐数的整数倍处,存放嵌套结构体大小个字节
// 这个结构体的整体大小是所有做大对齐数(含嵌套结构体的对齐数)的整数倍。
// 设计的时候,占用空间小的成员变量集中在一起,可以节省空间
//


struct S1
{
char a;
double b;
char c;
};
struct S2
{
char a;
char c;
double b;
};
struct S3
{
char a;
struct S2 s2;
double b;
};
#pragma pack(4)//设置默认对齐数是4
struct S4
{
char a;
double b;
};
#pragma pack()//取消设置默认对齐数
int main()
{
struct S1 s1 = { 0 };
printf("%zd\n", sizeof(s1));//24
struct S2 s2 = { 0 };
printf("%zd\n", sizeof(s2));//16
struct S3 s3 = { 0 };
printf("%zd\n", sizeof(s3));//32
//求偏移量
printf("%d\n", offsetof(struct S3, a));//传的是结构体名和结构体成员名
printf("%d\n", offsetof(struct S3, s2));//传的是结构体名和结构体成员名
printf("%d\n", offsetof(struct S3, b));//传的是结构体名和结构体成员名

struct S4 s4 = { 0 };
printf("%zd\n", sizeof(s4));
return 0;
}