8.2 KiB
C++ 类型转换 讲义
1. 引言
- 字符的储存
字符
'A'在计算机底层又是用哪个数字存储的呢?计算机的本质是处理数字,我们看到的所有文本、字符,在它眼中都是一个个特定的数字。最著名的编码表就是 ASCII (美国信息交换标准代码),在书本P17页有部分的ASCII编码表可做参考。
2. 核心思想
自动类型转换
我们有一个整数 int number = 65;。我们想得到它对应的字符。一个想法是:C++ 那么聪明,我直接把 int 赋值给 char 会怎么样?其实在 C++ 中,char 和 int 可以自由转换和运算。
int number = 65;
char c = number; // C++ 允许这样做,它会自动转换
cout << c; // 输出 'A'
这种由编译器自动完成的转换,叫做 自动类型转化(隐式转换)。在很多简单场景下,它完全没有问题!但是,这种有时会隐藏一些问题。如果代码很复杂,其他人读到 char c = 65; 时,可能会疑惑:这是一个笔误吗?还是故意这么写的?为什么两边的数据类型不一样?
因为正常情况下,赋值符号的右边的数据类型应该和左边的变量数据类型相匹配。
但是有些情况也可以不一致。源类型向目标类型转换时(例子中 char c = number; 源类型就是 int , 目标类型是char)。如果源类型和目标类型不一致,在编译器知道怎么转换的情况下,会进行自动类型转换!
- 例如:
int赋给double是安全的(int转换为double)。 - 但请注意:
double赋给int时,虽然编译器会尝试转换(截断小数部分),但这通常被认为是不安全的,因为它会丢失精度(小数点后的数据没有了)。 - 整型和浮点型混合运算时,整型会向浮点型转换以避免数据丢失。核心原则是 “向高精度、大范围类型转换”,以避免数据丢失。例如,
int和double相加时,int会被转换为double。
==简单来说,C++的自动类型转换是尽力让你在不同的数据类型之间进行操作时,得到一个合理的结果,并且尽量不丢失数据。==
强制类型转换(推荐使用!) 为了让我们的代码意图更加清晰,我们常常需要强制类型转换。
这相当于我们明确地告诉编译器:我需要在这里把这个值的类型变一下!
在 C++ 中,==强制类型转换语法==是:
(目标类型) 变量名 或 数值
- 例1:要把变量
int number转换为char类型,我们就可以写:(char)number。 - 例2:要把变量
int number转换为double类型,我们就可以写:(double)number。
**请注意:**如果我们想对 a + b 这种==整个表达式的计算结果==进行转换时,就必须使用括号 () 将表达式完整地包裹起来,写成 (char)(a + b),以此来明确地告诉编译器:先算括号里的,再把算出来的最终结果进行转化!
而不能写成 (char)a + b,如果这样写,它会先把变量 a 转换为 char 类型。然后再去去和变量 b 相加。和我们的目的:将 a + b 的结果转化为 char 类型就不符了。
步骤拆解 使用强制类型转换将数字转为字符的步骤很简单:
- 准备一个整数:定义一个
int类型的变量,并存入一个在 ASCII 码范围内的数字。 - 执行转换:使用
(char)(你的整数变量)来进行转换。 - 存储结果:将转换后的结果赋值给一个
char类型的变量。 - 输出验证:打印输出这个
char变量,看看结果是否符合预期。
3. 实例
-
具体案例 让我们把数字
97转换为它对应的 ASCII 字符。 -
分步演示
- 准备一个整数:
int number = 97; - 执行转换:我们使用强制类型转换。
(char)number // 这个表达式的结果就是字符 'a' - 存储结果:
char res = (char)number; - 输出验证:
cout << res; // 屏幕上将会打印出 a
- 准备一个整数:
4. 代码实现
现在,让我们把上面的步骤整合起来,写一个完整的程序。这个程序的作用是输入一个数字,输出这个数字在ASCII 码表中对应的字符。
- 完整代码
#include <iostream>
using namespace std;
int main() {
cout << "请输入一个整数 (例如 65 到 90 之间): ";
// 定义变量并接收用户的输入
int number;
cin >> number;
// 使用强制类型转换
// 将 int 类型的 number 转换为 char 类型
char ascii_char = (char)number;
// 输出结果
cout << "数字 " << number << " 在 ASCII 码表中对应的字符是: " << ascii_char << endl;
return 0;
}
5. 验证
让我们用几个例子来测试一下我们的程序,看看会发生什么。
- 正常情况:
- 输入
65,输出'A'。 - 输入
97,输出'a'。 - 输入
48,输出'0'。
- 输入
- 常见问题
- 问:为什么不直接用
char c = number;? - 答:在简单情况下可以,但它属于自动类型转化转换,意图不明确。像
(char)number这样的强制转换,能让你的代码意图更清晰,一眼就能让人知道你是故意这样做的。 - 问:强制类型转换安全吗?
- 答:不一定。比方说:
double强制转换为int类型时,虽然编译器会转换(但是会截断小数部分)。所以,在转换前你要对数据的范围有的认识。例如你想转化一个整数到char字符类型,那就要确保这个整数的数值在ASCII码表中有对应的字符,如果这个数字根本不存在对应的字符,那计算机就也不知道应该如何转化了。
- 问:为什么不直接用
6. C++ 字符大小写转换(两种办法)
一:直接观察法
-
观察 ASCII 码表,你会发现一个规律:
'A'是 65,'a'是 97'B'是 66,'b'是 98- ...
'Z'是 90,'z'是 122
任意一个相同字母的小写形式,其 ASCII 码值都比大写形式大 32! (
'a' - 'A' = 97 - 65 = 32)基于这个规律,我们有实现方式:
-
==小写转大写==:
大写字符 = 小写字符 - 32 -
==大写转小写==:
小写字符 = 大写字符 + 32 -
案例:大小写转换
char upper = 'B'; char lower = upper + 32; // 66 + 32 = 98 ('b') cout << lower; // 输出 b
二:差值计算法:
例如想要将大写字符 'C'转为小写
-
计算偏移量:首先,我们需要知道目标字母
'C'相对于大写字母起点'A'的“位置”或“差值量”。- 这个偏移量可以通过减法计算得出:
'C' - 'A'。我们知道结果是2。这告诉我们,'C'是排在'A'后面的第2个字母(从0开始计数)。
- 这个偏移量可以通过减法计算得出:
-
找到新起点:我们的目标是小写字母,那么小写字母的“起点”是谁?是
'a'。 -
应用偏移量:我们在新的起点
'a'上,加上刚才计算出的差值量2,就能得到我们想要的小写字母。'a' + ('C' - 'A')'a' + 2--> 结果就是'c'。
- 公式:
- 大写转小写:
小写字母 = 任意大写字母 - 'A' + 'a' - 小写转大写:
大写字母 = 任意小写字母 - 'a' + 'A'
- 大写转小写:
总结
- 字符在计算机底层是以数字(如 ASCII 码)存储的。
char和int之间可以相互转换。- 使用
(目标类型)值的形式可以进行强制类型转换,这能让代码的意图更清晰。 - 进行类型转换时,要注意目标类型的取值范围,防止数据溢出,例如你想转化一个整数到
char字符类型,那就要确保这个整数的数值在ASCII码表中有对应的字符,如果这个数字根本不存在对应的字符,那计算机就也不知道应该如何转化了。 - 英文字母的大小写形式在 ASCII 码表中具有固定的数值差 (
32)。