代碼現場
#include <stdio.h>
int main() {
int a = 8;
int *p = &a;
printf("%d\n", p); // 此處未解引用
return 0;
}
現象解析
- 不報錯原因:
printf 是可變參函數,編譯器無法在編譯期檢查格式字符串與實參類型是否匹配。%d 對應 int,而 p 是 int*,兩者在寄存器/棧上佔用相同位寬(32/64位),編譯器僅發出警告(需開啟 -Wall),不阻止編譯。
- 值不確定原因:輸出的是指針
p 存儲的地址值(即變量 a 的內存地址),而非 a 的值 8。地址值隨進程地址空間佈局隨機化(ASLR)每次運行不同,故顯示「不確定」。
正確寫法對比
| 代碼 | 輸出含義 | 示例輸出 |
printf("%d\n", p); | 指針地址(十進制) | 6422292 |
printf("%p\n", (void*)p); | 指針地址(十六進制,標準寫法) | 0x7ffee3b8 |
printf("%d\n", *p); | 指針指向的值(解引用) | 8 |
最佳實踐建議
- 編譯時務必加上
-Wall -Wextra 開啟所有警告,捕獲格式字符串不匹配
- 輸出指針地址請使用
%p 配合 (void*) 強轉,符合 C99 標準
- 養成「先解引用再輸出值」的肌肉記憶,避免低級錯誤