表达式求值或赋值时,值可能从一种类型变为另一种。C++ 在算术、函数传参等处会发生隐式转换;需要写明意图时,应使用命名转换(如 static_cast),而不要写成 C 语言类型转换里常见的 (int)x:那种括号写法把数值转换、指针转换等几种操作混在一起,读起来不易分辨。本节结合基本类型,请注意以下三点:两个整数相除会丢掉小数;把浮点赋给整数会截断而不是四舍五入;文本与数字之间用 stoi / to_string 互转。

整数除法与显式提升

两个 int 相除结果仍是整数,小数部分丢弃。需要商为浮点时,至少将一侧转为 double:

C++ static_cast 与整数除法运行
#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 以及文本与整数的互转。下一章从运算符与表达式开始。