梦想不会自己发光,真正闪耀的是那个为梦狂奔的你。献给知行的孩子们!(Eric.He著)
本教程将从 C++ 类型转换的核心规则、自动类型转换(混合运算/赋值)到强制类型转换,全面拆解 C++ 类型转换的核心用法,帮助你掌握这一基础且重要的编程知识点。
C++ 中的类型转换是指将一种数据类型的值转换为另一种数据类型的值,分为隐式转换(自动类型转换)和显式转换(强制类型转换):
自动类型转换的核心原则是「低精度 → 高精度」(避免数据丢失),C++ 基本数据类型的精度层级(从低到高):
bool → char → short → int → long → long long → float → double → long double
注:精度越高,能表示的数值范围越大、小数精度越高;自动转换时,低精度类型会向高精度类型靠拢。
当不同数据类型的变量/常量参与算术运算(+、-、*、/、% 等)时,编译器会先将所有操作数转换为同一类型,再进行运算,核心规则:
long double,其他操作数转换为 long double;double,其他操作数转换为 double;float,其他操作数转换为 float;long long → long → int → short → char → bool;bool 参与运算时,true 转换为 1,false 转换为 0;char/unsigned char 参与运算时,自动转换为 int(ASCII 码值)。
#include <iostream>
using namespace std;
int main() {
// 示例1:int + double → 全部转为double运算
int a = 10;
double b = 3.14;
double res1 = a + b; // a(10) → 10.0(double),运算结果:13.14
cout << "10 + 3.14 = " << res1 << endl;
// 示例2:char + int → char转为int(ASCII码)
char c = 'A'; // ASCII码为65
int d = 5;
int res2 = c + d; // 'A'(65) + 5 = 70
cout << "'A' + 5 = " << res2 << " (对应字符:" << (char)res2 << ")" << endl;
// 示例3:bool + float → bool转为int,再转为float
bool flag = true; // true → 1
float f = 2.5f;
float res3 = flag + f; // 1 → 1.0f + 2.5f = 3.5f
cout << "true + 2.5f = " << res3 << endl;
return 0;
}
输出结果:
10 + 3.14 = 13.14
'A' + 5 = 70 (对应字符:F)
true + 2.5f = 3.5
当赋值运算符 = 左右两侧类型不同时,右侧值的类型会转换为左侧变量的类型,再赋值给左侧变量,规则:
true,0值转为 false;
#include <iostream>
using namespace std;
int main() {
// 示例1:高精度→低精度(小数截断)
double num1 = 3.99;
int num2 = num1; // 3.99 → 3(小数部分丢失)
cout << "double(3.99) → int: " << num2 << endl;
// 示例2:低精度→高精度(无丢失)
int num3 = 100;
double num4 = num3; // 100 → 100.0
cout << "int(100) → double: " << num4 << endl;
// 示例3:数值→布尔
int num5 = 0;
bool flag1 = num5; // 0 → false
bool flag2 = -5; // 非0 → true
cout << "0 → bool: " << boolalpha << flag1 << endl;
cout << "-5 → bool: " << boolalpha << flag2 << endl;
// 示例4:数值→字符(ASCII码)
int num6 = 65;
char ch = num6; // 65 → 'A'
cout << "int(65) → char: " << ch << endl;
// 示例5:溢出风险(高精度→低精度)
long long bigNum = 1000000;
short smallNum = bigNum; // 数值溢出,结果不可控
cout << "long long(1000000) → short: " << smallNum << endl;
return 0;
}
输出结果:
double(3.99) → int: 3
int(100) → double: 100
0 → bool: false
-5 → bool: true
int(65) → char: A
long long(1000000) → short: 16960 // 溢出后结果(不同环境可能不同)
当自动类型转换无法满足需求(或需要主动控制转换规则)时,需使用强制类型转换,分为 C 风格和 C++ 风格两种语法。
语法简单、通用性强,但缺乏类型检查,风险较高,语法格式:
// 格式1:(目标类型) 表达式
(目标类型) 变量/常量/表达式;
// 格式2:目标类型 (表达式)
目标类型 (变量/常量/表达式);
// 格式3:(目标类型) (表达式)
(目标类型) (变量/常量/表达式);
#include <iostream>
using namespace std;
int main() {
// 示例1:强制转换小数为整数(截断)
double pi = 3.1415926;
int pi_int = (int)pi; // 3.1415926 → 3
cout << "(int)3.1415926 = " << pi_int << endl;
// 示例2:强制转换整数为字符
int ascii = 97;
char ch = char(ascii); // 97 → 'a'
cout << "char(97) = " << ch << endl;
// 示例3:强制转换浮点数除法为整数除法
double res1 = 7 / 2; // 自动转换:int/int=3 → 3.0
double res2 = (double)7 / 2; // 强制转换7为double,结果3.5
cout << "7/2 = " << res1 << endl;
cout << "(double)7/2 = " << res2 << endl;
return 0;
}
输出结果:
(int)3.1415926 = 3
char(97) = a
7/2 = 3
(double)7/2 = 3.5
C++ 提供了4种更安全、更具语义的强制类型转换运算符,替代C风格转换,降低类型错误风险:
| 转换运算符 | 用途 | 适用场景 |
|---|---|---|
static_cast<目标类型> |
静态类型转换 | 基本数据类型转换、父子类指针/引用转换(无多态)、void* 与其他指针转换 |
const_cast<目标类型> |
常量性转换 | 移除/添加变量的 const 修饰符 |
reinterpret_cast<目标类型> |
重解释转换 | 不同类型指针/引用间的强制转换(如int* → char*),底层二进制重解释 |
dynamic_cast<目标类型> |
动态类型转换 | 多态场景下的父子类指针/引用转换(运行时类型检查,失败返回nullptr) |
#include <iostream>
using namespace std;
int main() {
// 1. static_cast:基本类型转换(推荐替代C风格)
double num1 = 5.88;
int num2 = static_cast<int>(num1);
cout << "static_cast<int>(5.88) = " << num2 << endl;
// 2. const_cast:移除const修饰
const int num3 = 100;
int* pNum = const_cast<int*>(&num3);
*pNum = 200; // 注意:修改const变量的行为未定义,仅演示语法
cout << "const_cast修改后:" << num3 << endl;
// 3. reinterpret_cast:指针类型重解释
int num4 = 0x616263; // 十六进制对应字符 'a','b','c'
char* pCh = reinterpret_cast<char*>(&num4);
cout << "reinterpret_cast<int*>→char*: " << pCh << endl;
// 4. dynamic_cast(简单演示,多态场景更常用)
class Base { virtual void func() {} };
class Derived : public Base {};
Base* pBase = new Derived();
Derived* pDer = dynamic_cast<Derived*>(pBase);
if (pDer != nullptr) {
cout << "dynamic_cast转换成功" << endl;
} else {
cout << "dynamic_cast转换失败" << endl;
}
delete pBase;
return 0;
}
输出结果(参考):
static_cast(5.88) = 5 const_cast修改后:100 // 不同编译器可能输出200(未定义行为) reinterpret_cast →char*: cba dynamic_cast转换成功
static_cast 是最常用的C++转换方式,仅支持「相关类型」转换(如数值类型间、父子类间),拒绝无意义转换(如int* → double);const_cast 仅能修改变量的const属性,不能改变类型,滥用会导致未定义行为;reinterpret_cast 是最危险的转换方式,直接操作二进制,跨平台兼容性差,仅在底层编程时使用;dynamic_cast 仅支持含虚函数的类(多态类),转换失败时指针返回nullptr,引用抛出异常;(double)a / b),保证计算精度;dynamic_cast)、移除const限制(const_cast);reinterpret_cast 转换指针类型,操作二进制数据;static_cast/dynamic_cast等),语义更清晰、类型检查更严格,便于代码维护;本教程从 C++ 类型转换的核心规则、自动转换到强制转换,全面拆解 C++ 类型转换的核心用法。掌握类型转换的规则和风险,是学习C++编程的重要基础之一。