字串結尾為空字元的字串
程式怎麼知道一段文字在哪裡結束?在 C 中答案是末尾一個安靜的標記。C 字串就是一個字元陣列,外加一條規則:真正的文字後面跟著一個值為零的特殊結束標記字元,稱為字串結尾字元(寫作 '\0')。讀一個字串就是走過那些字元,直到撞上那個零位元組——那個位元組就是「在此停止」的標誌。
所以單字 "cat" 被存成四個位元組:'c'、'a'、't',然後 '\0'。你原始碼裡的字串字面值會自動替你加上那個結尾字元,所以 "cat" 需要一個至少 4 個 char 的陣列。這個結尾字元正是為什麼像 strlen() 的函式不必被告知就能算出長度——它們數字元直到那個零位元組(所以 strlen("cat") 是 3,不計結尾字元)。string.h 裡的標準字串函式庫完全建立在這個慣例上:strcpy() 複製到並含結尾字元,strcmp() 逐位元組比較直到不同或兩者都碰到零。
為什麼重要與危險:這個設計簡單又省記憶體,但它有著名的陷阱。如果你忘了替結尾字元留空間,或某個字串少了它的 '\0',函式就會在尋找一個不存在的零時衝出緩衝區尾端——一個緩衝區溢位、未定義行為、以及經典的安全錯誤。像 strcpy() 與 gets() 這類盲目信任結尾字元的函式很危險;較安全、有長度上限的版本(如 snprintf,或謹慎使用的 strncpy)之所以存在,正因為這種以空字元結尾的設計不提供任何內建的長度保護。
char word[] = "cat"; /* 存成 'c','a','t','\0':4 位元組 */ size_t n = strlen(word); /* 3——數到但不含 '\0' */ char buf[3]; /* strcpy(buf, "cat"); 會溢位:需要容納 '\0' 的空間 */
"cat" 因為隱藏的 '\0' 佔 4 位元組。strlen 數出 3 個可見字元。一個 3 位元組的緩衝區沒有容納結尾字元的空間。
字串需要為它的 '\0' 多留一個位元組,所以容納 n 個字元意謂一個 n+1 大小的陣列。掃描結尾字元的函式(strcpy、strlen)在它缺失或緩衝區太小時會衝出尾端——一個緩衝區溢位。