【C语言】整型提升和算术转换,表达式究竟是如何进行求值的?一张图说明白!

前言:上一篇文章小飞提到了整数在内存中的存储形式,那么表达式在这个过程中是如何进行计算的呢?其实在这个过程中,不仅会进行二进制运算,还可能会进行整型提升和算术转换这两个操作,那么计算机是如何进行的?这样做又有什么意义呢?看完觉得有帮助的话记得点赞收藏加关注哦~


目录

一、整型提升

二、算数转换


一、整型提升

 (1) 概念:

C语言中,整型算数运算总是至少以默认int类型的精度来进行的(int大小因平台而异,16位系统大小为2字节,32位和64位为4字节)为了达到这个最小精度,表达式中的字符短整型操作数在使用之前要被转换成默认整型,这种转换被称作:整型提升

注意:字符也可以看作整型家族的一员,实质存储的是ASCII码值。 


 (2)  整型提升的规则:

有符号整数提升由变量的符号位决定高位补符号位的值。

无符号整数提升,高位补0。

tips:进行提升的都是补码,因为内存运算使用的是补码(不知道的小伙伴可以看我的上一篇文章)

eg:①char a=-1;

        补码为11111111(char类型占一字节)

        char默认是有符号的,所以高位补充符号位1

        所以整型提升的结果为:

        11111111111111111111111111111111(32个1,对应

        int的32比特位)

        ②char b=1;

        补码00000001,有符号数,高位补符号位0

        整型提升的结果为:

        00000000000000000000000000000001

        

        ③unsigned char c=1;

        补码为00000001,无符号数,高位补0

        整型提升的结果为:

        00000000000000000000000000000001

以下面的加法运算为例:

char a = 5;//补码:00000101
char b = 125;//补码:01111101
char c = a + b;
printf("%d", c);

 要实现a+b运算过程:

①首先a和b要经过整型提升:也就是a存储的数据提升为0000…00000101,b存储的数据提升为0000…01111101再进行加法。得到结果0000…10000010但不能直接给c;

结果要截断为char类型对应的一字节1000010才能赋给c,截断后c存的是-126的补码,但printf按照%d类型打印,也就是按有符号int类型打印,且输出的是原码值

③因此c要打印出来要再经过一次整型提升,变为1111…100000010;

再转回原码1000…0111111110,这时printf才能输出-126。

下图为具体过程演示(图中序号和上面的解释序号对应):

(3) 整型提升的意义:

①硬件效率优化:

表达式的整型运算要在CPU(中央处理器)内整型运算器(ALU)进行,ALU的操作数的字节⻓度⼀般是int的字节⻓度,同时也是CPU的通⽤寄存器的⻓度。两个char类型的相加,在CPU执⾏时,要先转换为ALU操作数的字节⻓度,才能与机器字长对齐,提高计算效率


②统一操作数类型:

CPU一般难以实现两个1字节数据直接相加运算。所以表达式中各种可能⼩于int⻓度的整型值,都必须先转换为int或unsigned int,然后才能送⼊CPU去执⾏运算。


二、算数转换

首先,算数转换其实是隐式类型转换的一种。那什么是隐式类型转换呢?

隐式类型转换是编译器在无需程序员显式操作的情况下自动一种类型转换为另一种类型的过程。

发生的情况有:

  1. 赋值操作:将值赋给不同类型的变量时;
  2. 函数调用:传递参数与函数声明类型不匹配时;
  3. 混合类型运算:操作数类型不同时的算数运算;
  4. 条件判断:非布尔类型转换为布尔类型;
  5. 返回值类型:不同函数返回类型与声明的类型不一致时。

以上情况编译器都会自动进行隐式类型转换。

算数转换就是隐式类型转换的第三点,处理混合类型运算的一种具体形式。

如果某个操作符的各个操作数属于下图中不同的类型,那么除⾮其中⼀个操作数的转换为另⼀个操作数的类型,否则操作就⽆法进⾏。下⾯的层次体系称为寻常算术转换

注意:字符短整型没有出现在下图,是因为它们先要整型提升为int。

下图为算数转换的转换顺序:

假设某个操作数的类型在上⾯这个列表中排名靠后(越靠近int),如果另一个操作数类型和它一样就不用转换,否则要转换为另外⼀个操作数的类型后执⾏运算。

eg:

char a=1;//整型提升为int
float b=0.1;
a+b;//此时a先整型提升为int类型,再进行算数转换为float类型,才能与b进行加法运算

由于这里的计算涉及浮点数在内存中的储存,小飞就不详细描述了,下期将着重围绕浮点数展开,再做更多描述。


结语:非常感谢耐心看到这里的小伙伴,本文主要讲了表达式求值过程中整型提升和算数转换两个过程,但还存留了一点问题,整型运算直接进行二进制补码运算,那浮点数是怎样进行的呢?下期将围绕浮点数的储存展开。本篇文章到此结束,我们下期再见!

如果上述内容对您有帮助的话,还请点赞收藏✿

如果发现内容有误,还请给予指正,十分感谢:>

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值