表达式求值或赋值时,值可能从一种类型变为另一种。C++ 在算术、函数传参等处会发生隐式转换;需要写明意图时,应使用命名转换(如 static_cast),而不要写成 C 语言类型转换里常见的 (int)x:那种括号写法把数值转换、指针转换等几种操作混在一起,读起来不易分辨。本节结合基本类型,请注意以下三点:两个整数相除会丢掉小数;把浮点赋给整数会截断而不是四舍五入;文本与数字之间用 stoi / to_string 互转。
整数除法与显式提升
两个 int 相除结果仍是整数,小数部分丢弃。需要商为浮点时,至少将一侧转为 double:
#include <iostream>
int main() {
int a = 5, b = 2;
std::cout << (a / b) << "\n";
std::cout << (static_cast<double>(a) / b) << "\n";
int truncated = 3.9;
std::cout << truncated << "\n";
return 0;
}输出:
2
2.5
3浮点赋给整型会截断,不是四舍五入。列表初始化 int x{3.9}; 不允许这种丢掉小数的赋值(常称为窄化),因而无法通过编译,见变量与类型。
隐式转换常见情形
- 较小整数参与运算时常提升为
int。 - 整型与
double混合时,整型转为double。 - 条件中:算术零为假,指针空为假。
混合类型表达式宜加括号并显式写出意图,避免读者以为得到 2.5 而实际是整数 2。
命名转换(入门)
| 形式 | 典型用途 |
|---|---|
static_cast | 数值互转、层次明确的指针转换 |
const_cast | 去掉或加上 const(慎用) |
dynamic_cast | 多态向下转型,见多态 |
reinterpret_cast | 底层位模式,仅系统级代码 |
文本与数字之间不要靠 static_cast:用 std::stoi / std::to_string(头文件 <string>)。失败时 stoi 抛异常,见异常处理。
#include <iostream>
#include <string>
int main() {
std::string s = std::to_string(42);
int n = std::stoi("17");
std::cout << s << " " << n << "\n";
return 0;
}输出 42 17。stoi 从字符串开头解析整数,后面可跟非数字字符;空串或无法解析时抛 std::invalid_argument,数值过大抛 std::out_of_range。
有符号与无符号
int 与 unsigned 混合运算时,通常把有符号操作数转为无符号。负数一旦按无符号解释,会变成很大的正值,循环条件 i < u 在 i 为有符号、 u 为无符号时容易写错。比较或做差前应统一类型,或把容器 size() 的结果赋给 std::size_t 再比较。
本节归纳了隐式转换、static_cast 以及文本与整数的互转。下一章从运算符与表达式开始。