字节序的概念、判断、及转换
1.字节序的概念
首先,要明确以下两点:
- 一 双字节数据以上有高字节和低字节之分
- 二 字节在内存中从低地址到高地址依次存放
这样,以字WORD(双字节)数据0x1234为例:
大端字节序:字数据高字节存储在内存的低地址,而低字节存储在内存中的高地址 。如0x12存储在地址a处,则0x34存储在a+1处[即:高对低,低对高].
小端字节序:字数据高字节存储在内存的低地址,而低字节存储在内存中的高地址 。如0x34存储在地址a处,则0x12存储在a+1处[即:高对高,低对低].
通常,Intel的x-86系列采用小端字节序,而网络通信使用大端字节序。
2.字节序的判断
#define _UNICODE#define _AFXDLL#include<tchar.h>#include<afx.h>#include<iostream>using namespace std;typedef union _ut{TCHAR t;int n;
}ut;bool IsSmallEndian()
{ut u;u.n = 65;if(u.t=='A')
return true;else
return false;}int _tmain(int argc,TCHAR ** argv){wcout.imbue(std::locale("chs"));
if(IsSmallEndian())
wcout<<_T("此计算机使用小端")<<endl;
else
wcout<<_T("此计算机使用大端")<<endl;
return 1;
}
注意这里用到了联合体Union的独特性质。
3.字节序的转换
#if defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)
#define htons(A) (A)#define htonl(A) (A)#define ntohs(A) (A)#define ntohl(A) (A)#elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)#define htons(A) ((((uint16)(A) & 0xff00) >> 8) | \(((uint16)(A) & 0x00ff) << 8))#define htonl(A) ((((uint32)(A) & 0xff000000) >> 24) | \(((uint32)(A) & 0x00ff0000) >> 8) | \(((uint32)(A) & 0x0000ff00) << 8) | \(((uint32)(A) & 0x000000ff) << 24))#define ntohs htons#define ntohl htohl#else
#error "Either BIG_ENDIAN or LITTLE_ENDIAN must be #defined, but not both."
#endif
注意,主要用到了移位操作。