引言:
字节序的问题:小端表示:最低有效字节放在低地址
大端表示:最高有效字节放在低地址
比较容易记住的方法是:假如:int a = 0x 12345678 ; 对于小端,顺时针旋转, 12
34
56
78
正好低位放在低地址,假如有如下代码: char str = *a ; 那么str = 0x 78;
大端模式,逆时针旋转 AA放在低地址, char str = *a ; 那么str = 0x 12;
在不同机器间传输数据的时候,需要进行字节序转换,当从网络上取回数据,也需转换字节序。
转换字节序的方法:通过ntohs,ntohl函数将整数进行转换。这个函数的功能是将网络序转换成主机序,在大端机器上它什么也不做
htonl,htons用于本机序转换到网络序
没有对char型字节的转换:
模拟ntohs,ntohl的实现:
// 短整型大小端互换
#define BigLittleSwap16(A) ((((uint16)(A) & 0xff00) >> 8) | \
(((uint16)(A) & 0x00ff) << 8))
// 长整型大小端互换
#define BigLittleSwap32(A) ((((uint32)(A) & 0xff000000) >> 24) | \
(((uint32)(A) & 0x00ff0000) >> 8) | \
(((uint32)(A) & 0x0000ff00) << 8) | \
(((uint32)(A) & 0x000000ff) << 24))
假如 定义 short a = 0x 0; 字节序转换后为 0 ;short a = 0x 1; 0000 0000 0000 0001 转换后为 0000 0001 0000 0000 十进制256
定义 int a = 0x 0; 字节序转换后为 0; int a = 0x 1; 0000 0000 0000 0000 0000 0000 0000 0001 转换0000 0001 0000 0000 0000 0000 0000 0000 值16777216
位域问题:
与字节序一样,一个字节中的8个bit顺序在不同端序的机器上并不相同。大端机器上从低地址到高地址顺寻分别是msb->lsb,如下图:
现代计算机的最小存储单位是BYTE,无法对bit寻址,因此我们无法直接观察每个字节内部bit的顺序。但是我们仍然可以通过位域来间接观察字节内部bit顺序,以印证上面的说法
我们看看下面的程序。
#include <stdio.h>
typedef struct OneByte
{
char bt0 : 1;
char bt1 : 1;
char bt2 : 1;
char bt3 : 1;
char bt4 : 1;
char bt5 : 1;
char bt6 : 1;
char bt7 : 1;
} ONE_BYTE;
int main()
{
ONE_BYTE onebyte = {0};
onebyte.bt7 = 1;
printf("onebyte = %#x/r/n", *((unsigned char *)&onebyte));
return 0;
}
而在VC2005中编译运行的结果如下:
0x80转换成二进制是1000
所以位域在大小端机器上要相反定义,例如:
#ifdef BIG_ENDIAN
char th_x2 : 4;
th_off: 4;
#else
char th_off: 4;
th_x2 : 4;
#endif