語法書 / AA 競程語法書 下冊 / 第八單元 / 字元與整數的互相轉換

8.2 字元與整數的互相轉換

上冊 3.7 學過顯性轉換(cast),當時預告「字元和整數之間怎麼轉,下冊再談」——就是這裡。字元既然骨子裡是編號,跟整數互轉就只是「查表」:

字元 → 整數:得到它的 ASCII 編號

cout << (int)'A' << '\n';   // 65
cout << (int)'0' << '\n';   // 48:注意!字元 '0' 的編號是 48,不是 0

整數 → 字元:得到這個編號對應的字元

cout << (char)65 << '\n';   // A
cout << (char)48 << '\n';   // 0(數字「字元」)

只要整數落在字元存得下的範圍(競程場合就是 0 \sim 127),這個轉換一定正確。

數字字元 ↔ 數值:c - '0''0' + d

這是本節最重要的技巧。先想清楚一件事:字元 '7' 和數值 7 是兩回事——'7' 的編號是 55,直接拿去算數學會得到很怪的結果。

怎麼把 '7' 變成真正的 7?用「區段內連續」這個性質:'7' 的編號比 '0' 的編號恰好大 7,所以相減就是答案

char c = '7';
int d = c - '0';    // 55 - 48 = 7:數字「字元」變成真正的數值

反過來,把數值 3 變回字元 '3',就加回去:

int x = 3;
char c2 = '0' + x;  // 48 + 3 = 51,也就是字元 '3'

妙處在於:整個過程不需要記得 '0' 的編號是 48c - '0''0' + x 這兩個式子讓編譯器自己去查,你只要記得「跟 '0' 的距離=數值」。字母也同理:c - 'A' 是大寫字母 c 在字母表中的位置(從 0 數起),'A' + k 是第 k 個大寫字母(一樣從 0 數起)。

範例程式碼

來看一個「整數 → 字元」的可愛應用,一行迴圈印出整張大寫字母表:

#include <iostream>
using namespace std;

int main() {
    for (int i = 0; i < 26; i++) {
        cout << (char)('A' + i);   // 'A' 往後數 i 個位置
    }
    cout << '\n';
    return 0;
}

執行結果:

ABCDEFGHIJKLMNOPQRSTUVWXYZ

動手試試看:解掉字母順序寫不出來的大學生是存在的 2——題目有兩種詢問(第一行先給詢問類型):類型 1 給你 1 \sim 26 的編號、輸出對應的大寫字母;類型 2 反過來,給你大寫字母、回答它是第幾個。兩個方向剛好各練一次 'A' + kc - 'A'(注意題目從 1 數起、這兩個式子從 0 數起,兩邊的差一都要自己補)。