【C语言】整型提升与char取值范围

news2024/12/24 8:41:01

整型提升介绍

C语言中整型算术运算总是至少以缺省(默认)整型类型的精度来进行的。为了获得这个精度,表达式中字符、短整型操作数在使用前被转换为普通整型。而这个过程是悄悄发生的。

整型提升的意义:

表达式的整型运算要在CPU的相应运算器件内执行,CPU整型运算器(ALU)的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。

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

通用CPU难以直接实现两个8bit字节的直接加法运算。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行。

举个例子:

char a = 20;
char b = 130;
char c = a + b;
printf("%d\n", c);

根据我们上面说的,在这段代码中,其实会先把a、b提升为整型类型才计算。

怎么整型提升

有符号整数的整型提升是按照变量的数据类型的符号位来提升的;

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

回到我们刚才的例子:

char a = 20;

20本身是个整数,整数存到整型中应该有32个比特位(bit),因为是个正整数,它的原码、反码、补码相同:

00000000000000000000000000010100

但是我们现在要将它存放到char类型(只有1个字节,也就是8bit)中去,会发生截断。

我们只能存下这个:

00010100

 同样的道理,b里面我们只能存的是:

10000010

那么现在,c里面放的是什么?

因为我们已经知道,a+b在具体计算前会先发生整型提升,我们也知道整型提升的规则是:有符号整数的整型提升是按照变量的数据类型的符号位来提升的;无符号整数提升,高位就补0。因为是a、b是有符号整型,所以按照符号位来提升:

00010100 ---> 00000000000000000000000000010100 //因为符号位为0
10000010 ---> 11111111111111111111111110000010 //因为在提升时认为符号位是1
  a + b:      11111111111111111111111110010110
11111111111111111111111110010110 ---> 10010110 //因为c只能存8位,又截断

所以c里面存的是10010110,但是这还没有结束,最后我们要打印的时候用的是%d,这是打印一个有符号的整型,我们此时又要进行提升

10010110 ---> 11111111111111111111111110010110 
//因为%d是有符号整型,提升时按符号位提升,而1被视作符号位

而此时%d打印出来的结果并不是这个二进制序列直接翻译成十进制的结果,因为内存中存储的是补码,而我们要找出它的原码直接翻译的结果才是我们会打印出来的值:

因为现在的符号位上还是1,被当做负整数,所以原码、反码、补码并不相同,我们可以通过将补码取反+1的方法得到原码:

11111111111111111111111110010110 ---> 10000000000000000000000001101001
//取反的规则是符号位不变,其它位取反
10000000000000000000000001101001 ---> 10000000000000000000000001101010
//将取反的结果再加1

最后这个原码直接翻译:因为%d是有符号整数,符号位为1所以是负数,1101010转换为10进制是106,所以最后打印的结果就是-106。

另一种视角(char取值范围)

char a = 20;
char b = 130;
char c = a + b;
printf("%d\n", c);

关于这段代码,通过上面的讲解我们多次感受到了整型提升, 这是我们从内存中存储了什么的角度一步步去看为什么结果是-106的,其实还有另一个角度可以解释结果为什么结果为-106:

我们不要忘记char类型的取值范围,一般情况下char就是指的有符号的char,取值范围是-128~127(而unsigned char范围是0~255,都是256个不同数值)。

(本文不解释为什么是这样)这是我们char能存储的值的示意图,就像一个轮回:

所以其实130大于char的取值,我们无法将其存进b里。

我们可以通过监视看看b存的是什么:

可以看到我们存的值就是-126,那么a+b就变成了-106。

 那么为什么b里面会存为-126呢?在上面我们已经得到了a+b的二进制序列被截断为8bit,也就是c里实际存的二进制序列是:

10010110

在计算器中我们可以观察到这个二进制序列直接翻译为10进制的值是150。

但是对于char而言,这个二进制序列可不是代表150。 为什么?

因为char只能存8bit,且为有符号类型,所以最高位是符号位,1说明是负整数,那么说明存的是补码,原码需要计算,根据取反(符号位不变,其他位按位取反)再+1,我们得到原码是:

10010110 ---> 11101001 ---> 11101010
         取反          加1

最高位是符号位,代表是负数,而剩下的有效位转化为十进制是106。所以原码就是106,

补充:char能存储的补码

我们知道char有8位,而每一位非0即1,所以我们能存的补码就是00000000~11111111,又因为char是有符号的char,所以当最高位变为1的时候我们会将其作为符号位而非有效位,而存的又是补码,在翻译为10进制数的时候要先取反加1得到原码,直接翻译才是其对应的10进制数。

其中10000000的求原码比较特殊,取反加1后我们得到100000000是9位的,而char只能存8位,所以会变为00000000,但是我们却不将其翻译为10进制的0而是-128。除了这个特殊情况外,其它情况都可以正常方式得到原码:

通过这张图,你应该就理解了上面那个“轮回”的图为什么是那样的了。

我们还可以发现,除了127加1得到的是-128的特殊情况,其他时候补码加1就是10进制加1的效果。 

到此,整型提升和char取值范围的讲解就结束了,祝阅读愉快^-^ 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小米财报:业绩远超预期,汽车推着手机跑!

随着一季度财报陆续出炉,企业间的分化越来越明显。 新环境下,很多公司都陷入停滞时,去讨论“掉队”已经没有多少意义,现在真正值得我们关注的,是那些在逆风情况下,还能“领先”的企业。毫无疑问&#xff0…

小程序主体变更是通过迁移吗?是需要2个小程序吗?

小程序迁移变更主体有什么作用?好多朋友都想做小程序迁移变更主体,但是又不太清楚具体有啥用,今天我就来详细说说。首先,小程序迁移变更主体最重要的作用就是可以修改主体。比如你的小程序原来是 A 公司的,现在 A 公司…

2024-5-9-从0到1手写配置中心Config之@ConfigurationProperties热更新

在PropertySourcesProcessor中,需要通过http从config-server获取配置。 使用ConfigMeta包装服务信息 在MidnightConfigService接口中添加默认实现类 继承MidnightRepositoryChangeListener接口;获取默认的MidnightRepository;创建MidnightCo…

12306技术内幕

公司内部做的一次技术分享 文章目录 12306的成就12306系统特点12306系统难点解决思路产品角度技术角度余票库存的表如何设计? 抢票软件推荐巨人的肩膀 对于未公开的技术部分,只能结合已公开的信息,去做大胆的猜想。 本文提到的一些解决方案&…

chatgpt线性差值 将直线渐变颜色

color(x)(x-x1)/(x2-x1) 与gpt给出的 这个位置比例可以表示为d/L是概念相同 x-x1是计算当前点距离起点距离,x2-x1是计算长度 例如,如果我们在直线上距离起点A的距离为d,整条直线的长度为L 用数学方式解释 2024/5/25 18:54:30 当我们要在一…

【算法例题】递推与递归

刚讲完递推和递归,趁热打铁,给大家出点例题。 没学过的,先去学一下。 【算法】递推&递归https://blog.csdn.net/yangyanbin_sam/article/details/139182393?csdn_share_tail%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22…

⌈ 传知代码 ⌋ 基于扩散模型的无载体图像隐写术

💛前情提要💛 本文是传知代码平台中的相关前沿知识与技术的分享~ 接下来我们即将进入一个全新的空间,对技术有一个全新的视角~ 本文所涉及所有资源均在传知代码平台可获取 以下的内容一定会让你对AI 赋能时代有一个颠覆性的认识哦&#x…

小红书无限加群脚本无需ROOT【使用简单无教程】

小红书无限加群脚本无需ROOT,包含了对应的小红书版本【使用简单无教程】 链接:https://pan.baidu.com/s/1HkLhahmHDFMKvqCC3Q3haA?pwd6hzf 提取码:6hzf

ISCC 2024 部分wp

文章目录 一、Misc1、Number_is_the_key2、FunZip3、擂台—— 重“隐”;4、RSA_KU5、时间刺客6、成语学习7、 精装四合一8、钢铁侠在解密9、有人让我给你带个话10、Magic_Keyboard11、工业互联网模拟仿真数据分析 二、Web1、还没想好名字的塔防游戏2、代码审计3、原…

【C++】<图形库> 三人成棋(面向对象写法)

目录 一、游戏需求 二、程序架构 三、代码实现 四、实现效果 五、已知BUG 一、游戏需求 构建一个五子棋游戏,在自定义棋盘宽度和高度的基础上,实现三人对战功能,并且能判定谁输谁赢。 二、程序架构 (1) 对象分析: 【1】 需…

人工智能-YOLOv10-行人和车辆检测-yolo改进测距测速代码和原理

YOLOv10: 实时端到端目标检测技术的全新突破 YOLOv10代表了实时目标检测领域的重大进展,是YOLO系列模型的最新迭代,专为追求极致效率与精度平衡的应用场景设计。此项目由北京大学机器智能研究组(THU-MIG)的Ao Wang、Hui Chen、Li…

直击CHIMA 2024│美创全栈全新数安能力精彩亮相

5月17日,中国医院信息网络大会(CHIMA 2024)在南京正式拉开帷幕。本次大会以新质生产力理论为指导,以深化应用,融合创新,用信息技术赋能医院高质量发展为主题。 作为医疗数据安全的创新引领者和深耕实践者,美创科技再次…

IDEA通过tomcat运行注意事项

配置run--》edit configurations 以下的A B部分要保持一致 A和B的路径要保持一致

vue/core源码中ref源码的js化

起源: 当看见reactivity文件中的ref.ts文件长达五百多的ts代码后,突发奇想想看下转化成js有多少行。 进行转化: let shouldTrack true; // Define shouldTrack variable let activeEffect null; // Define activeEffect variable// 定义…

MATLAB system identification系统辨识app的使用

系统辨识 前言系统辨识第一步 选取时域数据到app第二步 分割数据第三步 设置传递函数的参数第四步 Estimate第五步 结束 前言 接上节:simulink-仿真以及PID参数整定 系统模型的辨识工作,在控制领域,一般用于开发控制器的先手工作。一般而言…

curl: (60) SSL certificate problem: self-signed certificat

目录: 1、背景2、测试结果 1、背景 今天帮忙客户排查问题,报错请求超时,但是ping客户的ip以及测试端口都是通的,最终不得不从中台服务器上发起请求客户回调接口,报错如下: 怀疑是客户的证书有问题&#xf…

测试网0撸大毛 — AI 公链ALIENX推出HAL Testnet活动(含保姆级教程)

近期,OpenAI推出了新一代的GPT-4o让AI再次获得关注。AI硬件销售商英伟达的股价也突破1000美元,市值攀升到2.6万亿美元。AI继续影响到我们生活的方方面面。 在加密货币行业,市场行情也逐渐走出低谷。以太坊现货ETF被批准,为整个市场…

51单片机 简单计算机实现

书接上回;http://t.csdnimg.cn/T4b0W 键盘位置如上 效果图 因为是四位,就没显示等于号, 而且段数比较少 显示不出来加号 所以 A ; B - ; C *; D / 基本原来都一样. 代码奉上 #include <reg51.h>#include <STRING.H>//利用矩阵键盘按键按下依次在数码管显…

九、OpenAI之图片生成(Image generation)

学习用DALL.E的API怎样生成和操作图片 1 介绍 图片API提供3个方法来和图片进行交互&#xff1a; 从0开始基于文字提示创建图片(DALL.E 3 and DALL.E2)基于一个新的提示词&#xff0c;通过让模型替换已有图像的某些区域来创建图像的编辑版本;&#xff08;DALL.E2&#xff09;…