数据计算中的整型提升( 以 “ char ” 和 “ int ” 为例 )

本文详细解释了C语言中整型提升的概念,探讨了为何发生提升,以及如何在int和char类型间进行提升,包括有符号和无符号的区别。通过实例说明了整型提升在存储和运算时的规则和注意事项。
摘要由CSDN通过智能技术生成
P. S.:以下代码均在VS2019环境下测试,不代表所有编译器均可通过。
P. S.:测试代码均未展示头文件stdio.h的声明,使用时请自行添加。

一 . 整型提升的定义

  首先,我们应该知道这一点:C语言中整型运算总是至少以缺省整型类型的精度来进行的。

  这句话什么意思呢?用大白话说就是:C语言中字节数少于整型字节数的数据类型在进行整型运算时,该类型的数据会被默认转为整型数据。

  其中,该类型的数据被转化为整型数据的过程就称为整型提升。


二 . 为什么会发生整型提升


  这是由计算机体系结构决定的,计算机中的计算都由CPU完成,具体来说是由CPU中的运算器(ALU)完成的。而ALU一般在被设计时,其操作对象——操作数的字节大小被要求至少是int的字节数。此时,我们还要明晰一个事情,那就是数据在被运算时,数据并不是直接在ALU上存储的,而是存储在CPU的寄存器(register)中,而通用寄存器的字节大小与ALU操作数的字节大小保持一致。
  大字节数据也可以储存小字节的数据。但问题在于大字节数据拥有4个字节的空间,如果时少于4个字节的数据,该将其放置哪些字节里面?如果随便存放,在需要获取其信息时,还需花费时间寻找存放数据的字节,这样势必会使效率变低。所以,在存放时,至少需要将小字节的数据变成4个字节的,这时就发生了整型提升。

  在32位平台,C语言非自定义数据类型的字节数只有4种(1,2,4,8)。

  非自定义数据类型的字节数取值可能,我们发现只有(1,2)在进行整型运算时,会发生整型提升。而这两个数据类型对应的便是char与short。

  总的来说:C语言中,表达式中的字符和短整型操作数在使用之前会发生整形提升,变为普通整型。


三 . 简述数据存储(以“ int ” “ char ”为例)


  C语言中,int 类型的数据在内存中存储需要4个字节,也就是32个bite位。
int a = 1;
//x在内存中存储的二进制为00000000 00000000 00000000 00000001
int b = -1;
//x在内存中存储的二进制原码为10000000 00000000 00000000 00000001
//                   反码为11111111 11111111 11111111 11111110
//                   补码为11111111 11111111 11111111 11111111
unsigned int c = 1;
//x在内存中存储的二进制为00000000 00000000 00000000 00000001
unsigned int d = -1;
//x在内存中存储的二进制原码为10000000 00000000 00000000 00000001
//                   反码为11111111 11111111 11111111 11111110
//                   补码为11111111 11111111 11111111 11111111

  当我们分别给有符号整型a , b 和无符号整型 c , d 储存1和-1时 他们的二进制存储如上面代码块所示


  当我们分别打印他们的时候会显示如下

printf("a=%d\n b=%d\n c=%d\n d=%d\n",a,b,c,d);
 a=1
 b=-1
 c=1
 d=4294967295

  我们发现将-1存储到无符号整型变量里时,补码11111111 11111111 11111111 11111111就会认为是一个无符号的数据,将其打印到屏幕是,按照二进制的计算规则,左边第一位就不再是符号位,而代表一个数据,十进制打印也就会出现 d=4294967295这样的情况。

  而有符号的数据类型,左边第一位为1就代表它为负数,为0就代表他为正数。


四 . 简单的整型提升(以“ int ” “ char ”为例)


  我们举一个例子,写一段代码,分别将300储存到 int 类型和 char 类型的变量中,并打印到屏幕上。
	int a = 300;
	char b = 300;
	printf("a=%d\n", a);
	printf("b=%d\n", b);

在这里插入图片描述


  我们发现明明都是300,为什么打印出来的值却不一样呢?


在这里插入图片描述
  因为计算机储存数据时会将其转换为32个二进制位数据进行存储,而 char 类型只能存放一个字节也就是八个bite位的数据,此时就会发生截断现象,也就如上图所示,b变量内存储的只是红色标记部分的00101100,而我们在打印时又是以整型数据打印的,这个时候就会发生整型提升,也就是将char类型的数据通过左补符号位来进行整型提升,此时b打印出来的数值就是44。


五 . 整型提升的规则(以 “ char ”为例)


  整型提升分为有符号和无符号两种。

5.1 有符号的:


  整型提升时是按照变量的补码被截断时的最高位是什么进行补位的,如果截断后最高位即最左面的一位数为 1 则在最高位前补 1 ,如果最高位是 0 则在前面补 0 ,补够32位即int类型即可。

  例如

	char a = 128;
	char b = 127;
	printf("a=%d\n", a);
	printf("b=%d\n", b);

在这里插入图片描述
  在存储时我们只会将红色部分的数据存储到a和b中,当我们使用“%d”来打印时,需要将他们整型提升,也就是按照整型提升的规则进行补位/,如下。
在这里插入图片描述
  a数据的左一位为1,所以左边用1补足32位,b数据同理。
  但因为是有符号类型,所以a会被当作负数进行打印,我们需要通过补码来得到它的原码。
在这里插入图片描述
  此时a所打印的值就为-128。
在这里插入图片描述



5.2 无符号的:


  直接在被截断的前面补 0 即可。

  同样我们以实例说话。

	unsigned char a = 128;
	unsigned char b = 127;
	printf("a=%u\n", a);
	printf("b=%u\n", b);

在这里插入图片描述
  因为我们的数据类型为无符号类型,所以左边直接用0补足32位即可,打印出来的数值如下图所示。
在这里插入图片描述





六 . 结语 :


  整型提升时需注意区分有符号无符号的提升方法,储存变量时也要注意是否有截断的发生。



  十分感谢您观看我的原创文章。
  本文主要用于个人学习和知识分享,学习路漫漫,如有错误,感谢指正。
  如需引用,注明地址。

  • 29
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值