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 核心功能:不仅是一款局域网监控软件,更是一个全面的内网安全管理解决方…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...
API网关Kong的鉴权与限流:高并发场景下的核心实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中,API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关,Kong凭借其插件化架构…...
LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》
🧠 LangChain 中 TextSplitter 的使用详解:从基础到进阶(附代码) 一、前言 在处理大规模文本数据时,特别是在构建知识库或进行大模型训练与推理时,文本切分(Text Splitting) 是一个…...
