一个int四个字节
- 高字节处于低内存,属于大端序
- 低字节处于低内存,属于小端序
1
2
3
4
5
6
7
8
9
10
11
12
13
|
/*
digit : 1
高字节 低字节
31 <----> 0
00 00 00 01
*/
int num = 1; /* 01 00 00 00 */
char c = *(char*)# /* ^^ */
if (c == 1) /* 内存低地址 --> 内存高地址 */
cout << "小端" << endl; /* 01 00 00 00 */
else
cout << "大端" << endl; /* 00 00 00 01 */
|
即大端序。UDP/TCP/IP协议规定: 把接收到的第一个字节当作高字节看待。
就一个思路:一个一个字节操作,高字节移动到低位,低字节移动到高位,然后把一个一个字节通过或|运算符拼起来。
1
2
3
4
5
6
7
|
#define NTOHS(x) ((((x) & 0x00FF) << 8) | \
(((x) & 0xFF00) >> 8))
#define NTOHL(x) (((((x) & 0x000000FF) << 24) | \
(((x) & 0x0000FF00) << 8) | \
(((x) & 0x00FF0000) >> 8) | \
(((x) & 0xFF000000) >> 24)))
|
无论是NTOHS还是HTONS,宏定义的具体实现都是相同的,都是字节轴对称换个位置。
注意到char和short类型的数据在左移<<的时候会被默认提升到int。
这在比较严格的编译选项-Wsign-conversion中会报错隐式转换,所以可以在左移运算结束后强制转换类型:
1
2
3
|
#define USHORT unsigned short int
#define NTOHS(x) (((USHORT)(((x) & 0x00FF) << 8)) | \
(((x) & 0xFF00) >> 8))
|