開啟章節選單
字元
極為常見雖然在 基本資料型態 中我們有簡單提到字元,但我們其實還有很多東西沒有講到,所以這個章節我們就來更深入的了解一下字元!
所謂的字元就是指一個字,通常為符號、字母、數字還有換行字元等等,好比說 a
、1
、+
、\n
。
基本用法
在 C++ 中,字元的型態是 char
,宣告方式如下,不過要記得所有的字元都要用單引號 '
包住:
char c = 'a'; cout << c << endl; // a
請不要使用雙引號 "
來包住字元,因為這樣會變成字串,而不是字元:
char c = "a"; // 這樣是錯誤的
關於字串的部分,我們會在之後的章節詳細介紹。
ASCII 編碼
在繼續學習字元之前,我們得先了解一下 ASCII
編碼。
ASCII
是一種字元編碼方式,它將字元和數字一一對應起來,用來在電腦中儲存字元。每一個字元都有自己的 ASCII
碼,比如說 a
就是 97,b
就是 98,0
就是 48,A
就是 65,等等。常見字元的 ASCII
編碼如下:
種類 | 內容 | 編碼 |
---|---|---|
數字 | 0~9 | 48~57 |
大寫字母 | A~Z | 65~90 |
小寫字母 | a~z | 97~122 |
空白 | 32 |
ASCII 與字元
實際上字元在記憶體中其實是一個整數(ASCII 編碼),只是在輸出時會轉換成對應的字元。所以如果你想要知道字元的 ASCII
碼,可以把它強制轉型成 int
再輸出:
char a = 'a'; cout << (int)a; // 97
或者如果你需要的話,也可以把整數換成字元:
int a = 97; cout << (char)a; // a
不過既然是整數,當然也可以進行運算:
char a = 'a'; char b = 'b'; cout << a + b << endl; // 195 cout << a + 1 << endl; // 98 cout << (char)(a + 1) << endl; // b
還可以這樣賦值:
char a = 97; cout << a << endl; // a
字元與整數之間的轉換
前面我們提到,字元在記憶體中其實是一個代表 ASCII
碼的整數,所以當然可以被當作整數來用。不過要注意的是,字元和整數相加的時候,會被當作 ASCII
碼來運算,而不是「數字」。舉例來說:
char one = '1'; char two = '2'; cout << one + two << endl; // 99
那如果想要把字元轉成「數字」呢?這邊有一個小技巧,就是減去字元 '0'
,這樣就可以得到對應的數字了。這是因為 ASCII
碼中數字 '0'
到 '9'
是連續的,所以只要減去 '0'
就可以得到對應的數字,也就是他們的差值:
char one = '1'; char two = '2'; int one_num = one - '0'; cout << one_num << endl; // 1 int two_num = two - '0'; cout << two_num << endl; // 2 cout << one_num + two_num << endl; // 3 cout << two_num * 5 << endl; // 10
反過來,如果想要把數字轉成字元,只要加上 '0'
就可以了:
int a = 1; int b = 2; char a_char = a + '0'; cout << a_char << endl; // 1 char b_char = b + '0'; cout << b_char << endl; // 2 cout << a_char + b_char << endl; // 99
字元的比較
字元之間的比較和整數一樣,可以用 ==
、!=
、<
、>
、<=
、>=
來比較。不過要注意的是,字元之間的比較是根據 ASCII
碼來比較的,舉例來說:
char a = 'a'; char b = 'b'; char c = 'c'; cout << (a < b) << endl; // true cout << (a < c) << endl; // true cout << (a > c) << endl; // false
和判斷字元有點相關的函式們
isalpha
這個函式是拿來判斷字元是否為字母,不是的話就回傳 0,否則就是一個非零整數。
char a; cin >> a; if (isalpha(a)) cout << "Yes"; else cout << "No";
isdigit
跟上面有點像,只是這次是判斷字元是不是數字,也是回傳 0 或非零整數。
char a; cin >> a; if (isdigit(a)) cout << "Yes"; else cout << "No";
isalnum
則是判斷字元是不是字母或數字,也是回傳 0 或非零整數。
char a; cin >> a; if (isalnum(a)) cout << "Yes"; else cout << "No";
islower
和 isupper
則是判斷字元是不是小寫或大寫字母,也是回傳 0 或非零整數。
char a; cin >> a; if (islower(a)) cout << "Yes"; else cout << "No";
char a; cin >> a; if (isupper(a)) cout << "Yes"; else cout << "No";
再次強調,這邊有一點必須非常注意,isalpha
、isdigit
、isalnum
、islower
、isupper
以上這些函式回傳的是 int
,而不是 bool
,而且可能的回傳值不只有 0
和 1
,有些人可能會直覺的這麼寫:
if (isalpha(a) == 1) cout << "Yes"; else cout << "No";
但這樣寫是錯誤的,isalpha
的回傳值可能會因為不同字元、不同編譯器或者版本而有所不同,所以請絕對不要這樣寫!
來看看這份程式碼:
for (auto c = 'a'; c <= 'z'; c++) { cout << isalnum(c) << " "; } for (auto c = 'A'; c <= 'Z'; c++) { cout << isalnum(c) << " "; } for (auto c = '0'; c <= '9'; c++) { cout << isalnum(c) << " "; }
以下是使用 GNU G++20 13.2 (64 bit, winlibs)
編譯器測試上面這段程式碼的結果:
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4
可以看到 isalnum
回傳的值絕對不只有 0
和 1
,所以請記得不要把 isalpha
、isdigit
、isalnum
、islower
、isupper
拿來跟 1
比較!
下面這兩種寫法才是正確的:
if (isalpha(a)) cout << "Yes"; else cout << "No";
if (isalpha(a) != 0) cout << "Yes"; else cout << "No";
小測驗
如果把兩個字元相加,會得到什麼?