定義與本質區別
| 符號 | 類型 | 定義 | 用途 |
| 0 | 整數常數 | 值為 0 的 int | 通用零值,任何語境均可,編譯器自動轉型 |
| '\0' | 字元常數 | ASCII 碼 0 (NUL 字元) | 字串結束標記、字元比較、字元陣列初始化 |
| NUL | 術語/巨集 | 字元 '\0' 的名稱 | 文檔溝通用;C 標準庫未定義,若需用請 #define NUL '\0' |
| NULL | 巨集 | ((void*)0) 或 0 (C++) | 僅用於指標,表示空指標 |
| EOF | 巨集 | 通常為 -1 (int) | 檔案讀取結束標記,getchar()、fgetc() 回傳 |
核心規則:不可互換
// 正確
char *p = NULL; // 指標
char c = '\0'; // 字元
int i = 0; // 整數
if (getchar() == EOF) // 檔案結束
// 錯誤/危險
char *p = 0; // C++ 允許,C 建議用 NULL
char *p = '\0'; // 型別不匹配
int *p = NULL; // 正確
int i = NULL; // 錯誤:NULL 可能是 (void*)0,指標轉整數未定義
char c = NULL; // 錯誤
if (strcmp(s1,s2) == NULL) // 錯誤:strcmp 回傳 int
記憶體模型視角
- NULL:編譯器保證該位址不可存取(通常為 0x0),解參考觸發硬體異常。
- 0:純數值,作為指標時同 NULL,但語意不清。
- '\0':佔 1 byte 記憶體,值為 0x00,是字串長度計算的哨兵。
- EOF:
int 範圍外的特殊值(-1),區別於合法字元 (0~255),故 getchar() 回傳 int 而非 char。
常見錯誤與最佳實踐
- 指標判空:
if (ptr == NULL) 或 if (!ptr),勿用 if (ptr == 0)(雖合法但語意弱)。
- 字串結尾:
str[len] = '\0'; 明確語意,優於 str[len] = 0;。
- 檔案讀取迴圈:
int ch;
while ((ch = getchar()) != EOF) { /* 處理 ch */ }
// 錯誤:char ch; while ((ch = getchar()) != EOF) ... // 若 char 為 unsigned,EOF(-1) 變 255,永不相等
- 自定義 NUL:若專案需用 NUL 符號,統一在共用標頭定義
#define NUL '\0'。
標準引用
- C99 §7.17:
NULL 定義於 <stddef.h>、<stdio.h> 等
- C99 §7.19.1:
EOF 定義於 <stdio.h>,值為負整數常數
- C99 §6.4.4.4: 字元常數
'\0' 型別為 int,值為 0