C语言结构体的内存对齐

结构体

是由一批数据组合而成的一种新的数据类型。组成结构型数据的每个数据称为结构型数据的“成员”。
结构体的声明

struct tag{
 member-list;
}variavle-list;
//例如学生结构体
struct Stu{
char name[20]; //名字
int age; //年龄
char sex[5];//性别
char id[10];//学号
};

特殊声明

//匿名结构体
struct {
int a;
int b;
float c;
}x;

结构体的自引用必须使用指针,常用于数据结构中例如链表中。

struct Node{
int data;
struct Node* next;
};

结构体内存对齐

**为什么:**由于硬件平台限制,访问内存次数正价,效率降低。
**是什么: **通过牺牲空间方案换区效率的提升。
怎么做?

  1. 第一个成员在与结构体变量偏移量为0的地址处
  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处
  3. 结构体的总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍
  4. 出现结构体嵌套结构体的情况,内部的结构体对齐到自己的最大对齐数的整数倍处,外部结构体的大小就是所有最大对齐数(含内部结构体的对齐数==结构体内部最大对齐数)的整数倍。

注:对齐数:大小为自身元素类型。与编译器无关。
对齐: 起始偏移量整除对齐数。
第一个成员变量的大小也要参与最大对齐数的比较
在这里插入图片描述

//例1
struct s1{ //
 char c1;  //   1 
 int i;    //  3+ 4   起始偏移量为1,不对齐进行扩增+3见怎么做的第2点
 char c2;  // 1      1  
};
printf("%d",sizeof(struct s1)); 
//12  总大小为最大对齐数(4)的整数倍 即  8<9<12即为12

在这里插入图片描述

//例2
struct s2{
char c1; //1
char c2; //1
int i;   // 不整除扩增2        2+4
}
printf("%d",sizeof(struct s2)); 总大小为最大对齐数的整数倍 8
//例3
struct s3{
double d; //8
char c;  //1
int i;  // 不整除扩增3   3+4
};
printf("%d",sizeof(struct s3));  //16
//例 4
struct s4{  //         对齐数
char c1;    //         1
struct s3 s;//       7 (8为s3的最大对齐数)+16(16为s3的大小)
double d;  //           8
};
printf("%d",sizeof(struct s4)); //32
struct s5{
char c1;             1
struct s3 s;//对齐数为8 不整除扩增7         7+16
char *arr[3];//对齐数为4 整除不用扩增      +12
short *b;                +4
double d;             +8
}        
printf("%d",sizeof(struct s5)); //48 48%8==0;  

总结:第一个成员变量不需要对齐从第二个成员变量开始每次计算时看当前偏移量能否整除当前成员变量的对齐数,若能,直接加上对应类型的大小,若不能,则进行扩增,扩增到最近一个能整除最大对齐数的位置。重复进行上述操作,得到的结果整除最大对齐数。若能处尽则为内存大小,若除不尽找到给结果加上最大对齐数-余数即为内存大小。
例如 得到结果为 30 最大对齐数为 8 则内存大小为32

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值