C语言的显式类型转换和隐式类型转换详细讲解

 目录

一、类型转换

1、显式类型转换

2、隐式类型转换

二、算术转换

三、总结


每个编译器都会对表达式做两件事情,一是判断表达式中操作符的优先级和结合性,二是判断表达式中的操作数类型是否一致,如果不一致则需要进行类型转换。第一点在我前面的文章中已经讲解过了,这篇就特意来讲解一下第二点类型转换和算术转换。看看编译器是如何进行操作的。

一、类型转换

首先我们先来学习C语言中的类型转换,为什么要进行类型转换呢?因为C的整型算术运算总是至少以缺省整型类型的精度来进行的。编译器为了实现这个精度,所以会将表达式中操作数小于整型数据类型字节大小的数据转换为普通整型再进行运算,这种方法称为整型提升。如果有时候我们知道表达式中的数据需要进行转换,那我们就可以显示转换,如果有时候我们没有对数据进行显示转换,那么编译器就会隐式的帮我们转换。

所以,类型转换分为两种:显式类型转换和隐式类型转换。

显式类型转换:我们自己使用强制类型转换操作符进行数据类型转换。

隐式类型转换:编译器默认的帮我们转换。

那我们现在再来了解一个概念,编译器为什么要提升精度呢?这个就要从计算机层面进行分析,这是我从网上搜到的资料。

表达式的整型运算要在CPU的相应运算器内执行,也就是在CPU内整型运算器(ALU)。

ALU的操作数的字节长度一般就是int的字节长度(4个字节),同时也是CPU的通用寄存器的长度。

因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。

通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int

,然后才能送入CPU去执行运算。

 了解这些之后,我们就分别来学习一下两种方式的类型转换。

1、显式类型转换

int main()
{
    //显式类型转换
    float a = 10.55f;
    float b = 13.14f;
    float c = (int)a + (int)b;
    printf("%f\n",c);

    return 0;
}

大家看代码执行的结果,为什么两个浮点数相加之后,并且我用浮点数打印结果,却结果是不对的,应该打印正确的结果为23.690000。这是因为我对数据类型进行了显式转换的处理。

起到作用的代码主要是这一行:float c = (int)a + (int)b;首先变量a和变量b是浮点型存储在内存中的,然后我从内存中取出这两个变量的时候,就对他们进行了处理。处理的方式就是(int)a,意思就是把a的值取出来强制转换为int的数据类型,(int)c也是同样的处理,这样操作之后 (int)a + (int)b的结果就为10+13=23。最后再把23赋值给变量c,变量c在用浮点数的形式存储在内存中。所以最后打印出来的是23.000000。

看完这段代码是不是对显式类型转换有了一定的了解。这里提一个小小的建议,在以后写代码的时候,如果你知道自己需要使用什么样的数据类型,就提前定义好数据类型,尽量少在表达式中使用显式类型转换。这样可能会给你的代码带来潜在的危害。C语言标准有这个操作,说明也有它的好处存在,所以大家根据需要决定使用。

2、隐式类型转换

隐式这词见名思意就知道是我们不显式的写类型转换,让编译器根据代码的实际情况,判断要不要进行数据转换。编译器隐式转换的主要方法就是整型提升。

编译器是如何进行整型提升的呢?整形提升是按照变量的数据类型的符号位来提升的。下面给大家画图演示一下。

不管是short类型还是char类型,在表达式中进行运算的时候编译器都会按照图片中的方法进行整型提升。以方便CPU进行计算。

我们再来看一个例子:

    char c = -1;
    printf("%d\n",sizeof(c));
    printf("%d\n", sizeof(+c));
    printf("%d\n", sizeof(-c));

为什么同样用sizeof操作符求变量c的字节大小的时候,结果会不一样呢?这就是因为编译器在运行代码的时候,进行表达运算的时候,表达式中的数据类型有小于int字节大小的数据都会被隐式的整型提升操作。sizeof(+c)、sizeof(-c)中的c都做了表达式运算,所以被整型提升了,最后sizeof求的是int类型的字节数。

总结:显式类型转换就是可以随便转换我们想要的数据类型。而这里的隐式转换只是在表达式中,操作数的数据类型有小于int类型的数据转换为int大小的数据,也就是整型提升。这种只是隐式转换的一种形式,还有另外一种形式。

二、算术转换

这里的算术转换其实就是上面所说的隐式转换的第二种形式。这里的算术转换的都是大于等于int类型的数据。算术转换就是在一个表达式中,有两个不同数据类型的操作数,那么编译器就会隐式的转换为一种数据类型,然后进行运算。那编译器是如何判断将两种不同的数据类型转换成一个呢?那请看下面。

long double
double
float
unsigned long int
long int
unsigned int
int

编译器在隐式转换类型的依据就是把精度低的数据类型转换成精度高的数据类型。上面图片就是各种数据类型的精度排行,从下往上就是代表精度从低到高。

    int a = 20;
    float b = 5.23f;
    int c = a + b;

上面的代码中,有两个不同的数据类型变量,在进行   int c = a + b; 表达式运算的时候,会有一个隐式转换的过程。因为int 类型比 float类型的精度低,所以编译器会先把变量a隐式转换为float类型的数据,然后再把两个float类型的a和b进行相加。

注意:虽然编译器会帮我们隐式转换数据类型,提高数据类型精度。但我们还是要合理使用它。比如下面的代码就会带来潜在的问题。

本来我们想要把变量f的值给变量num,但是这里会有一个隐式转换,会把float类型隐式转换为int类型,这样就会导致数据的精度丢失。所以我们要合理的使用它,这种潜在的问题在调试bug的时候不容易找出来。

三、总结

 这节主要讲了类型转换的操作,类型转换主要分为显式类型转换和隐式类型转换。隐式类型转换又分为整型提升和算术转换两个操作。整型提升的用途主要是在表达式中,有数据类型小于int类型大小的,编译器就会隐式的把小于int类型的数据转换为int类型的数据。算术转换的用途就是在表达式中,操作数的数据类型都是大于等于int 类型,并且数据类型不一致,这个时候编译器就会隐式算术转换。两种隐式转换都有一定的潜在问题,大家都要合理使用。

谢谢大家~~

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

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

相关文章

吴恩达机器学习实践实验室:决策树(Decision Trees)

在本练习中,您将从头开始实施决策树,并将其应用于蘑菇可食用还是有毒的分类任务。 文章目录 1-包2-问题陈述3-数据集3.1一个热编码数据集 4-决策树4.1计算熵4.2分割数据集4.3计算信息增益4.4获得最佳分割 5-构建树 1-包 首先,让我们运行下面…

【问题解决】ubuntu安装新版vscode报code-insiders相关错误

问题 目前 vscode官网 最新的包为 insiders_1.89.0-1712297812_amd64.deb ,双击或者使用sudo dpkg -i code-insiders_1.89.0-1712297812_amd64.deb安装后报错,执行其他命令也报错。 安装环境:ubuntu18.04 dpkg: 处理软件包 code-insiders (…

代码随想录算法训练营第四十九天 | 121. 买卖股票的最佳时机、22. 买卖股票的最佳时机 II

代码随想录算法训练营第四十九天 | 121. 买卖股票的最佳时机、22. 买卖股票的最佳时机 II 121. 买卖股票的最佳时机题目解法 122. 买卖股票的最佳时机 II题目解法 感悟 121. 买卖股票的最佳时机 题目 解法 题解链接 没看题解想出来的:贪心 class Solution { pub…

归档模式下,物理删除数据文件的完全的恢复

归档模式下,物理删除数据文件的完全的恢复 1、实验环境 环境归档模式 SQL> archive log list Database log mode Archive Mode Automatic archival Enabled Archive destination /arch/archivelog Oldest online log seq…

用户态网络缓冲区的设计

一、网络缓冲区 在内核中也是有网络缓冲区的,比如使用 read 读取数据(read 是一种系统调用,第一个参数为 fd),当陷入到内核态的时候,会通过 fd 指定 socket,socket 会找到对应的接收缓冲区。在…

抓住风口,快速上手RAG应用开发!

免责声明~ 任何文章不要过度深思! 万事万物都经不起审视,因为世上没有同样的成长环境,也没有同样的认知水平,更「没有适用于所有人的解决方案」; 不要急着评判文章列出的观点,只需代入其中,适度…

37-代码测试(下):Go语言其他测试类型及IAM测试介绍

。 Go中的两类测试:单元测试和性能测试。 我就来介绍下Go 语言中的其他测试类型:示例测试、TestMain函数、Mock测试、Fake测试等, 示例测试 示例测试以Example开头,没有输入和返回参数,通常保存在example_test.go…

Go语言实现Redis分布式锁2

项目地址: https://github.com/liwook/Redislock 1.支持阻塞式等待获取锁 之前的是只尝试获取一次锁,要是获取失败就不再尝试了。现在修改为支持阻塞式等待获取锁。 添加LockOptions结构体 添加option.go文件。 在LockOptions中 isBlock表示是否是阻塞模式blo…

美团一面:说说synchronized的实现原理?问麻了。。。。

引言 在现代软件开发领域,多线程并发编程已经成为提高系统性能、提升用户体验的重要手段。然而,多线程环境下的数据同步与资源共享问题也随之而来,处理不当可能导致数据不一致、死锁等各种并发问题。为此,Java语言提供了一种内置…

Pots(DFS BFS)

//新生训练 #include <iostream> #include <algorithm> #include <cstring> #include <queue> using namespace std; typedef pair<int, int> PII; const int N 205; int n, m; int l; int A, B, C; int dis[N][N];struct node {int px, py, op…

谱重排变换和同步压缩变换的区别是什么?

谱重排方法能够得到非常高的时频分辨率&#xff0c;但是同样也存在一个问题&#xff0c;不能重构原始信号&#xff0c;2011 年 Daubechies 提出了一种基于相位的高分辨率时频分析方法—同步压缩小波变换&#xff0c;该方法也是一种谱重排的方法&#xff0c;能使非平稳非线性信号…

Mybatis报错:Unsupported conversion from LONG to java.sql.Timestamp

Mybatis在封装结果集的时候&#xff0c;如果方法返回的是对象&#xff0c;则会去调用这个对象的无参构造方法。 如果实体类标注了Builder注解&#xff0c;则此注解会把默认的构造方法全部改成私有的&#xff0c;则Mybatis在通过无参构造方法反射创建对象时&#xff0c;就会找不…

Redis中的集群(二)

节点 集群数据结构 redisClient结构和clusterLink结构的相同和不同之处 redisClient结构和clusterLink结构都有自己的套接字描述符和输入、输出缓冲区&#xff0c;这两个结构的区别在于&#xff0c;redisClient结构中的套接字和缓冲区是用于连接客户端的&#xff0c;而clust…

已解决:windows 下无法加载文件 xxx.ps1,因为在此系统上禁止运行脚本

目录 1&#xff0c;问题描述2&#xff0c;问题解决 1&#xff0c;问题描述 当通过 npm 全局安装依赖后&#xff08;比如 ts 对应的 tsc 命令&#xff0c;还有 pnpm&#xff09;&#xff0c;想直接使用安装的命令&#xff0c;就会报错&#xff1a; 2&#xff0c;问题解决 以管…

2024年AI带来的革命性变革与创新

大家好&#xff01;相信大家对于AI&#xff08;人工智能&#xff09;的发展已经有了一定的了解&#xff0c;但你是否意识到&#xff0c;到了2024年&#xff0c;AI已经变得如此强大和普及&#xff0c;带来了我们从未想象过的便利和创新呢&#xff1f;让我们一起来看看AI在这个时…

Python学习笔记11 - 列表

1. 列表的创建与删除 2. 列表的查询操作 3. 列表的增、删、改操作 4. 列表元素的排序 5. 列表生成式

负荷预测 | Matlab基于TCN-GRU-Attention单输入单输出时间序列多步预测

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab基于TCN-GRU-Attention单输入单输出时间序列多步预测&#xff1b; 2.单变量时间序列数据集&#xff0c;采用前12个时刻预测未来96个时刻的数据&#xff1b; 3.excel数据方便替换&#xff0c;运行环境matlab20…

QT drawPixmap和drawImage处理图片模糊问题

drawPixmap和drawImage显示图片时&#xff0c;如果图片存在缩放时&#xff0c;会出现模糊现象&#xff0c;例如将一个100x100 的图片显示到30x30的区域&#xff0c;这个时候就会出现模糊。如下&#xff1a; 实际图片&#xff1a; 这个问题就是大图显示成小图造成的像素失真。 当…

蓝桥杯刷题-16-买瓜-DFS+剪枝优化⭐⭐

蓝桥杯2023年第十四届省赛真题-买瓜 该如何剪枝呢&#xff1f;⭐⭐ 如果当前方案的切的刀数&#xff0c;已经大于等于了之前已知合法方案的最优解&#xff0c;那么就没必要 往后搜了。如果后面的瓜的总和加起来&#xff0c;再加上当前已有的重量&#xff0c;都不到m,那么也没…

Flask Web框架的使用-安装Flask

Flask Web框架的使用-安装Flask 一、前言二、安装Flask 一、前言 个人主页: ζ小菜鸡大家好我是ζ小菜鸡&#xff0c;让我们一起来学习Flask Web框架的使用-安装Flask如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连) 二、安装Flask 大多数Python 包都是使用pip 实用工具安…