首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言判斷 CPU 大小端模式:三種經典方法與原理圖解

     編輯:關於C語言

概念速覽

模式低地址存放高地址存放典型架構
大端高位字節低位字節网络字節序、PowerPC、SPARC
小端低位字節高位字節x86、x64、ARM (默認)

例:0x12345678 在小端機上內存佈局(地址遞增):78 56 34 12。

方法一:指釖強制類型轉換(最常用)


bool is_little_endian() {
    int val = 0x12345678;
    char *p = (char *)&val;  // char* 逐字節訪問
    return p[0] == 0x78;     // 低地址存低位 → 小端
}

也可用 short / union 變體。

方法二:聯合體(語義清晰,無嚴格別名問題)


bool is_little_endian() {
    union {
        int i;
        char c[4];
    } u;
    u.i = 0x12345678;
    return u.c[0] == 0x78;
}
  • 聯合體成員共享內存,標準保證此用法合法。
  • 可直接打印 u.c[0]..u.c[3] 觀察完整字節序。

方法三:移位與掩碼(無類型轉換,純算術)


bool is_little_endian() {
    int val = 1;  // 0x00000001
    return (*(char *)&val) == 1;  // 等價判斷最低字節是否為 1
}

最簡潔,利用 1 的二進制只有最低位為 1。

運行時檢測 vs 編譯時檢測

  • 運行時:上述函數,適用於異構部署(同一二進制跑不同架構)。
  • 編譯時:#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ (GCC/Clang),#ifdef _WIN32 (Windows 均為小端)。

網絡編程中的字節序轉換


#include   // 或 

// 主機序 → 網絡序 (大端)
uint16_t port_net = htons(port_host);
uint32_t ip_net   = htonl(ip_host);

// 網絡序 → 主機序
uint16_t port_host = ntohs(port_net);
uint32_t ip_host   = ntohl(ip_net);

鐵律:所有進出網絡的整數必須轉換,即使當前機器是大端(遷移時免改代碼)。

結構體序列化陷阱


#pragma pack(1)
struct Packet {
    uint32_t magic;   // 需 htonl
    uint16_t len;     // 需 htons
    char data[];
};
#pragma pack()
  • #pragma pack(1) 消除填充,但不處理字節序。
  • 發送前逐字段 hton*,接收後 ntoh*。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved