8.3 字元的運算
字元骨子裡是整數,所以整數會的運算它都會——加減、比較都沒問題。把 char 想成「1 位元組的迷你整數」,只差在 cout 印它時會印出編號對應的字元而不是編號本身。這一節把競程用得到的字元運算一次練齊。
¶字母的位移與距離
「區段內連續」讓兩件事變得超簡單——往後數 k 個字母(加法)和算兩個字母差幾個位置(減法):
#include <iostream>
using namespace std;
int main() {
char c1 = 'A';
char c2 = c1 + 1; // 'A' 的下一個字母
cout << c2 << '\n'; // B
cout << (char)('a' + 2) << '\n'; // 小寫同理:'a' 往後數 2 個 → c
int dif = 'z' - 'a'; // 兩個字母的「距離」
cout << dif << '\n'; // 25:z 是第 25 個小寫字母(從 0 數起)
return 0;
}
執行結果:
B
c
25
數字字元同理:'1' + 5 對應到 '6'(嚴格說,運算的結果是整數)、'8' - '3' 是 5。但注意運算範圍——數字字元只有 '0' ~ '9' 十個,加超過就掉出區段外:
#include <iostream>
using namespace std;
int main() {
char c = '9'; // '9' 的編號是 57
c++;
cout << c << '\n'; // 編號 58 是冒號,不是「'10'」!
return 0;
}
執行結果:
:
'9' 加一不會變成「一個代表 10 的字元」——ASCII 表上 57 的下一格是冒號 ':'。想做真正的十進位進位,得先 c - '0' 轉成數值再算。
¶大小寫轉換
同一個字母的大小寫編號差固定是 32,所以大寫加 32 變小寫、小寫減 32 變大寫。但更推薦的寫法是讓編譯器自己算差距——忘了 32 也不會錯:
#include <iostream>
using namespace std;
int main() {
char c1 = 'A';
char c2 = c1 + 32; // 加上固定差距 32
cout << c2 << '\n'; // a
char c3 = 'c';
char c4 = c3 + 'A' - 'a'; // 小寫轉大寫:加上(大寫 − 小寫)的差距
cout << c4 << '\n'; // C
char c5 = 'Q';
char c6 = c5 + 'a' - 'A'; // 大寫轉小寫:方向反過來
cout << c6 << '\n'; // q
return 0;
}
執行結果:
a
C
q
記法:要變成誰,就把誰放前面加——轉小寫加 'a' - 'A',轉大寫加 'A' - 'a'。(8.5 還會介紹更省事的內建函式 toupper/tolower。)
¶一條一定要記的規則:integer promotion
用一個極端的例子感受一下——兩個「字元」相乘:
#include <iostream>
using namespace std;
int main() {
cout << 'c' * '\n' << '\n'; // 'c' 是 99、'\n' 是 10,相乘就是整數運算
return 0;
}
執行結果:
990
沒有任何錯誤訊息——字元本來就是整數,乘起來理直氣壯。規則本身不難,難的是它埋的陷阱:
動手試試看:輸入兩個大寫字母,輸出它們在字母表中相隔幾個位置(例如 A 和 E 相隔 4)。誰前誰後不一定,記得用上冊 7.6 的 abs 取絕對值。