Byteorder 字节序

#Byteorder

一个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*)&num;		/* ^^ */

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,宏定义的具体实现都是相同的,都是字节轴对称换个位置。

注意到charshort类型的数据在左移<<的时候会被默认提升到int
这在比较严格的编译选项-Wsign-conversion中会报错隐式转换,所以可以在左移运算结束后强制转换类型:

1
2
3
#define USHORT unsigned short int
#define NTOHS(x) (((USHORT)(((x) & 0x00FF) << 8)) | \
				           (((x) & 0xFF00) >> 8))
updatedupdated2025-03-032025-03-03