C语言中的字节对齐和对程序的影响
- 字节对齐的概念
- 字节对齐对程序的影响
- #pragma指令设置 字节对齐
- 编译器对字节对齐的原则
- 字节对齐的编程设置
- 位段定义
字节对齐的概念:
现代计算机中内存空间都是按照byte来划分的,从理论上来讲,似乎对任何类型的变量的访问可以从任何地址开始,但是实际情况是在访问特定类型变量的时候经常在特定的内存地址访问(牺牲内存空间来换取读取的效率);
定义:
各种类型的数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是字节对齐(硬件平台其实已经处理好了);
原因和作用:
各种硬件平台对存储空间的处理上有很大不同;
利用字节对齐可以提高存取效率;
字节对齐对程序的影响
字节对齐对程序的影响:
字节对齐事例:(假设在32为系统中)
struct A{
int a ; //--->实际4个字节
char b; //--->实际1个字节-->字节对其后2个字节
short c;//--->实际2个字节
};
sizeof(struct A);//出现的是8个字节,就是根据字节对齐来分配的
struct B{
char b; //-->实际1个字节-->字节对其后4个字节
int a; //-->实际4个字节
short c; //-->实际2个字节-->字节对其后4个字节
};
sizeof(B); //为12个字节,
向后面最大的字节靠拢,保证一个读取周期能够完整读完一个或这多个完整的值
#pragma指令设置字节对齐
/*按两个字节对齐*/
#pragma pack(2) //申请字节对其方式
struct c{
char b;
int a;
short c;
};
#pragma pack() //取消对齐方式
sizeof(struct c);//8个字节
//--------------
/*按照1个字节来对齐*/
#pragma pack(1)
struct D{
char b;
int a;
short c;
};
#pragma pack();
sizeof(struct D);//输出为7
编译器对字节对齐原则:
数据类型自身的对齐
char类型数据,其自身对齐值为1
short类型为2
int float double类型为其自身对齐数值为4
结构体自身对齐数值:齐成员中自身对其值最大的那个数值
通过#pragma来指定对其数值#pragma pack(value);指定字节对齐
数据成员,结构体的有效对齐值,:自身对齐值和指定对其数值中小的那个
重要概念:
有效对齐值N :存放起始地址%N = 0;
对齐值圆整:结构体成员变量占用总长度需要对 结构体有效对齐值的整数倍;
字节对齐的编程设置
空间换取时间:
结构体中的成员按照类型的大小从小到大进行定义,或者从大到小这样去定义,避免大小不一混乱排列
位段定义
位段的概念:
在计算机中去存储的时候一般以字节为单位,实际上,有时存储一个信息不必要用一个或者多个字节,例如”真”和”假”用0或者1来表示,只需1位
在计算机用于过程控制,参数检测,或者数据通信领域时,控制信息往往只战一个字节中的一个或者几个二进制位,常常一个字节中放几个信息;
C语言中允许在一个结构体中以位为单位来制定成员所占内存的长度,这种以位为单位的成员称为”位断”或者称为”位域(bit field)”,利用未断能够用较少的位数>存储数据,节约空间又方便操作,在特定行业中去使用
位段的定义语法:
类型说明符 [位段名]:位长
位段名可选,位长表示该位段所占的二进制位数,不能超过该类型说明符的上限
位段成员的类型说明符号必须以int ,signed , unsigned int
无名的位段是不可以访问的,但会占空间爱你
不可以对位段进行去地址操作
事例:
struct node
{
unsigned int a:4; // 位段占4位
unsigned int :0; //无名位段占0位
unsigned int b:4; //位段b占4位
int c:32; //位段c占32位
int :6; //无名位段占6位
}