撤销个人网站备案,贵州省住房建设部网站,手机网站空间申请,图片滤镜网站开发大端与小端存储详尽说明 大端与小端存储详尽说明 大端与小端存储详尽说明一. 什么是字节序二. 什么是大端存储模式三. 什么是小端存储模式四. 大小端各自的特点五. 为什么会有大小端模式之分六. 为什么要注意大小端问题六. 大小端判定程序七. 大端小端的转换1#xff09;16位大…大端与小端存储详尽说明 大端与小端存储详尽说明 大端与小端存储详尽说明一. 什么是字节序二. 什么是大端存储模式三. 什么是小端存储模式四. 大小端各自的特点五. 为什么会有大小端模式之分六. 为什么要注意大小端问题六. 大小端判定程序七. 大端小端的转换116位大小端转换232位大小端转换 八. 大小端数据的存取1存储时2读取时 一. 什么是字节序
字节序也就是字节的顺序指的是多字节的数据在内存中的存放顺序。 在几乎所有的机器上多字节对象都被存储为连续的字节序列。 不同的CPU有不同的字节序类型最常见的有两种 Little-Endian将低序字节存储在起始地址低位编址也就是小端存储模式。 Big-Endian将高序字节存储在起始地址高位编址也就是下面说的大端存储模式。
二. 什么是大端存储模式
数据的低位保存在内存中的高地址中数据的高位保存在内存中的低地址中这样的存储模式有点儿类似于把数据当作字符串顺序处理地址由小向大增加而数据从高位往低位放 高字节数据存储在低地址。 16进制数据0x12345678 存储方式低地址12|34|56|78高地址 数组表示 buf[3] (0x78) – 低位 buf[2] (0x56) buf[1] (0x34) buf[0] (0x12) – 高位 记忆方法: 地址的增长顺序与值的增长顺序相反。
三. 什么是小端存储模式
数据的低位保存在内存中的低地址中数据的高位保存在内存中的高地址中这种存储模式将地址的高低和数据位权有效地结合起来高地址部分权值高低地址部分权值低和我们的逻辑方法一致。 16进制数据0x12345678 存储方式低地址78|56|34|12高地址 数组表示 buf[3] (0x12) – 高位 buf[2] (0x34) buf[1] (0x56) buf[0] (0x78) – 低位 记忆方法: 地址的增长顺序与值的增长顺序相同
四. 大小端各自的特点
小端模式 强制转换数据不需要调整字节内容1、2、4字节的存储方式一样。 大端模式 符号位的判定固定为第一个字节容易判断正负。网络传输一般使用的就是Big Endian也被称之为网络字节序或网络序。
五. 为什么会有大小端模式之分
这是因为在计算机系统中我们是以字节为单位的每个地址单元都对应着一个字节一个字节为8bit。但是在C语言中除了8bit的char之外还有16bit的short型32bit的long型要看具体的编译器另外对于位数大于8位的处理器例如16位或者32位的处理器由于寄存器宽度大于一个字节那么必然存在着一个如果将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。 我们常用的x86结构是小端模式而KEIL C51则为大端模式。很多的ARMDSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。 因此可以说大端存储或小端存储都是由系统设定的两者区别在于低地址存储的数据因此可以写程序进行判断。
六. 为什么要注意大小端问题
C/C语言编写的程序里数据存储顺序是跟编译平台所在的CPU相关的而JAVA编写的程序则唯一采用big endian方式来存储数据。试想如果你用C/C语言在x86平台下编写的程序跟别人的JAVA程序互通时会产生什么结果就拿上面的 0x12345678来说你的程序传递给别人的一个数据将指向0x12345678的指针传给了JAVA程序由于JAVA采取big endian方式存储数据很自然的它会将你的数据翻译为0x78563412。 因此在你的C程序传给JAVA程序之前有必要进行字节序的转换工作。
六. 大小端判定程序
请写一个C函数若处理器是Big_endian的则返回0如果Little_endian的则返回1。
int checkLittleEndian()
{{union w{int a;char b;} c;c.a 1;return (c.b 1);}
}联合体union的存放顺序是全部成员都从低地址开始存放解答利用该特性轻松地得到了CPU对内存采用Little-endian仍是Big-endian模式读写。
void Endianness()
{int a 0x12345678;if( *((char*)a) 0x78)cout Little Endian endl;elsecout Big Endian endl;
}这一种是通过强制类型转换的方式来判断大小端的。如果是小端的话低位字节0x78的内容应该是存放在低地址中。
七. 大端小端的转换
116位大小端转换
#define BSWAP_16(x) \ (uint_16)((((uint_16)(x) 0x00ff) 8) | \ (((uint_16)(x) 0xff00) 8) \ ) 或者是函数的形式
uint_16 bswap_16(uint_16 x)
{return (((uint_16)(x) 0x00ff) 8) | \(((uint_16)(x) 0xff00) 8) ;
}232位大小端转换
#define BSWAP_32(x) \ (uint_32)((((uint_32)(x) 0xff000000) 24) | \ (((uint_32)(x) 0x00ff0000) 8) | \ (((uint_32)(x) 0x0000ff00) 8) | \ (((uint_32)(x) 0x000000ff) 24) \ ) 或者是函数的形式
uint_32 bswap_32(uint_32 x)
{ return (((uint_32)(x) 0xff000000) 24) | \ (((uint_32)(x) 0x00ff0000) 8) | \ (((uint_32)(x) 0x0000ff00) 8) | \ (((uint_32)(x) 0x000000ff) 24) ;
} 八. 大小端数据的存取
1存储时
1先按照数据类型开辟一个空间。 int a4字节|——|——|——|——| 2数据定义。a0x123456 3数据分割成存储单元字节。 0x12——0x34——0x56 4不用考虑谁先放谁后放我们要按顺序放先放0x12再放0x34…… 5大端存储方式先往低地址放 |0x12|0x34|0x56|——| 小段存储方式先往高地址放 |——|0x56|0x34|0x12|
2读取时
读取时 1大端依次读出小端倒叙读出。读取时字节内部是一个整体不受倒叙影响。 2读取后就和之前未存储时顺序一致了也就是数没发生变化。 char只占有一个字节因此字符不需要考虑大小端而字符串又是单个字符的组合因此也不需要考虑大小端。因此在网络通信中通信信息为字符串不需要考虑大小端问题。