a) 小端模式Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
b)大端模式 Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
1)大端小端只和数据存储有关
2)大小端只是数据在地址中的存储顺序,这个并不涉及存储单元内部
大小端存储和读取时,我们必须知道数据大小,也就是为什么我们在使用一个数据或者定义一个参数时,必须定义它的数据类型(占用了几个储存单元/几个字节)。
存储时:
1)先按照数据类型开辟一个空间。int a;4字节|——|——|——|——|
2)数据定义。a=0x123456;
3)数据分割成存储单元(字节)。0x12——0x34——0x56
4)不用考虑谁先放谁后放,我们要按顺序放,先放0x12,再放0x34……
5)大端存储方式,先往低地址放,|0x12|0x34|0x56|——|
小端存储方式,先往高地址放,|——|0x56|0x34|0x12|
读取时:
1)大端依次读出,小端倒叙读出。读取时,字节内部是一个整体不受倒叙影响。
2)读取后,就和之前未存储时顺序一致了,也就是数没发生变化。
小端模式优点:
1.内存的低地址处存放低字节,所以在强制转换数据时不需要调整字节的内容(注解:比如把int的4字节强制转换成short的2字节时,就直接把int数据存储的前两个字节给short就行,因为其前两个字节刚好就是最低的两个字节,符合转换逻辑);
2.CPU做数值运算时从内存中依顺序依次从低位到高位取数据进行运算,直到最后刷新最高位的符号位,这样的运算方式会更高效
大端模式优点:
符号位在所表示的数据的内存的第一个字节中,便于快速判断数据的正负和大小
其各自的优点就是对方的缺点,正因为两者彼此不分伯仲,再加上一些硬件厂商的坚持,因此在多字节存储顺序上始终没有一个统一的标准
联合体union的存放顺序是所有成员都从低地址开始存放,利用该特性可以轻松地获得了CPU对内存采用Little-endian还是Big-endian模式读写
#include
using namespace std;
union A{
char a;
int b;
/*
char 占一个字节,int占四个字节
所以联合体的大小为四个字节,且a b公用一块内存
当对b赋值为1时,则b=0x00 00 00 01; ====》数据从高到低 地址从低到高
当为大端模式时:读取a得到的值为0; ====》低位地址高位数据
当为小端模式时:读取a得到的值为1; ====》低位地址低位数据
*/
};
int main(){
A U;
U.b=1;
if(U.a){
cout<<"小端模式"<<endl;
}
else{
cout<<"大端模式"<<endl;
}
return 0;
}
计算机系统中内存是以字节为单位进行编址的,每个地址单元都唯一的对应着1个字节(8 bit)。这可以应对char类型数据的存储要求,因为char类型长度刚好是1个字节,但是有些类型的长度是超过1个字节的(字符串虽然是多字节的,但它本质是由一个个char类型组成的类似数组的结构而已),比如C/C++中,short类型一般是2个字节,int类型一般4个字节等。
因此这里就存在着一个如何安排多个字节数据中各字节存放顺序的问题。正是因为不同的安排顺序导致了大端存储模式和小端存储模式的存在。
芯片字节序: 大端,符合阅读习惯;
网元字节序: 小端,ARM大部分是小端;
网络字节序: 大端,规定。