C/C++中奇妙的类型转换
1.引言
大家在学习C语言的时候,有没有遇见过类似于下面这样的代码呢?
// 整形转bool
int count = 10;
while(count--)
{cout << count << endl;
}// 指针转bool
int* ptr = cur;
while(ptr)
{//……
}
众所周知,while循环的判断是bool类型的变量,那为什么整形变量和指针变量可以直接作为 while循环的判断条件呢?之所以可以这样直接利用整形变量和指针变量作为while循环的判断条件,是不是说明整形类型的变量和指针类型的变量可以转换成bool类型呢?没错,是的。
大家在学习编程的过程中肯定都有遇到过各种各样的 “神奇的” 类型转换,这些类型转换给我们编程带来了很大的方便,比如说 上面的整形直接转bool值判断、指针直接转bool值判断等等……下面我们就一起来学习一下C/C++中的那些神奇的类型转换。
提醒:所有的类型转换之间要有关联,没有关联的类型之间即使是强制类型转换,也是不能转换的。
2.C语言中的那些类型转换
在C编写C/C++代码的时候,我们经常会遇到发生类型转换的场景,比如 赋值运算符的两个操作数不同、实参和形参类型不同、函数返回值类型和接收返回值的类型不同,都会发生类型转换;所以,在C语言中提供了两种类型转换 —— 隐式类型转换和显示类型转换
隐式类型转换
隐式类型转换是隐式的,是我们看不见的,比如下面这段代码:
double a = 1.0;
int b = a; // 发生隐式类型转换
隐式的类型转换有以下几种:
- 1.整形和整形之间:不同的整形之间是可以发生隐式类型转换的,比如:char,short,int,long 、long long之间(char是属于整形家族的哦!)。
- 2.整形和浮点型之间:整形和浮点型数据之间也具有一定的关联性,也是可以发生隐式类型转换的,比如:int 和 double,int 和 float 类型的数据……
- 3.整形和bool之间:因为在编程中,我们习惯用0表示假,非0表示真,所以整形和bool型的数据是可以相互转换的。
- 4.指针和bool之间:指针有可以分为空指针和非空指针,相当于0和非0,所以指针类型的数据也是可以和bool型之间的数据进行转换的。
显示类型转换
显示类型转换式可以看见的,是用户显示使用的,比如下面这段代码:
int main(){int c = 0;char* pc = (char*)&c;return 0;
}
显示的类型转换有以下几种:
- 整形和指针类型之间:这两者之间可以转换是因为指针是进程地址空间中字节的编号,和整形数据之间还是具有关联性的,所以可以互相转换。
- 不同类型的指针变量之间:之所以可以互相转换,和上面一点是相同道理的;但是指针的类型决定了指针解引用之后,可以访问的内存地址字节数的大小(比如说,int*类型的指针解引用之后,可以访问四字节的内存空间,char*类型的指针解引用之后,只能访问1字节的内存空间;这是由指针所指向的数据的类型决定的)。有了这个点,其实所有类型的对象之间都能间接转换了,但是解引用之后所能访问的内存空间大小不一样。
3.C++中的那些类型转换
为什么C++还要改进类型转换呢?
我们都知道,C++是对C的改进和扩充,C++不仅仅改进了C语言中的错误处理机制,还改进了C语言中的类型转换。相信你可能有这样的疑问,C语言中的类型转换挺好用的,那为什么还要改进呢?看下面这段代码:
#include <iostream>
using namespace std; void func(size_t pos)
{int end = 10;while (end >= pos){cout << end << endl;--end;}
}int main()
{func(0);return 0;
}
大家可以猜一猜上面这段程序运行的结果是什么?结果如图:
- 出乎意料吧,程序的结果是死循环;这是因为,end 和 pos是不同类型的数据,相互比较时会发生隐式的类型转换,范围小的会向范围大的数据类型转换,所以end会转换为无符号数,无符号数中没有负数,所以比较的时候,end总是大于pos,导致死循环。
从上面这个案例可以看出,C语言中的类型转化可视性比较差,可能存在难以预料的风险,所以C++的前辈们觉得有必要对类型转换升级升级了。
C++中的类型转换
C++语言中引入了面向对象的思想,提供了继承机制,所以多多少少都会涉及父类和子类之间的转换,这是C语言中的类型转换不能很好的解决的问题之一;再者,C语言中的类型转换可视性较差,所以C++中为了加强类型转换的可视性和可控性,提供了四种类型转换操作符,分别是 static_cast、reinterpret_cast、const_cast、dynamic_cast;
static_cast:static_cast 操作符对应C语言中的隐式类型转换,使用方式如一下代码,加强了隐式类型转换的可视性。
int main()
{double a = 3.14;int b = static_cast<int>(a);return 0;
}
reinterpret_cast:reinterpret_cast 操作符对应C语言中的强制类型转换,使用方式如下,以前使用强制类型转换的地方就可以这样使用了。
int main()
{int a = 0;int* p = reinterpret_cast<int*>(a);return 0;
}
const_cast:const_cast 操作符用于强制类型转换中,去掉const属性。去掉变量的const属性的这种强制类型转换存在一定的内存可视化风险,虽然强制类型转换也可以去掉const属性,但是可视性较差,不便于分析程序。

- 分析上面的代码可以得出,a变量并没有被重新赋值,但是*p指向的空间被重新赋值了,但是*p指向的不就是变量a吗?为什么会出现这样的现象呢?这是因为,编译器认为a是const修饰的,是不会改变的变量,所以在寄存器上存放了一份a,这样一来,当需要使用a变量的时候,直接就可以去寄存器上面取,提高程序的运行效率,*p = 3;改变的是内存空间中a的值,打印的时候,a是在寄存器中取的值,*p是在内存空间中取的值,所以两个值不一样。

- 分析上面代码可以看出给 const 修饰的变量添加volatile关键字,答应出的结果在意料之中,这是因为,volatile关键字表明,不把该 const 修饰的变量 a 放在寄存器中,所以不会出现上面那种情况。
dynamic_cast:dynamic_cast操作符用于支持向下转换,也就是将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换);dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0;dynamic_cast只能用于父类含有虚函数的类,这是因为,dynamic_cast的实现和虚函数表有关,要想有虚函数表,类中得有虚函数。

- 如上图左侧所示,如果父类的指针指向子类对象,该父类的指针是可以转化成子类的指针的,因为可以看到本来就属于它的空间
- 如上图右侧所示,如果父类的指针指向父类对象,该父类的指针是不能转化为子类的指针的,因为会导致解引用之后,该指针的步长变大,访问本来就不属于它的空间。
- 总结一下就是子类的指针or引用or对象,是可以直接转换成父类的指针or引用or对象(赋值兼容转换规则),但是父类的指针or引用需要通过dynamic_cast操作符类进行转换,如果能转换,则转换,反之,则返回0;
相关文章:
C/C++中奇妙的类型转换
1.引言 大家在学习C语言的时候,有没有遇见过类似于下面这样的代码呢? // 整形转bool int count 10; while(count--) {cout << count << endl; }// 指针转bool int* ptr cur; while(ptr) {//…… } 众所周知,while循环的判断…...
嵌入式AI快速入门课程-K510篇 (第三篇 环境搭建及开发板操作)
第三篇 环境搭建及开发板操作 文章目录 第三篇 环境搭建及开发板操作1.配置VMware使用桥接网卡1.1 vmware设置1.2 虚拟网络编辑器设置 2.安装软件2.2 安装 Windows 软件2.3 使用MobaXterm远程登录Ubuntu2.4 使用FileZilla在Windows和Ubuntu之间传文件2.5编程示例:Ub…...
C++第三十九弹---C++ STL中的无序容器:unordered_set与unordered_map使用详解
✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】 目录 1 unordered_set 1.1 unordered_set的接口说明 1.1.1 unordered_set的构造 1.1.2. unordered_set的容量 1.1.3. unordered_set的迭代器 1.1…...
数学建模起步感受(赛前15天)
0基础直接上手数模,因为大一!年轻就是无所畏惧!开个玩笑,因为数模比赛比一年少一年… 抱着不打也是浪费的态度,我开始着手准备 首先python啥也不会,知道有元组这玩意… 仅仅在刷软考题的时候遇到python选择…...
【YOLO5 项目实战】(4)红外目标检测
欢迎关注『youcans动手学模型』系列 本专栏内容和资源同步到 GitHub/youcans 【YOLO5 项目实战】(1)YOLO5 环境配置与测试 【YOLO5 项目实战】(2)使用自己的数据集训练目标检测模型 【YOLO5 项目实战】(3)P…...
游泳耳机哪个牌子好?角逐必选榜的4大王者游泳耳机测评解析!
在选择游泳耳机时,许多消费者往往会被市场上五花八门的产品所困扰。特别是那些标榜能够防水防潮的产品,但实际上它们往往缺乏核心技术支持,存在很高的损伤风险。据调查,超过90%的用户反映,市面上的游泳耳机常常无法达到…...
鹤岗房全国蔓延,现在要不要买房?
文|琥珀食酒社 作者 | 积溪 房子卖白菜价、人人都能买得起的时代 真的要来了 以前啊你花2万块钱 在大城市买不到一个厕所 可现在只要几万块你就能买一整套房 还带装修和家电 而且这样的房子还很多 “鹤岗”房已经在全国快速蔓延 那对咱普通人来说到底是好…...
Flink程序部署与提交
前言 我们看门见山,生产环境一般用的是在YARN上面采用应用模式进行部署flink程序。实际生产中一般需要和资源管理平台(如YARN)结合起来,选择特定的模式来分配资源、部署应用。 部署模式 在一些应用场景中,对于集群资源分配和占用的方式,可能会有特定的需求。Flink 为各…...
了解Android
Android 系统架构 从图中可以看出,整个Android操作系统分为五层。它们分别是: 内核层 Android系统是基于Linux内核的,这一层为Android设备的各种硬件提供了底层的驱动。硬件抽象层 该层为硬件厂商定义了一套标准的接口。这样可以在不影响上层…...
Tomcat学习进阶
目录 Apache Tomcat架构配置线程模型Tomcat 的类加载机制类加载器层次结构类加载流程 Tomcat 的优化策略Tomcat 的集群部署Tomcat故障排查 Apache Tomcat 架构配置 Apache Tomcat是一个开源的Java Servlet容器和Web服务器,它实现了Java EE规范中的Servlet和JSP API。…...
【C++】————智能指针
作者主页: 作者主页 本篇博客专栏:C 创作时间 :2024年8月20日 一,什么是智能指针 在C中没有垃圾回收机制,必须自己释放分配的内存,否则就会造成内存泄露。解决这个问题最有效的方法是使用智能指针&…...
GT IP中CC序列(Clock Correction Sequence)的周期性
CC序列(Clock Correction Sequence),即时钟校正序列,在数字通信中扮演着至关重要的角色。这一序列的周期性插入机制,旨在确保发送器和接收器之间的时钟同步,从而维持数据传输的准确性和稳定性。以下是CC序列…...
grafana pod 无法启动 Only one datasource per organization can be marked as default
标题信息 helm 部署的 prometheus 全栈监控 chart 为 prometheus-community/kube-prometheus-stack helm 部署的 loki 日志系统 chart 为 grafana/loki-stack 问题描述 grafana pod 启动不了,查看该pod 日志报错如下 logger=provisioning t=2024-08-21T06:42:45.954318228…...
你是如何克服编程学习中的挫折感的?(-@-^-0-)
在编程学习中遇到挫折感是极为常见且正常的现象,因为编程往往涉及解决复杂问题、理解抽象概念以及不断试错的过程。 以下是一些建议,帮助你在面对挫折时调整心态,继续前行: 接受失败是成长的一部分:首先要认识到&#…...
大数据技术之Zookeeper(1)
目录 Zookeeper 入门 概述 Zookeeper的主要特点包括: Zookeeper的应用场景: Zookeeper的基本概念: 架构: Zookeeper工作机制 Zookeeper数据结构 Znode(Zookeeper Node) Znode的类型 Znode路径 Znode属性 Wa…...
鸿蒙学习(四):泛型空安全模块导入导出
泛型与函数 泛型类型和函数允许创建的代码在各种类型上运行,而不仅支持单一类型。 泛型类和接口(Element) 类和接口可以定义为泛型,将参数添加到类型定义中,如以下示例中的类型参数Element: class CustomStack<Element>…...
无人机(Unmanned Aerial Vehicle, UAV)视觉感知论文汇总
综述类 A Survey of Object Detection for UAVs Based on Deep LearningDeep Learning for UAV-based Object Detection and Tracking:A surveyMoving Target Tracking by Unmanned Aerial Vehicle:A Survey and TaxonomyVision-Based Learning for Dro…...
【ORACLE】 ORA-01691: Lob 段无法通过 8192 (在表空间 XXX_SPACE 中) 扩展
ORA-01691错误通常表示Oracle数据库在尝试扩展LOB段时无法为表空间分配更多的空间。这个问题通常由表空间容量不足引起。根据搜索结果,以下是几种可能的解决方案: 检查并扩大表空间:首先,确认表空间是否已经达到其最大容量。可以使…...
Java之静态代理与动态代理的区别
🍁 作者:知识浅谈,CSDN签约讲师,CSDN博客专家,华为云云享专家,阿里云专家博主 📌 擅长领域:全栈工程师、爬虫、ACM算法 🔥 微信:zsqtcyw 联系我领取学习资料 …...
公司内网监控软件有哪些?(2024年10款最新款推荐内网监控软件)
在2024年,公司内网监控软件市场提供了多种选择,以满足不同企业的监控需求。 以下是一些值得推荐的最新款内网监控软件: 1. Performance Monitor 核心功能:不仅是一款局域网监控软件,更是一个全面的内网安全管理解决方…...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...
渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...
[特殊字符] 手撸 Redis 互斥锁那些坑
📖 手撸 Redis 互斥锁那些坑 最近搞业务遇到高并发下同一个 key 的互斥操作,想实现分布式环境下的互斥锁。于是私下顺手手撸了个基于 Redis 的简单互斥锁,也顺便跟 Redisson 的 RLock 机制对比了下,记录一波,别踩我踩过…...
Mac flutter环境搭建
一、下载flutter sdk 制作 Android 应用 | Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 1、查看mac电脑处理器选择sdk 2、解压 unzip ~/Downloads/flutter_macos_arm64_3.32.2-stable.zip \ -d ~/development/ 3、添加环境变量 命令行打开配置环境变量文件 ope…...
React核心概念:State是什么?如何用useState管理组件自己的数据?
系列回顾: 在上一篇《React入门第一步》中,我们已经成功创建并运行了第一个React项目。我们学会了用Vite初始化项目,并修改了App.jsx组件,让页面显示出我们想要的文字。但是,那个页面是“死”的,它只是静态…...
