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

C 語言指標運算解析:結構體陣列指標減法為何得 120

     編輯:程式設計綜合問答

程式碼中 char* p = (char*)(st[2].errstr + 32); printf("%d", p - (char*)st); 輸出 120,核心在於指標減法結果以指標指向型別大小為單位,此處皆為 char*,故結果為位元組數差值。

結構體記憶體佈局

struct st_t {
    int status;        // 4 bytes
    short* pdata;      // 4/8 bytes (假設 32 位元 4 bytes)
    char errstr[32];   // 32 bytes
}; // 總計 40 bytes (含對齊)
st_t st[16];           // 連續 16 個結構體

指標 p 走位過程

  1. (char*)st:陣列起始位址(第 0 個結構體開頭)。
  2. st[2].errstr:第 2 個結構體(索引 2,即第 3 個)的 errstr 成員起始位址。
    偏移 = 2 * 40 (前兩結構體) + 4 (status) + 4 (pdata) = 88 bytes。
  3. st[2].errstr + 32:errstr 陣列結束後的位址,即第 3 個結構體結束、第 4 個結構體開頭。
    偏移 = 88 + 32 = 120 bytes。
  4. p - (char*)st:兩 char* 相減,單位為 sizeof(char) = 1 byte,結果 = 120。

關鍵知識點

  • 指標減法:ptr1 - ptr2 結果型別為 ptrdiff_t,值為「相差多少個 sizeof(*ptr) 單位」。
  • 結構體對齊:編譯器可能在成員間插入填充位元組,sizeof(st_t) 可能大於成員大小總和。此例假設無額外填充(40 bytes)。
  • 陣列索引:st[2] 為第 3 個元素,偏移 2 * sizeof(st_t)。

驗證程式

printf("sizeof(st_t)=%zu\n", sizeof(st_t)); // 40
printf("offsetof(errstr)=%zu\n", offsetof(st_t, errstr)); // 8
printf("st[2].errstr - (char*)st = %td\n", (char*)&st[2].errstr - (char*)st); // 88
printf("p - (char*)st = %td\n", p - (char*)st); // 120

掌握指標運算單位與結構體記憶體佈局,是 C 語言底層開發與逆向分析的基本功。

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