热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[C++]类型转换

类型转换在C语言中,某些类型之间有关联,如果两种类型有关联,那么当程序需要其中一种类型的运算对象时,可以用另一种关联类型的对
类型转换

在C++语言中,某些类型之间有关联,如果两种类型有关联,那么当程序需要其中一种类型的运算对象时,可以用另一种关联类型的对象或值来替代。换句话说,如果两种类型可以相互转换,那么它们就是关联的。

例如

int ival = 3.14 + 3;
// 3.14 + 3 = 6 : double + int ~ double
// ival = 6 : double ~ int

何时发生隐式转换

1、在大多数表达式中,比int类型小的整型值首先提升为较大的整数类型

2、在条件中,非布尔值转换成布尔类型

3、初始化过程中,初始值转换成变量的类型;在赋值语句中,右侧运算对象转换成左侧运算对象的类型。

4、如果算术运算或关系运算的运算对象有多种类型,需要转换成同一种类型。

5、函数调用时也会发生类型转换

算术转换

算术转换的含义是把一种算术类型转换成另外一种算术类型,

其中:运算符的运算对象将转换成最宽的类型;当表达式中既有浮点类型也有整数类型时,整数值将转换成相应的浮点类型

整型提升

整型提升负责把小整数类型转换成较大的整数类型。要求转换后的类型要能容纳原类型所有可能的值

无符号类型的运算类型

如果某个运算对象的类型是无符号类型,那么转换的结果就要依赖于机器中各个整数类型的相对大小

首先要进行整型提升,如果带符号的类型不大于无符号的类型,然后对于有符号的数转换成无符号的数。如果带符号的类型大于无符号的类型,那么转换的结果依赖于机器。

其他隐式类型转换 数组转换成指针

数组是自动转换成指向数组首元素的指针

int ia[10];
// 含有10个整数的数组
int* p = ia;
// ia转换成指向数组首元素的指针

decltype、&、sizeof、typeid等运算符操作时,上述转换不会发生

如果用一个引用来初始化数组,上述转换也不会发生。

指针的转换

常量整数值或字面值nullptr能转换成任意指针类型

指向任意非常量的指针能转换成void*

指向任意对象的指针能转换成const void*

还存在继承类型关系间的指针转换

转换成布尔类型

如果指针或算术类型的值为0,转换结果是false。

转换成常量

允许将指向非常量类型的指针转换成指向相应的常量类型的指针,对于引用也是这样。

如果T是一种类型,我们就能将指向T的指针或引用分别转换成指向const T的指针或引用。

int i;
const int &j = i;
// 非常量转换成const int的引用
const int *p = &i;
// 非常量的地址转换成const的地址
int &r = j, *q = p;
// 错误,不允许const转换成非常量

相反的转换不存在,因为它试图删除掉底层const

类类型定义的转换

类类型能定义由编译器自动执行的转换,不过编译器每次只能指向一种类类型的转换。

string s, t = "a value";
// 字符串字面值转换成string类型

显式转换

显式将对象强制转换成另外一种对象

强制类型转换如浮点数除法,

int i, j;
double slope = i / j;
// 将i和/或j显式转换成double

命名的强制类型转换

cast-name(expression);

type: 转换的目标类型

expression: 要转换的值

如果type是引用类型,则结果是左值。

cast-name: static_cast、dynamic_cast、const_cast、reinterpret_cast

static_cast

任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast

double slope &#61; static_cast<double>(j) / i;
// 进行强制类型转换以便执行浮点数除法

当需要把一个较大的算术类型赋值给较小的类型时&#xff0c;static_cast非常有用

如果不使用static_cast则会给出警告信息&#xff0c;

static_cast对于编译器无法自动执行的类型转换非常有用

可以用static_cast找回存在于void*指针中的值。

void* p &#61; &d;
// 任何非常量对象的指针都能存入void*double *dp &#61; static_cast<double*>(p);
// 正确&#xff0c;将void*转换回初始的指针类型

在转换时要确保指针的值保持不变&#xff0c;也就是说强制转换的结果将与原始的地址值相等。

const_cast

const_cast只能改变运算对象的底层const

const char *pc;
char *p &#61; const_cast<char*>(pc);

对于常量对象转换成非常量对象的行为&#xff0c;我们一般称为去掉const性质。

如果对象本身不是一个常量&#xff0c;使用强制类型转换获得写权限是合法的行为

如果对象本身是一个常量&#xff0c;使用强制类型转换执行写操作就会产生未定义的后果。

const char *cp;
char *q &#61; static_cast<char*>(cp);
// 错误&#xff0c;static_cast不能转换掉const性质
static_cast<string>(cp);
// 正确&#xff1a;字符串字面值传换成string类型
const_cast<string>(cp);
// 错误&#xff1a;const_cast只改变常量属性

reinterpret_cast

reinterpret_cast常为运算对象的位模式提供较低层次上的重新解释

int *ip;
char *pc &#61; reinterpret_cast<char*>(ip);
// pc所指的真实对象是一个int而非字符&#xff0c;如果把pc当作普通的字符指针使用就可能在运行时发生错误
string str(pc);
// 导致异常

 

转:https://www.cnblogs.com/immjc/p/8044220.html



推荐阅读
  • C语言自带的快排和二分查找
    Author🚹:CofCaiEmail✉️:cai.dongjunnexuslink.cnQQ😙:1664866311personalPage&#x ... [详细]
  • 利用空间换时间减少时间复杂度以及以C语言字符串处理为例减少空间复杂度
    在处理字符串的过程当中,通常情况下都会逐个遍历整个字符串数组,在多个字符串的处理中,处理不同,时间复杂度不同,这里通过利用空间换时间等不同方法,以字符串处理为例来讨论几种情况:1: ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 电话号码的字母组合解题思路和代码示例
    本文介绍了力扣题目《电话号码的字母组合》的解题思路和代码示例。通过使用哈希表和递归求解的方法,可以将给定的电话号码转换为对应的字母组合。详细的解题思路和代码示例可以帮助读者更好地理解和实现该题目。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • Ihaveaworkfolderdirectory.我有一个工作文件夹目录。holderDir.glob(*)>holder[ProjectOne, ... [详细]
  • node.jsrequire和ES6导入导出的区别原 ... [详细]
  • 本文详细介绍了在Linux虚拟化部署中进行VLAN配置的方法。首先要确认Linux系统内核是否已经支持VLAN功能,然后配置物理网卡、子网卡和虚拟VLAN网卡的关系。接着介绍了在Linux配置VLAN Trunk的步骤,包括将物理网卡添加到VLAN、检查添加的VLAN虚拟网卡信息以及重启网络服务等。最后,通过验证连通性来确认配置是否成功。 ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了VoLTE端到端业务详解|VoLTE用户注册流程相关的知识,希望对你有一定的参考价值。书籍来源:艾怀丽 ... [详细]
author-avatar
手机用户2502862793
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有