C/ c++中的类型强制转换到底是什么?
What exactly is a type cast in C/C++?
C/c++中的类型强制转换到底是什么?编译器如何检查是否需要显式类型转换(并且有效)?它是否比较一个值所需的空间?例如:
int a;
double b = 15.0;
a = (int) b;
如果我没记错的话,双精度值比整数(4字节)需要更多的空间(是8字节吗?!)两者的内部表征是完全不同的(对两个/尾数的补充)。那么内部发生了什么呢?这里的例子非常简单,但是在C/c++中有很多类型转换。
编译器如何知道(或程序员),如果我可以转换例如FOO到BAR?
类型强制转换基本上是从一种类型到另一种类型的转换。它可以是隐式的(即,由编译器自动完成,可能在过程中丢失信息)或显式的(即,由开发人员在代码中指定)。字体所占的空间是次要的。更重要的是转换的适用性(有时是便利性)。
隐式转换可能丢失信息,可能丢失/获得符号,可能发生溢出/下溢。编译器不会保护您免受这些事件的影响,除非在编译时生成一个警告。当派生类型隐式转换为基类型(按值)时,也可能发生切片。
对于可能非常危险的转换(例如,从基类型到派生类型),c++标准要求显式强制转换。不仅如此,它还提供了更严格的显式强制转换,如static_cast
、dynamic_cast
、reinterpret_cast
和const_cast
,每个都进一步将显式强制转换限制为可能转换的一个子集,从而减少了强制转换错误的可能性。
有效的隐式和显式转换最终由C/c++标准定义,尽管在c++中,开发人员可以通过使用构造函数和重载(强制转换)操作符来扩展用户定义类型的隐式和显式转换。
标准允许哪些类型的强制转换以及不允许哪些类型的强制转换的完整规则可能会变得相当复杂。在这个回答中,我试图忠实地对其中一些规则做一个比较简明的总结。如果您真的对什么是允许的,什么是不允许的感兴趣,我强烈建议您访问标准并阅读有关类型转换的相应部分。
我想提一件经常被忽视的事情:
- 强制转换总是创建目标类型的临时对象(尽管如果目标类型是引用,您不会注意到)。
这可能很重要。例如:
#include <iostream>
void change_one_print_other( int& a, const int& b )
{
a = 0;
std::cout << b << "n";
}
int main(void)
{
int x = 5, y = 5;
change_one_print_other(x, x);
change_one_print_other(y, static_cast<int>(y));
}
那个cast看起来没用。但外表有时会骗人。
编译器知道如何隐式地执行某些类型强制转换——从double到int就是其中之一。它只是去掉了小数点部分。内部表示作为过程的一部分被转换,因此赋值工作正确。
请注意,有些值太大而无法正确转换。我不记得这种情况下的规则是什么;可由编译器自行决定。
为您的代码编写一个小C程序,并按照如何让GCC生成汇编代码中的说明来查看编译器如何进行类型强制转换。
- 是什么导致了这种使用三进制而不是短整型的有符号int到无符号int转换
- 从长整整转换为uint64_t的推荐方法是什么?
- C++:Lambda 函数指针转换的用例是什么?
- 将传入的网络"char*"数据转换为"uint8_t"并返回的安全方法是什么?
- 为什么此指针值不能转换为整数的规则是什么?
- 指针类型类成员的动态强制转换的恒定性是什么?
- 将QGyroscopeReading转换为QVector3D的正确方法是什么?
- 在C++中将uint64_t转换为void类型的目的是什么
- 在C++中,将无符号整数转换为八进制表示,反之亦然的最佳方法是什么
- 这个typedef和转换运算符语法是什么意思
- 是什么将程序集转换为实际可执行的材料
- 转换为非标量误差是什么意思?我该如何解决?
- 在 OpenGL 中计算矩阵时,转换的正确顺序是什么?
- 统一初始化是隐式发生的,即使 int 强制转换运算符是使用 explicit 关键字声明的.原因是什么?
- C++ 将字符串数据包转换为 iphdr语言 - 字符串数据包的格式应该是什么?
- 将 24 位".bmp"图像转换为黑白/单色图像的可能算法是什么?
- 将强制转换运算符重载到 std::map 的正确语法是什么
- 初始化中的模板转换运算符类型推导规则是什么?
- 在 C/C++ 中从双精度到int64_t的隐式转换是什么
- 在LPVOID返回时DWORD的类型强制转换是什么?