目錄
第一性問題:什么是“大小寫”?
逐步構造代碼:全部轉為大寫?
我們現在用 第一性原理 的方式,從字符串與字符的本質出發,一步步推導出如何在 C 語言中將字符串中的字母變成全部大寫或全部小寫。
第一性問題:什么是“大小寫”?
我們必須問清楚:
?“A”和“a”之間的差異在計算機里是什么?
答案:ASCII碼!
字符 | ASCII值 |
---|---|
'A' | 65 |
'a' | 97 |
'B' | 66 |
'b' | 98 |
… | … |
'Z' | 90 |
'z' | 122 |
觀察:
每個小寫字母與對應的大寫字母的 ASCII 差值是:32
字母對 | 差值 |
---|---|
'a' - 'A' | 97 - 65 = 32 |
'z' - 'Z' | 122 - 90 = 32 |
推導公式:
-
把小寫轉大寫:
ch - 32
-
把大寫轉小寫:
ch + 32
但前提是:你必須先判斷這個字符是字母!
?明確目標(功能定義)
1. 輸入一個以 \0
結尾的字符串
2. 將里面所有英文字母統一轉為大寫 或 統一轉為小寫
3. 非字母字符保持不變
如何判斷字符是不是字母?
我們繼續從 ASCII 的第一性原理推導:
范圍 | 條件 | ASCII |
---|---|---|
大寫字母 | 'A' <= ch <= 'Z' | 65~90 |
小寫字母 | 'a' <= ch <= 'z' | 97~122 |
逐步構造代碼:全部轉為大寫?
Step 1: 定義字符串
char str[] = "Hello World! 123";
Step 2: 遍歷字符數組,直到遇 \0
for (int i = 0; str[i] != '\0'; ++i) {// 每個字符處理
}
Step 3: 判斷小寫字母并轉換為大寫
if (str[i] >= 'a' && str[i] <= 'z') {str[i] = str[i] - ('a' - 'A'); // 或者 -32
}
完整函數
void to_uppercase(char* str) {for (int i = 0; str[i] != '\0'; ++i) {if (str[i] >= 'a' && str[i] <= 'z') {str[i] = str[i] - ('a' - 'A');}}
}
轉為小寫(相同邏輯,反方向)
void to_lowercase(char* str) {for (int i = 0; str[i] != '\0'; ++i) {if (str[i] >= 'A' && str[i] <= 'Z') {str[i] = str[i] + ('a' - 'A');}}
}
完整程序
#include <stdio.h>void to_uppercase(char* str) {for (int i = 0; str[i] != '\0'; ++i) {if (str[i] >= 'a' && str[i] <= 'z') {str[i] -= 32;}}
}void to_lowercase(char* str) {for (int i = 0; str[i] != '\0'; ++i) {if (str[i] >= 'A' && str[i] <= 'Z') {str[i] += 32;}}
}int main() {char str1[] = "Hello World!";char str2[] = "Hello World!";to_uppercase(str1);to_lowercase(str2);printf("Uppercase: %s\n", str1); // 輸出:HELLO WORLD!printf("Lowercase: %s\n", str2); // 輸出:hello world!return 0;
}
總結邏輯鏈
步驟 | 原理 |
---|---|
為什么能判斷大小寫 | ASCII 編碼連續且規范 |
為什么能轉換 | 字母大小寫之間固定差值 32 |
為什么能存空格/符號 | 只要不是 \0 ,都可以是字符串一部分 |
為什么能逐個訪問字符 | 字符串本質是字符數組 |
為什么知道終止 | 全靠 '\0' 終結符 |