
🔥个人主页:艾莉丝努力练剑 ❄专栏传送门:《C语言》、《数据结构与算法》、C语言刷题12天IO强训、LeetCode代码强化刷题、C/C++干货分享&学习过程记录 🍉学习方向:C/C++方向 ⭐️人生格言:为天地立心,为生民立命,为往圣继绝学,为万世开太平
前言:本专栏记录了博主C++从初阶到高阶完整的学习历程,会发布一些博主学习的感悟、碰到的问题、重要的知识点,和大家一起探索C++这门程序语言的奥秘。这个专栏将记录博主C++语法、高阶数据结构、STL的学习过程,正所谓“万丈高楼平地起”嘛,我们话不多说,继续进行C++阶段的学习。本文我们不讲C++主线的内容,我们来拓展一下或者说整理一下我们学习时C/C++时经常会提到的一些专有名词,例如形参、实参,显式类型转换和隐式类型转换类型转换,内置类型等等。

C++的两个参考文档:
老朋友(非官方文档):cplusplus 官方文档(同步更新):cppreference
在C语言中,类型转换分为显式类型转换和隐式类型转换两种方式。C++ 也支持这些 C 风格的转换,但推荐使用更安全的 C++ 风格类型转换操作符。
隐式类型转换,又称自动类型转换,是编译器在不需要程序员显式指定的情况下自动进行的类型转换。
int i = 42;
double d = i; // 隐式将int转换为double
float f = 3.14f;
double sum = f + d; // 隐式将f提升为double
void func(double x);
func(i); // 隐式将int转换为double1、小类型向大类型转换;
2、整型向浮点型转换;
3、有符号向无符号转换(可能导致意外结果)。
1、char、short 等小整型在运算时自动提升为 int。
使用强制类型转换运算符显式指定转换。
(type_name) expression
// 或
type_name (expression) // C++ 中可用我们举个例子:
double d = 3.14159;
int i = (int)d; // 显式将double转换为int,截断小数部分
float f = 1.5f;
int j = int(f); // C++风格的写法,效果相同
unsigned int u = 0xffffffff;
int k = (int)u; // 可能产生负数注意:
1、强制转换会绕过编译器的类型检查;
2、可能导致数据丢失或未定义行为;
3、指针类型转换非常危险。
int x = 10;
char *p = (char *)&x; // 危险:可能违反严格别名规则C++ 提供了四种更安全的类型转换操作符:
1、static_cast—— 用于良性转换2、const_cast—— 去除 const 属性3、dynamic_cast—— 用于多态类型的向下转换4、reinterpret_cast—— 低层重新解释(最危险)
double d = 3.14;
int i = static_cast<int>(d); // C++推荐方式static_cast 等新式转换;
隐式类型转换又称自动类型转换,是编译器在不需要程序员显式指定的情况下自动进行的类型转换。
当表达式中包含不同类型的操作数时发生:
int i = 5;
double d = 2.5;
double result = i + d; // i被隐式转换为double当赋值运算符两侧类型不一致时:
int i;
double d = 3.14;
i = d; // d被隐式转换为int,小数部分被截断实参与形参类型不匹配时:
void func(double x);
func(5); // int 5被隐式转换为double 5.0返回类型与函数声明类型不一致时:
double func()
{
return 5; // int 5被隐式转换为double 5.0
}char、short等小整型自动提升为int
char c1 = 'A', c2 = 'B';
int result = c1 + c2; // char提升为int再相加按以下优先级转换(低→高):
bool、char、short → int
int → unsigned int
unsigned int → long
long → unsigned long
unsigned long → long long
long long → unsigned long long
float
float → double
double → long double
unsigned int u = 10;
int i = -5;
if (i < u)
{ // i被转换为unsigned int,结果可能出乎意料
// 这里可能不会执行
}int i = 300;
char c = i; // 可能溢出,结果依赖于实现显式类型转换是程序员明确指定的类型转换,也称为强制类型转换。
语法:
(type_name) expression
// 或
type_name (expression) // C++风格double d = 3.14159;
int i = (int)d; // 截断小数部分,i=3int x = 10;
char *p = (char *)&x; // 重新解释内存void (*func_ptr)() = (void (*)())some_function;C++提供了四种更安全的转换操作符——
用于良性转换,编译时检查:
double d = 3.14;
int i = static_cast<int>(d);移除const/volatile属性:
const int ci = 10;
int *pi = const_cast<int*>(&ci);用于多态类型的安全向下转换:
Base* b = new Derived();
Derived* d = dynamic_cast<Derived*>(b);低层重新解释,最危险:
int i = 10;
float f = reinterpret_cast<float&>(i);double d = 3.9;
int i = (int)d; // i=3,小数部分丢失int x = 0x12345678;
char *p = (char *)&x;
if (*p == 0x78)
{
// 依赖于字节序
// 在小端机器上成立
}float f = 3.14f;
unsigned u = *(unsigned *)&f; // 违反严格别名规则static_assert(sizeof(int) == 4, "int must be 4 bytes");1、以下代码的输出是什么?
unsigned int u = 10;
int i = -5;
if (i < u)
{
printf("True");
}
else
{
printf("False");
}答案:可能输出"False"(因 i 被转换为很大的unsigned值)。
2、如何安全地将float的位模式转换为int?
float f = 3.14f;
int i;
memcpy(&i, &f, sizeof(f)); // 安全方式往期回顾:
由于往期回顾的博客太多了,这里就只放前一篇博客的链接啦——
关于C++的四种强制转换类型,大家可以去看这位大佬的博客,比较易懂——
【C++】深度解析C++的四种强制转换类型(小白一看就懂!!)
往期回顾(本文涉及的一些往期博客)
C风格的强制类型转换:
【C/C++】初识C++(三):C++入门内容收尾——const引用,指针和引用关系梳理,inline(内联函数),nullptr替代NULL
C语言中的强制类型转换:
变量的一些知识点整理(续)、算术操作符、赋值操作符:=和复合赋值、单目操作符以及强制类型转换的知识点总结
结语:本文内容到这里就全部结束了。本文博主带大家回顾了介绍C语言时就登场,一直到现在都有不少戏份的强制类型转换,C++中具有C风格的强制类型转换:显式类型转换、隐式类型转换。