8.6 C 語言字串:帶結尾記號的字元陣列
從這一節開始處理「一整串文字」——字串(string)。習慣上用雙引號描述字串內容:"abc"、"I love AACPSCHOOL"。其實你從第一支程式就在用它:cout << "Hello World" 裡的那段就是字串。
上冊 6.6 已經用字元陣列存過一串字,但當時有個不太自然的地方:題目得先告訴你長度 n,你才知道要讀幾個字、之後的處理要跑到哪。真實世界的字串(還有很多題目)不會附長度——那電腦怎麼知道一個字串到哪裡結束?
C 語言想出的辦法很簡單,C++ 也照著用到今天(名字就是這樣來的:C 語言字串,簡稱 C 字串)。做法只有兩步:
- 把字串的所有字元按順序放進字元陣列(連續的記憶體,上冊 6.1 學過)。
- 在最後一個字元的下一格放一個結尾記號:空字元(null character)
'\0'——ASCII 編號 0 的那個字元。
長度不用另外記——從頭開始走,撞到 '\0' 就是結束。陣列開多大不重要,'\0' 的位置才決定字串多長。
char s[10] = "abc";
索引: 0 1 2 3 4 ... 9
內容: 'a' 'b' 'c' '\0' '\0' ... '\0' ← 字串是前 3 格,s[3] 的 '\0' 是結尾記號
(後面幾格也是 '\0',是上冊 6.5「初始化沒給到的自動補 0」的老規則。之後若改用 cin >> s 讀進來,'\0' 後面的格子留著什麼都有可能——反正一切以第一個 '\0' 為準,後面是什麼沒人在乎。)
三個容易搞混的字元,趁現在分清楚:
| 寫法 | ASCII 編號 | 是什麼 |
|---|---|---|
'\0' |
0 | 空字元——C 字串的結尾記號,看不見 |
'0' |
48 | 數字「零」的字元,看得見 |
' ' |
32 | 空格,看不見但佔一格 |
¶雙引號字面常數,其實就是 C 字串
寫在程式裡的 "abc",編譯器會把它做成一個 C 字串:三個字母+自動附上的 '\0',共佔 4 個位元組。可以用 sizeof 驗證(上冊 2.2 的老朋友):
¶範例程式碼
#include <iostream>
using namespace std;
int main() {
char s[10] = "abc"; // 前 3 格是 a b c,第 3 格之後補 '\0'
cout << s << '\n'; // cout 遇到字元陣列:從頭印到 '\0' 為止
cout << s[0] << s[1] << '\n'; // 也可以照舊當一般陣列逐格存取
cout << (int)s[3] << '\n'; // 隱藏在結尾的 '\0',編號是 0
cout << sizeof("abc") << '\n'; // 字面常數佔 4 位元組:3 個字母 + 1 個 '\0'
return 0;
}
執行結果:
abc
ab
0
4
第一行是新魔法:cout << 一個字元陣列,會把整個字串一路印到 '\0' 前為止——不用自己寫迴圈。這也是為什麼結尾記號如此重要:沒有 '\0',cout 不知道在哪停下來。
動手試試看:把範例程式碼的 "abc" 換成空字串 "",猜猜 cout << s 和 sizeof("") 各是什麼,再執行驗證(提示:空字串也有 '\0')。