在 C 語言中,將大寫字母轉換為小寫字母是字元處理的入門操作。看似簡單的 c2 = c1 + 32,實則蘊含了 ASCII 編碼設計的精妙規律。
#include <stdio.h>
int main() {
char c1, c2;
printf("請輸入一個大寫字母: ");
scanf("%c", &c1);
c2 = c1 + 32; // ASCII 碼差值
printf("c2=%c\nc2=%d\n", c2, c2);
return 0;
}
請輸入一個大寫字母:A c2=a c2=97
| 字元 | 十進制 | 二進制 | 十六進制 |
|---|---|---|---|
| 'A' | 65 | 0100 0001 | 0x41 |
| 'a' | 97 | 0110 0001 | 0x61 |
| 'Z' | 90 | 0101 1010 | 0x5A |
| 'z' | 122 | 0111 1010 | 0x7A |
關鍵發現:大小寫字母僅在第 6 位(值為 32)不同!大寫第 6 位為 0,小寫為 1。因此:
c | 32 或 c + 32c & ~32 或 c - 32c ^ 32(異或翻轉第 6 位)#include <ctype.h> // 標準字元處理函數
int main() {
char c = 'A';
printf("tolower: %c\n", tolower(c)); // 標準轉小寫
printf("toupper: %c\n", toupper('z')); // 標準轉大寫
return 0;
}
優勢:可移植性強(支援 EBCDIC 等非 ASCII 字元集)、處理非字母字元安全(原樣返回)、語意清晰。
#define TO_LOWER(c) ((c) | 0x20) #define TO_UPPER(c) ((c) & ~0x20) #define TOGGLE_CASE(c) ((c) ^ 0x20) // 僅適用於 ASCII 字母,非字母字元會產生亂碼 // 實務上請優先使用函數
'@' + 32 = '`'(反引號),非預期結果。ctype.h 函數需轉 unsigned char:避免負值導致未定義行為。理解 ASCII 碼表中大小寫字母的位分佈,不僅能寫出高效的轉換程式,更能建立「字元即數值、位運算即邏輯」的系統級思維。實務開發請優先使用標準庫 tolower/toupper,確保跨平台正確性。