「C/C++ 01」类型转换与整型提升

目录

一、类型转换和截断问题

1. 隐式类型转换

2. 强制类型转换

3. 截断问题 

二、整型提升

0. 算数表达式的计算过程

1. 整型提升是什么?

2. 为什么要整型提升?

3. 如何进行整型提升

4. 唯一的注意事项

5. 通过在vs中的监视窗口来观察整型提升 

6. 整型提升会不会引发线程安全问题?  

7. 整型提升是隐式类型转换吗 


一、类型转换和截断问题

1. 隐式类型转换

隐式类型转换是指编译器算数、比较、赋值、传参、传返回值时,遇到与要求不符合类型时,编译器就会自动执行类型转换以使得操作数具有符合条件的类型。


C/C++中有以下四种情况会进行隐式转换:

  • 算数或比较时,低类型转换为高类型。
  • 赋值时,右边表达式的值自动隐式转换为左边变量的类型,并赋值。
  • 传参时,系统将实参转换为形参的类型后,赋给形参。
  • 传返回值时,系统将返回值的类型转换为返回值类型。

隐式类型转换的例子包括:

算数或比较时:

  • 整型提升:小于intunsigned int的整数类型(如charshort)在表达式中会自动提升为intunsigned int

  • 浮点提升:当float类型的值和double类型的值进行算术运算时,float值会被提升为double类型。

赋值、传参、传返回值时:

  • 赋值时,右边表达式的值自动隐式转换为左边变量的类型,并赋值。
  • 传参时,系统将实参转换为形参的类型后,赋给形参。
  • 传返回值时,系统将返回值的类型转换为返回值类型。
  • 上面三种情况都可能因为大类型转换为小类型,导致截断问题

2. 强制类型转换

        如果想把一个变量A的值强制放到另外一种类型的变量B中,我们就需要在A前面加上(B的类型)来完成强制类型转换,如:

int *A;
double *B = (double *)A;

但使用强转时一定要小心大类型转换为小类型,导致截断问题

无论是哪种类型转换,都是借助了一个临时变量,被转换的变量没有发生变化。

3. 截断问题 

        类型转换(无论是隐式还是显式)都可能导致数据截断问题,特别是在将较大类型的值转换为较小类型时。当源类型的表示范围大于目标类型时,如果源类型的值超出了目标类型的表示范围,或者源类型的精度高于目标类型,就会发生数据截断。这里的截断要考虑到数据类型的大小(占几个字节)和数值的二进制。

二、整型提升

0. 算数表达式的计算过程

  • 值的取出:
           变量在表达式中参与计算时,其变量中保存的值会被编译器取出然后保存到寄存器中。
  • 整型提升:
            在上诉过程中从各种短整型(如 char、short、unsigned short等)中取出的值会被编译器提升成 int 或 unsigned int型【如果表达式中有 unsigned int 或 size_t型变量,表达式中所有变量的值就被提升为unsigned int型;没有就被提升为int型】
  • 结果的存储:
            ​​​​​​​​​​​​​​运算结果被放在一个int或unsigned int型的临时变量中
  • 赋值给变量:
            ​​​​​​​​​​​​​​然后将这个int或unsigned int型的临时变量赋值给接收结果的变量(看情况发生隐式类型转换或截断)。

1. 整型提升是什么?

        整型提升是隐式类型转换的一种特殊情况,它发生在整型变量的算术运算或比较运算中,将整型变量中的值取出到用于计算或比较的寄存器时,对取出的数值的二进制位进行补0或补1的操作,使其变为4byte(32bit)的int 或 unsigned int 类型。


总结下来就是:

  • 执行表达式比较大小时,各种短整型(如 char、short....等)要提升为int 或 unsigned int 类型;
  • 如果表达式中存在unsigned int 或 size_t类型变量,那 短整型和int 就要提升为unsigned int类型
  • 如果只存在短整型和int,那 短整型 就要提升为int类型。

2. 为什么要整型提升?

        表达式的整型运算是由CPU的整型运算器(ALU)来完成的,CPU内整型运算器的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。

3. 如何进行整型提升

  • 整形提升为unsigned int:在高位补0 ,直到补满32bit。
  • 整形提升为int:在高位补符号位(整数补0,负数补-1),直到补满32bit。

4. 唯一的注意事项

        唯一一点要注意的是-1被整型提升为unsigned int类型时会变成42亿9千多万。其中的原理相信学过位运算后都能明白。

5. 通过在vs中的监视窗口来观察整型提升 

我们可以通过在vs中的监视窗口来观察整型提升:

  • 如果只存在短整型和int,那 短整型 就要提升为int类型:

  • 如果表达式中存在unsigned int 或 size_t类型变量,那 短整型和int 就要提升为unsigned int类型:

6. 整型提升会不会引发线程安全问题?  

        不会,整型提升不是对变量进行强制类型转换,而是将变量中的值取出到用于计算或比较的寄存器时,对取出的数值的二进制位进行补0或补1的操作,使其变为4bit。

7. 整型提升是隐式类型转换吗 

        是的,C++中的整型提升是一种隐式类型转换(Implicit Type Conversion)。隐式类型转换是编译器自动进行的类型转换,不需要程序员显式指定,也不会对原变量造成影响,整型提升是隐式类型转换的一种特殊情况,它发生在整型变量的算术运算或比较运算中


------------------------END-------------------------

才疏学浅,谬误难免,欢迎各位批评指正。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/585759.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

螺旋角和导程、转位后的齿轮有什么关系?

最近和小伙伴聊到了一个问题:斜齿轮螺旋角和导程的关系,主要是在遇到在采用转位设计方式的刀具时,更觉得有点迷惑,今天咱们就聊聊这个事儿。 先来说斜齿轮螺旋角和导程的关系: 斜齿轮是有多个螺旋面组成的&#xff0…

力扣153. 寻找旋转排序数组中的最小值

Problem: 153. 寻找旋转排序数组中的最小值 文章目录 题目描述思路复杂度Code 题目描述 思路 1.初始化左右指针left和right,指向数组的头和尾; 2.开始二分查找: 2.1.定义退出条件:当left right时退出循环; 2.2.当nums…

【会员单位】浙江晧月水务科技有限公司

中华环保联合会理事单位 水环境治理专业委员会副主任委员单位 公司成立于2018年3月14日,是专业研究废水处理业务的国家高新技术企业。 公司自主研发的脱硫废水“零排放”的技术,不仅适应性好,技术先进,智慧化程度高&#xff0c…

深度学习中的变形金刚——transformer

很荣幸能和这些大牛共处一个时代。网络结构名字可以是一个卡通形象——变形金刚,论文名字可以来源于一首歌——披头士乐队的歌曲《All You Need Is Love》。 transformer在NeurIPS2017诞生,用于英语-德语,英语-法语的翻译,在BLEU…

21 如何进行高保真压测和服务扩容?

在后台架构中,压测非常常见,也是必须的工作。它能够帮我们发现微服务架构中的性能瓶颈,以及知道构建的微服务能承载的流量极限值。 但实际情况是,很多压测并不能发现瓶颈点和微服务所能承载的真实流量极限值。一方面是因为压测时…

LiveGBS user/save 逻辑缺陷漏洞复现(CNVD-2023-72138)

0x01 产品简介 LiveGBS是安徽青柿信息科技有限公司研发的一款国标(GB28181)流媒体服务软件,可提供提供用户管理及Web可视化页面管理,开源的前端页面源码;提供设备状态管理,可实时查看设备是否掉线等信息等。 0x02 漏洞概述 LiveGBS user/save 接口处存在逻辑缺陷漏洞,未…

【Qt之OpenGL】01创建OpenGL窗口

1.创建子类继承QOpenGLWidget 2.重写三个虚函数 /** 设置OpenGL的资源和状态,最先调用且调用一次* brief initializeGL*/ virtual void initializeGL() override; /** 设置OpenGL视口、投影等,当widget调整大小(或首次显示)时调用* brief resizeGL* param w* para…

请求接口报错:java.lang.IllegalStateException: argument type mismatch

目录 一、场景二、报错信息三、控制器四、接口调用五、原因六、解决 一、场景 1、调用后端接口报错 2、接口参数以Json方式传递 – 二、报错信息 java.lang.IllegalStateException: argument type mismatch Controller [com.xxx.huarunshouzheng.controller.MallControlle…

Ubuntu如何更换 PyTorch 版本

环境: Ubuntu22.04 WLS2 问题描述: Ubuntu如何更换 PyTorch 版本考虑安装一个为 CUDA 11.5 编译的 PyTorch 版本。如何安装旧版本 解决方案: 决定不升级CUDA版本,而是使用一个与CUDA 11.5兼容的PyTorch版本,您可…

75、堆-前K个高频元素

思路 这道题还是使用优先队列,是要大根堆,然后创建一个类,成员变量值和次数。大根堆基于次数排序。前k个就拿出前k的类的值即可。代码如下: class Solution {public int[] topKFrequent(int[] nums, int k) {if (nums null || …

解决: 0x803f7001 在运行Microsoft Windows 非核心版本的计算机上,运行“ slui.exe 0x2a 0x803f7001 “以显示错误文本,激活win10步骤流程。

一. 解决 0x803F7001在运行Microsoft Windows非核心版本的计算机错误 首先,按下winR打开"运行",输入 regedit 后回车,打开注册表。   然后再注册表下输入地址HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SoftwareProt…

Electron+Vue3+Vite+ElectronForge整合 - 一键启动两个服务 一键打包两个服务

说明 本文介绍一下 Electron Vue3 Vite Electron Forge 的高级整合操作。vue3 : 使用 TS 的语法开发; Electron : 使用 JS 的语法开发。本文将从项目初始化开始,一步一步的完成项目的启动、打包全流程的介绍。实现的效果是 : 1、一个正常…

一个类实现Mybatis的SQL热更新

引言 平时用SpringBootMybatis开发项目,如果项目比较大启动时间很长的话,每次修改Mybatis在Xml中的SQL就需要重启一次。假设项目重启一次需要5分钟,那修改10次SQL就过去了一个小时,成本有点太高了。关键是每次修改完代码之后再重…

前端打包过大如何解决?

前端开发完毕部署到线上是,执行npm run build。当打包过大时,部署到服务端后加载缓慢,如何优化? 我们可以通过执行npm run analyze。可以看到各个包文件大小的区别。 当打包过大时,通过压缩gzip的方式,可以…

React路由导航

1. 什么是路由导航 一个路由跳转到另一个路由&#xff0c;并且在跳转的同时有可能需要传递参数进行通信&#xff0c;比如列表页跳转到详情页携带参数 2. 声明式导航 声明式导航是指通过在模版中通过 <Link/> 组件描述出要跳转到哪里去&#xff0c;比如后台管理系统的…

【LeetCode】---15.最小栈

【LeetCode】---15.最小栈 一、题目解析&#xff1a;二、算法原理&#xff1a;三、代码实现&#xff1a; 一、题目解析&#xff1a; 设计一个支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初…

ARP学习及断网攻击

1.什么是ARP ARP&#xff08;Address Resolution Protocol&#xff09;是一种用于在IPv4网络中将IP地址映射到MAC地址的协议。在计算机网络中&#xff0c;每个网络接口都有一个唯一的MAC地址&#xff08;Media Access Control address&#xff09;&#xff0c;用于识别网络设备…

形态学图像处理

首先自己随便写了一个单词&#xff0c;然后在周围画一些相对细一点的噪声。 # 读取原始图片 original cv2.imread("romance.jpg") # 构造一个全1的5*5矩阵 kernel np.ones((5, 5), np.int8) 腐蚀 腐蚀&#xff08;Erosion&#xff09;是形态学图像处理中的一种基本…

Linux操作系统·进程管理

一、什么是进程 1.作业和进程的概念 Linux是一个多用户多任务的操作系统。多用户是指多个用户可以在同一时间使用计算机系统&#xff1b;多任务是指Linux可以同时执行几个任务&#xff0c;它可以在还未执行完一个任务时又执行另一项任务。为了完成这些任务&#xff0c;系统上…

初识Linux -- Linux的背景和发展史介绍

点赞关注不迷路&#xff01;&#xff0c;本节涉及初识Linux&#xff0c;主要为背景介绍和xshell登录主机。 1.Linux背景 1.1 发展史 Linux从哪里来&#xff1f;它是怎么发展的&#xff1f;在这里简要介绍Linux的发展史。 要说Linux&#xff0c;还得从UNIX说起。 1.2 UNIX发…
最新文章