目录
一. 结构体内存对齐
1.练习题
//练习1
struct S1
{
char c1;
int i;
char c2;
};
printf("%d\n", sizeof(struct S1)); //12
//练习2
struct S2
{
char c1;
char c2;
int i;
};
printf("%d\n", sizeof(struct S2)); //8
//练习3
struct S3
{
double d;
char c;
int i;
};
printf("%d\n", sizeof(struct S3)); //16
//练习4-结构体嵌套问题
struct S4
{
char c1;
struct S3 s3;
double d;
};
printf("%d\n", sizeof(struct S4)); //32
2. 如何计算?掌握结构体对齐规则:
3.为什么存在内存对齐 ?
大部分的参考资料都是如是说的:
1. 平台原因 ( 移植原因 ) :
不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。 //比如只在内存地址为4的倍数处读取
2. 性能原因 :
数据结构 ( 尤其是栈 ) 应该尽可能地在自然边界上对齐。 原因在于,为了访问未对齐的内存,处理器
需要作两次内存访问;而对齐的内存访问仅需要一次访问。
总体来说:
结构体的内存对齐是拿 空间 来换取 时间 的做法
4.修改默认对齐数
之前我们见过了 #pragma 这个预处理指令,这里我们再次使用,可以改变我们的默认对齐数
#include <stdio.h>
#pragma pack(8)//设置默认对齐数为8
struct S1
{
char c1;
int i;
char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
#pragma pack(1)//设置默认对齐数为1
struct S2
{
char c1;
int i;
char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
int main()
{
//输出的结果是什么?
printf("%d\n", sizeof(struct S1)); //12
printf("%d\n", sizeof(struct S2)); //6
return 0;
}
结论:
结构在对齐方式不合适的时候,我么可以自己更改默认对齐数。 //最好设置为2^n,便于读取内存
二.位段
1.什么是位段
2.位段的内存分配
3.位段的跨平台问题
三.枚举
1.枚举的类定义
2.枚举的优点
四.联合体(共用体)
1.联合体类型定义
联合也是一种特殊的自定义类型 这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以 联合也叫共用体)
2.联合体大小计算