FILE *fp = NULL; 是 C 語言文件操作的**防禦性編程**慣用語,核心作用有三:
NULL 宏展開為空指針常量(通常為 (void*)0)。FILE *fp = NULL; // 1. 初始化
fp = fopen("data.txt", "r"); // 2. 嘗試打開
if (fp == NULL) { // 3. 必須檢查
perror("fopen failed");
return -1;
}
// 4. 安全使用 fp
fclose(fp);
fp = NULL; // 5. 關閉後置 NULL,防雙重釋放/野指針
若省略步驟 1,fp 可能含隨機值,步驟 3 的判斷失效,導致後續 fread/fwrite 崩潰。
FILE *fp = NULL;
const char *paths[] = {"./config.ini", "/etc/app/config.ini", NULL};
for (int i = 0; paths[i] && fp == NULL; i++)
fp = fopen(paths[i], "r");
if (fp == NULL) {
fprintf(stderr, "所有路徑均打開失敗\n");
exit(EXIT_FAILURE);
}
| 概念 | 含義 | 內存視角 |
|---|---|---|
| 指針值為 0 / NULL | 不指向任何對象,標準保證不等於任何合法對象地址 | 地址 0x0,通常由硬體/MMU 保護,訪問觸發 SegFault |
| 野指針 | 未初始化,持有隨機位模式 | 可能指向代碼段、數據段、棧、堆,訪問行為不可預測 |
| 懸空指針 | 原對象已釋放(free/fclose),指針值未清零 | 指向已歸還內存,訪問屬 UB(未定義行為) |
FILE *fp = NULL; / int *p = NULL;。if (fp) { ... } 或 if (fp != NULL)。fclose(fp); fp = NULL; / free(p); p = NULL;。*ptr = NULL 初始化。-Wuninitialized -Wmaybe-uninitialized (GCC/Clang)。if (fp = fopen(...)) 賦值即判斷雖簡潔,但易與 == 混淆,建議分行寫。NULL 佔用內存——它只是編譯期常量,不佔用運行時額外空間。fp = 0 與 fp = NULL 有區別——在指針上下文中完全等價,但語義上 NULL 更清晰。養成「指針生來為 NULL,用完歸 NULL」的習慣,能消除 90% 以上的指針相關崩潰。