You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

小端系统下大小端转换疑问:数值与字节表示的困惑

小端系统中ntohs/htons转换后数值差异的原因

运行以下C++代码(小端系统):

#include <iostream>
#include <arpa/inet.h>

using namespace std;

int main(){
  uint16_t a = 0b0000000000000001;

  cout<<"Little Endian = "<<a<<endl;
  cout<<"Big Endian = "<<ntohs(a)<<endl;
  uint16_t c = ntohs(a);

  cout<<"Big Endian = "<<c<<endl;
  cout<<"Little Endian = "<<htons(c)<<endl;
  return 0;
}

输出:

Little Endian = 1
Big Endian = 256
Big Endian = 256
Little Endian = 1

先明确两个核心概念:

  • 字节序:多字节数据在内存中的物理存储顺序,和变量的逻辑数值无关。
  • ntohs/htons:在小端主机上本质是字节反转操作,它们转换的是字节的存储顺序,最终体现为逻辑数值的变化。

代码逻辑拆解

  1. 变量a的存储与打印
    uint16_t a = 0b0000000000000001;定义的是变量的逻辑数值(十进制1)。在小端系统中,编译器会把它按「低字节在前、高字节在后」的规则存进内存:

    • 内存字节顺序:0x01(对应逻辑值的低8位)在前,0x00(对应逻辑值的高8位)在后。
    • 打印a时,CPU会自动按小端规则读取字节,还原成逻辑数值1,所以输出Little Endian = 1。
  2. ntohs(a)的转换逻辑
    ntohs的作用是将网络字节序(大端)的字节流转换为主机字节序(小端)。但你传入的是主机字节序的a,相当于让ntohs把a的内存字节当成大端字节序来解析:

    • 大端规则是「高字节在前、低字节在后」,所以a的内存字节0x01 0x00会被解析为高字节0x01 + 低字节0x00,组合成逻辑值0x0100(十进制256)。
    • 这就是ntohs(a)的返回结果,所以输出Big Endian = 256。
  3. htons(c)的转换逻辑
    c的逻辑数值是256,在小端主机上它的内存存储是0x00(低字节)在前,0x01(高字节)在后。htons的作用是将主机字节序的字节流转换为网络字节序(大端):

    • 它会反转这两个字节,变成大端的0x01 0x00,对应逻辑数值1,所以输出Little Endian = 1。

一句话总结

你混淆了「字节的物理存储顺序」和「变量的逻辑数值」。ntohs/htons在小端主机上是反转字节,反转后的字节组合成的逻辑数值自然会变化——把原本低字节在前的1(内存0x01 0x00)反转成高字节在前的0x0100,数值就是256,反之亦然。

内容的提问来源于stack exchange,提问作者onxy tzy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 02:12:51