目录
第一性问题:什么是“大小写”?
逐步构造代码:全部转为大写
我们现在用 第一性原理 的方式,从字符串与字符的本质出发,一步步推导出如何在 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' 终结符 |