C++类型转换
类型转换
在C++中,某些类型之间是有关联的。如果两种类型有关联,那么当程序需要其中一个类型的运算对象时,可以用另一种关联类型的对象或值来替代。即如果两种类型可以相互转换,那么它们就是关联的。
**隐式转换:**类型的自动转换,由编译器做,不需要程序员插手。
发生隐式类型转换的几种情况:
1、在大多数表达式中,比int类型小的整型值首先提升为较大的整数类型。
2、在条件中,非布尔值转换为布尔类型。
3、在初始化过程中,初始值转换成变量的类型;在赋值语句中,右侧运算对象转换成左侧运算对象的类型。
4、如果算术运算或关系运算的运算对象有多种类型,需要转换为同一种类型。
5、函数调用时也会发生类型转换。
算术转换
**算术转换:**把一种算术类型转换为另一种算术类型。例如有一个运算对象的类型为long double,则另一个运算对象不管是什么类型的都转换为long double;当表达式中既有浮点类型也有整数类型时,整数值类型将转换为相应的浮点数。
**整形提升:**将小整数类型转换为较大的整数类型。
例如bool,char,signed char,unsigned char,short和unsigned short等类型,只要它们存在int里,它们就会被提升为int类型;否则提升为unsigned int类型,布尔值false提升为0,true提升为1。
再例如较大的char类型(wchar_t,char16_t,char32_t)提升为int,unsigned int,long,unsigned long,long long和unsigned long long中最小的一种类型。
**无符号类型的运算对象:**如果运算对象中存在无符号类型,转换为机器中的整型
如果一个运算对象是无符号类型的,另一个运算对象是带符号类型的,而且无符号类型大于等于带符号类型,那么**带符号类型对象转换为无符号的。**例如unsigned int和int类型,int类型为负数时,int类型转换为unsigned int类型(2的32次方取模)。
带符号类型大于无符号类型,转换结果依赖于机器。如果无符号类型都能存在带符号类型中,则无符号类型转换为有符号类型。如果不能,则带符号类型转换为无符号类型。
理解算术类型:多研究研究例子就行了。
隐式类型转换
**数组转换为指针:**在大多数用到数组的表示式中,使用数组名会自动转换为指向数组首元素的指针
当数组使decltype关键的参数,以及作为取地址符(&)、sizeof及typeid等运算的运算对象,使用引用初始化数组,上述转换不会发生。
**指针的转换:**常量值0或者字面值nullptr能转换为任意指针类型;指向任意非常量的指针能转换为void *;指向任意对象的指针能转换成const void *。
**转换为布尔类型:**如果指针或算术类型的值为0,转换结果为false,否则转换结果为true。
**转换成常量:**允许在指针和引用前面加底层const
**类类型定义的转换:**类类型能定义由编译器自动执行的转换。
4.11.3 显式转换
1、命名的强制类型转换
**形式:**cast_name(expression)
type是要转换的目标类型而expression是要转换的值。如果type是引用类型,则结果是左值。cast_name是static_cast,dynamic_cast,const_cast,reinterpret_cast中的一种。
**static_cast:**任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast
//将对象i强制类型转换为浮点数以便执行浮点数除法
double slope=static_cast<double>(i)/j;
static_cast也可以对编译器无法自动执行的类型进行使用,例如用static_cast找回void *指针中的值
void *p=&d; //正确:任何非常量对象的地址都能存入void *
double *dp=static_cast<double*>p;//正确:将void*转换为double*类型
强制类型转换后的所得到的类型必须要和指针所指的类型相同,否则将产生未定义的后果。
**const_cast:**只能改变运算对象的底层const
const char *pc;
char *p=const_cast<char*>(pc);//正确:但是不同通过p进行写操作(进行写操作就会产生未定义的后果)
对于将常量对象转换成非常量对象的行为,一般称为**“去掉const性质”**。
如果对象本身不是一个常量,使用强制类型转换获得写操作是合法的。
如果对象本身是一个常量,则使用cast_const执行写操作就会产生未定义的结果。
只有const_cast能改变表达式的常量属性(不能改变表达式的其他类型),使用其他类型的命名强制类型转换表达式的常量属性是错误的。即const_cast只能改变常量属性。
**reinterpret_cast:**通常为运算对象的位模式提供低层次上的重新解释
**总结:**使用reinterpret_cast是非常危险的,因为它在本质上依赖于机器。要想安全的使用,必须对涉及的类型和编译器实现转换的过程都非常了解。(跳过吧,太坑了)
**建议:**避免强制类型转换。
2、旧式的强制类型转换:
type(expr); //函数形式的强制类型转换
(type)expr; //c语言风格的强制类型转换
旧式的强制类型转换分别与const_cast,static_cast或reinterpret_cast有想似的行为。
- 身份证号码验证算法
- JS读书心得:《JavaScript框架设计》——第12章 异步处理
- 被解放的姜戈04 各取所需
- PLT:说说Evaluation strategy
- 被解放的姜戈06 假作真时
- idea 创建的maven+spring+mybatis项目整合 报错无法创建bean
- 代数几何:点,线,抛物线,圆,球,弧度和角度
- 被解放的姜戈05 黑面管家
- 用数据来告诉你2018年的未来趋势
- JavaWeb(三)JSP之3个指令、6个动作、9个内置对象和4大作用域
- 被解放的姜戈03 所谓伊人
- JS魔法堂: Native Promise Only源码剖析
- JavaWeb(三)JSP概述
- 人工智能拥有意识,仅是一个时间问题而已
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 萌新不看会后悔的C++基本类型总结(一)
- 2019 ICPC 银川网络赛 D. Take Your Seat (疯子坐飞机问题)
- 2019 ICPC 银川网络赛 H. Fight Against Monsters
- 状态压缩DP(大佬写的很好,转来看)
- 2019 ICPC 银川网络赛 F-Moving On (卡Cache)
- 树形结构--二叉树的遍历算法应用(十九)
- POJ1088 滑雪题解+HDU 1078(记忆化搜索DP)
- 2019 ICPC 南京网络赛 F Greedy Sequence
- 补题Codeforces 1102E. Monotonic Renumeration
- 2019 ICPC 南京网络赛 H-Holy Grail
- 写代码?程序猿?你不能不懂的八大排序算法的Python实现
- Java开发编程规范:5.集合处理
- codeforce 272E Dima and Horses (假DFS)
- 网速慢?NO可能是路由器的原因?
- codeforce 272B Dima and Sequence