首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C 語言指針類型轉換與大小端模式:char_point 遍歷 int/float 內存字節序差異解析

     編輯:程式設計綜合問答

代碼核心邏輯

  • 定義 typedef unsigned char * char_point;(字節指針)。
  • int_cp、float_cp 將變量地址強轉為 char_point 返回。
  • endian 以字節為單位打印內存內容(cp[i] 訪問第 i 字節)。
  • 對比:直接傳 &i 強轉 vs 通過函數返回指針再傳入。

現象差異原因

函數參數傳遞改變了變量在棧上的內存地址。

  • 直接傳 &i:`i` 在 `main` 棧幀中,地址固定,內存佈局連續。
  • 通過 `int_cp` 返回:`i` 作為參數傳給 `int_cp`,在 `int_cp` 的棧幀中**重新分配副本**,返回該副本地址。副本生命周期隨函數返回結束,**返回指針指向已銷毀的棧內存**(懸空指針),後續訪問屬於未定義行為(UB),打印出的字節序為隨機垃圾值。

內存佈局圖解

main 棧幀:          int_cp 棧幀 (調用時):
[ i: 0x21893678 ]    [ i 副本: 0x21893678 ]  <-- 返回 &副本
                     [ 返回地址 ... ]
                     [ 舊 ebp ... ]
返回後 int_cp 棧幀彈出,副本內存被標記可覆蓋,指針懸空。

修正方案:傳遞原變量地址而非副本

// 修改 int_cp 簽名,接受指針參數
char_point int_cp(int *p) {  // 接收 main 中 i 的地址
    printf("i: %d\n", *p);
    printf("&i: %p\n", (void*)p);
    printf("(c_p)&i: %p\n", (char_point)p);
    return (char_point)p;    // 返回原地址
}

// main 中調用
endian(int_cp(&i), sizeof(i)); // 傳遞 &i,而非 i

大小端驗證輸出解讀

  • 小端模式:低位字節存低地址。0x21893678 內存順序:78 36 89 21(`endian` 打印順序)。
  • 大端模式:高位字節存低地址。順序:21 89 36 78。
  • 浮點數 913.45678f(IEEE 754 單精度):符號位(0) + 指數(10001111) + 尾數...,內存字節序同理取決於端模式。

核心知識點總結

  1. 函數參數按值傳遞會創建副本,返回副本地址導致懸空指針。
  2. 指針類型轉換(`int*` → `char*`)不改變地址值,僅改變解釋方式(步長 1 字節)。
  3. 大小端檢測:通過 `char*` 遍歷 `int` 內存字節序即可判斷。
  4. 避免 UB:永不返回局部變量/參數副本的地址。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved