C/C++ 中有哪些类型转换方式? 分别有什么区别?

ops/2024/11/17 18:50:52/

        在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字节的内存空间;这是由指针所指向的数据的类型决定的)。有了这个点,其实所有类型的对象之间都能间接转换了,但是解引用之后所能访问的内存空间大小不一样。

C++中的强制类型转换

        在C++语言中新增了四个用于强制类型转换的关键字,分别是 static_cast、 dynamic_cast, const_cast、 和 reinterpret_cast,使用语法为 xxxx_cast(expression)。

        相比于C语言中使用小括号()来完成强制类型转换,C++中这几个关键字的引入能更清晰的表明它要完成强制类型转换的意图,容易暴露出隐藏的问题。

        其实很长一段时间以来,我对于这四种强转方式区分的不是很清晰,其中 const_cast 的功能还比较容易辨别,但是另外3种经常混作一团,所以在仔细学习后才发现,这4种强转关键字的区别就在他们的名字上,下面逐个来看一下。

static_cast

        这个关键字的作用主要表现在 static 上,是一种静态的转换,在编译期就能确定的转换,可以完成C语言中的强制类型转换中的大部分工作,但需要注意的是,它不能转换掉表达式的 const、volitale 或者 _unaligned 属性。

dynamic_cast

        从名字上看,这个关键字与 static_cast 的静态转换是对立的,这是一个“动态”转换函数,只能对指针和引用的进行转换,并且只用于类继承结构中基类和派生类之间指针或引用的转换,可以进行向上、向下,或者横向的转换。

        相比于 static_cast 的编译时转换, dynamic_cast 的转换还会在运行时进行类型检查,转换的条件也比较苛刻,必须有继承关系的类之间才能转换,并且在基类中有虚函数才可以,有一种特殊的情况就是可以把类指针转换成 void* 类型

const_cast

        在C/C++中,const限定符通常被用来限定变量,用于表示该变量的值不能被修改,这种限定可以避免程序员犯一些初级错误,但同时也造成了一些不便,比如一些已有函数要求非常量指针,但是掉用这些函数的接口函数中都传递了常量指针,这时候就要对指针类型去常量化。

        但需要特别注意的是 const_cast 不能去除变量的常量性,只能用来去除指向常数对象的指针或引用的常量性,且去除常量性的对象必须为指针或引用。

        常量指针被转化成非常量指针,并且仍然指向原来的对象,常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象可能被转换成非常量对象。

        实际上,使用const_cast通常是一种无奈之举,利用const_cast去掉指针或引用的常量性并且去修改原始变量的数值,这是一种非常不好的行为,如果可以的话,尽可能在程序设计阶段就规避这种情况。

reinterpret_cast

        它被用于不同类型指针或引用之间的转换,或者指针和整数之间的转换,是对比特位的简单拷贝并重新解释,因此在使用过程中需要特别谨慎,比如前面提到的一个例子,static_cast 不能将 int* 直接强转成 char*,使用reinterpret_cast就可以办到。


http://www.ppmy.cn/ops/134499.html

相关文章

CSM32RV20:RISC-V核的低功耗MCU芯片,常用在智能门锁上

CSM32RV20是一款基于RISC-V核的低功耗MCU芯片。 内置RISC-V RV32IMAC内核(2.6CoreMark/MHz); 蕞高32MHz工作频率; 内置4kB的SRAM; 内置8B的ALWAYS寄存器,能在掉电模式2下保存数据; 内置40kB的嵌…

【Rust调用Windows API】获取正在运行的全部进程信息

前言 WIndows API官方文档 提供了C的调用示例,最近想尝试用Rust去实现,本系列博客记录一下实现过程。 依赖 Rust调用Windows API需要引入依赖winapi,在Cargo.toml中添加依赖 winapi "0.3.9"调用不同的API集就需要使用相应的功…

Python - 初识Python;Python解释器下载安装;Python IDE(一)

一、初识Python Python 是一种高级编程语言,Python是一种面向对象的解释型计算机程序设计语言,Python由荷兰国家数学与计算机科学研究中心的吉多范罗苏姆()Guido van Rossum吉多范罗苏姆()于1989 年底发明…

羊城杯2020Easyphp

审题 看到url,可以想到伪协议读取 尝试过后可以发现,题目绕过了read后面的编码 我们可以尝试双重urlencode进行绕过 ?filephp://filter/read%25%36%33%25%36%66%25%36%65%25%37%36%25%36%35%25%37%32%25%37%34%25%32%65%25%36%32%25%36%31%25%37%33%…

react 中 memo 模块作用

memo是一个用于优化组件性能的高阶组件。 一、避免不必要的重新渲染 1. 浅比较机制原理 1.1 组件渲染触发条件 在 React 中,当组件的props或state发生变化时,组件会重新渲染。然而,在某些情况下,即使父组件重新渲染并传递给子…

STM32 ADC --- 任意单通道采样

STM32 ADC — 单通道采样 文章目录 STM32 ADC --- 单通道采样cubeMX配置代码修改:应用 使用cubeMX生成HAL工程 需求:有多个通道需要进行ADC采样,实现每次采样只采样一个通道,且可以随时采样不同通道的功能。 cubeMX配置 这里我们…

HarmonyOS4+NEXT星河版入门与项目实战--------开发工具与环境准备

文章目录 1、熟悉鸿蒙官网1、打开官网2、下载 DevEco Studio3、HarmonyOS 资源库4、开发指南与API 2、安装 DevEco Studio1、软件安装2、配置开发工具 1、熟悉鸿蒙官网 1、打开官网 百度搜索 鸿蒙开发者官网 点击进入开发者官网,点击开发,可以看到各种…

leetcode 扫描线专题 06-leetcode.252 meeting room 力扣.252 会议室

扫描线专题 leetcode 扫描线专题 06-扫描线算法(Sweep Line Algorithm) leetcode 扫描线专题 06-leetcode.218 the-skyline-problem 力扣.218 天际线问题 leetcode 扫描线专题 06-leetcode.252 meeting room 力扣.252 会议室 leetcode 扫描线专题 06…