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

C 語言 Union 與大小端模式:原理、實例與檢測代碼

     編輯:關於C

一、Union 基礎特性

  • 所有成員共享同一塊內存,起始地址相同
  • 佔用空間 = 最大成員的大小
  • 同一時刻只能存儲一個成員的值
  • 主要用途:節省空間、類型懲罰、檢測大小端
union StateMachine {
    char character;
    int number;
    char *str;
    double exp;
};  // 大小 = sizeof(double) = 8 字節 (64位)

二、大小端對 Union 的影響

union {
    int i;
    char a[2];
} *p, u;

p = &u;
p->a[0] = 0x39;
p->a[1] = 0x38;
模式內存佈局 (低地址→高地址)p->i 值
大端0x39, 0x38, 0x00, 0x000x39380000
小端0x38, 0x39, 0x00, 0x000x00003839

因 Union 所有成員偏移均為 0,a[0] 對應 i 的最低/最高字節,直接反映端序。

三、運行時檢測大小端的標準代碼

int check_endianness(void) {
    union {
        int i;
        char c;
    } u = { .i = 1 };
    return u.c == 1;  // 1 = Little Endian, 0 = Big Endian
}

原理:int i = 1 內存中只有最低字節為 1。小端模式最低字節在低地址,c 讀到 1;大端模式最低字節在高地址,c 讀到 0。

四、調試器直觀驗證

內存佈局截圖

圖 內存中 0x01 位於低地址,確認當前為小端模式

五、經典指針算術題目解析

#include 
int main() {
    int a[5] = {1,2,3,4,5};
    int *ptr1 = (int *)(&a + 1);   // &a 是 int(*)[5],+1 跳過整個數組
    int *ptr2 = (int *)((int)a + 1); // a 轉整數 +1,僅偏移 1 字節
    printf("%x, %x\n", ptr1[-1], *ptr2);
    return 0;
}

解析

  1. ptr1 指向數組尾後,ptr1[-1] 即最後一個元素 5 (0x5)
  2. ptr2 指向 a[0] 低地址偏移 1 字節處,讀取 4 字節得到 00 00 00 02(小端),即 0x02000000

六、工程建議

  • 網絡協議/文件格式必須固定字節序(通常大端),收發端用 htons/htonl/ntohs/ntohl 轉換
  • Union 類型懲罰在 C11 後為未定義行為,嚴格項目建議用 memcpy 或 _Static_assert 配合 alignas
  • 跨平台代碼避免依賴特定端序,封裝讀寫接口統一處理

七、總結

Union 共享內存特性使其成為檢測大小端、零拷貝類型轉換的利器。理解「低地址存低字節(小端) / 高字節(大端)」並能手寫檢測代碼,是系統級 C 程序員基本功。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved