c语言表达式求值--整型提升

news2024/11/27 0:37:17

什么是整型提升?

C的整型算术运算总是至少以缺省整型类型的精度来进行的。 为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。

什么叫缺省整数类型?缺省在计算机里面是默认的意思。

这句话大概意思就是,在c语言的整数运算中,如果有精度小于整型的非自定义类型数,就需要先转换为一个整数类型。

比如char和short int类型,它们的字节数分别为1、2,如果它们参与整数表达式的运算就会先转换成整数类型,再参与运算。

这里我们只谈论char和short int

代码举例:

int main()
{
	char a = 0x80;
	short b = 0x8000;
	int c = 0x86000000;
	if (a == 0x80)
		printf("a");
	if (b == 0x8000)
		printf("b");
	if (c == 0x86000000)
		printf("c");
	return 0;
}

看结果:

0d54d9484a714f45bd0b199538fb437f.png只输出了一个c。

为什么会这样呢?a、b变量被赋予的值也没有超出它们的字节大小代表的最大值,为什么a==0x80和b==0x8000会为假呢?

这其中就发生了整型提升。

 

整型提升的规则

1、操作数为int的时候,高位补充符号位

2、操作数为unsigned int(无符号整数)的时候,高位补充0

 分析例子

1.变量a整型提升:

首先,a占一个字节,在转换前被赋值0x80(十六进制),二进制(补码)表示为1000 0000。

符号位是1.

整型提升变成四个字节,前面补充1,就转换成了:

1111 1111 1111 1111 1111 1111 1000 0000

所以这个时候的a就不等于原来的数了,很明显这都变成了一个负数。

2.变量b整型提升:

首先,b占两个字节,在转换前被赋值0x8000(十六进制),二进制(补码)表示为:

1000 0000 0000 0000

符号位是1.

整型提升变成四个字节,前面补充1,就转换成了:

1111 1111 1111 1111 1000 0000 0000 0000

所以这个时候的b就不等于原来的数了,很明显这都变成了一个负数。

而c是int,不需要转换。

代码1:


int main() {
	char a = 0x80;
	char b = 0x80;
	int c = a + b;
	printf("%d", c);

	return 0;
}

这里又会输出什么结果呢?

因为运算涉及到整数,所以字符a和b在参与计算的时候会先整数提升,而根据上面我们知道,a整型提升之后是一个负数,所以得到:

edeec9cb8fed4fedbedfe75677c67981.png

 

代码2:

int main()
{
 char c = 1;
 printf("%u\n", sizeof(c));
 printf("%u\n", sizeof(+c));
 printf("%u\n", sizeof(-c));
 return 0;
}

这里我们要注意,我前面已经强调过,只有在参与运算的时候才会考虑是否要整型提升,而sizeof(c)里的c并没有参与运算,所以不需要整型提升,得到的还是一个字节。

那么sizeof(+c)和sizeof(-c)呢?c语言会认为(+c)和(-c)都是参与了运算,所以需要整型提升,得到的也就是一个整型的字节大小。

1a2e9b63568d46a69bc44b9d61712b7c.png

 

整型提升的意义?

表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度 一般就是int的字节长度,同时也是CPU的通用寄存器的长度。 因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长 度。 通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令 中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转 换为int或unsigned int,然后才能送入CPU去执行运算。

总的来说,整型提升的目的是为了保持表达式中操作数的一致性。当不同大小的整数类型参与运算时,较小的类型会被提升为较大的类型,以避免精度丢失和数据溢出的问题

 

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

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

相关文章

第三章 内存管理 一、内存的基础知识

目录 一、什么是内存 二、有何作用 三、常用数量单位 四、指令的工作原理 五、装入方式 1、绝对装入 2、可重定位装入(静态重定位) 3、动态运行时装入(动态重定位) 六、从写程序到程序运行 七、链接的三种方式 1、静态…

MySQL建表操作和用户权限

1.创建数据库school,字符集为utf8 mysql> create database school character set utf8; 2.在school数据库中创建Student和Score表 mysql> create table school.student( -> Id int(10) primary key, -> Stu_id int(10) not null, -> C_n…

服务运营 |摘要:学术+业界-近期前沿运筹医疗合作精选

推文作者:李舒湉 编者按 本文归纳整理了近期INFORMS Journal on Applied Analytics中的相关业界合作研究。 这些研究成果体现了运筹学在医疗健康领域实践的效果。文中的学术业界合作使用了不同的研究工具。第一篇文章使用仿真模型帮助诊所进行不同拥挤程度下诊所使用…

【Java学习之道】日期与时间处理类

引言 在前面的章节中,我们介绍了Java语言的基础知识和核心技能,现在我们将进一步探讨Java中的常用类库和工具。这些工具和类库将帮助我们更高效地进行Java程序开发。在本节中,我们将一起学习日期与时间处理类的使用。 一、为什么需要日期和…

并发编程——1.java内存图及相关内容

这篇文章,我们来讲一下java的内存图及并发编程的预备内容。 首先,我们来看一下下面的这两段代码: 下面,我们给出上面这两段代码在运行时的内存结构图,如下图所示: 下面,我们来具体的讲解一下。…

解锁机器学习-梯度下降:从技术到实战的全面指南

目录 一、简介什么是梯度下降?为什么梯度下降重要? 二、梯度下降的数学原理代价函数(Cost Function)梯度(Gradient)更新规则代码示例:基础的梯度下降更新规则 三、批量梯度下降(Batc…

java io读取数据

1.字节流读取数据 2.字节流读取数据: read() package wwx;import jdk.swing.interop.SwingInterOpUtils;import java.io.*; import java.nio.charset.StandardCharsets;public class Test {public static void main(String[] args) {FileInp…

1.1 向量与线性组合

一、向量的基础知识 两个独立的数字 v 1 v_1 v1​ 和 v 2 v_2 v2​,将它们配对可以产生一个二维向量 v \boldsymbol{v} v: 列向量 v v [ v 1 v 2 ] v 1 v 的第一个分量 v 2 v 的第二个分量 \textbf{列向量}\,\boldsymbol v\kern 10pt\boldsymbol …

机器人制作开源方案 | 杠杆式6轮爬楼机器人

1. 功能描述 本文示例将实现R281b样机杠杆式6轮爬楼机器人爬楼梯的功能(注意:演示视频中为了增加轮胎的抓地力,在轮胎上贴了双面胶,请大家留意)。 2. 结构说明 杠杆式6轮爬楼机器人是一种专门用于爬升楼梯或不平坦地面…

thinkphp6 - 超详细使用阿里云短信服务发送验证码功能,TP框架调用对接阿里云短信发验证码(详细示例代码,一键复制开箱即用)

效果图 在thinkphp 5/6 框架(只要不是太低的版本就能用)中,实现接入调用阿里云短信服务详细教程,整个配置过程及示例代码保证小白也能轻松完成! 直接复制就行,改个阿里云参数就能用了。

MongoDB 简介和安装

一、MongoDB 相关概念 1.1 业务应用场景 1.1.1 三高需求 传统的关系型数据库(如 MySQL) ,在数据操作的 “三高” 需求以及应对 Web2.0 的网站需求面前,显得力不从心。”三高“ 需求如下所示,而 MongoDB 可应对 “三高…

C++入门指南:类和对象总结友元类笔记(下)

C入门指南:类和对象总结友元类笔记(下) 一、深度剖析构造函数1.1 构造函数体赋值1.2 初始化列表1.3 explicit关键字 二、static成员2.1 概念2.2 特性 三、友元3.1 友元函数3.2 友元类 四、 内部类4.1 概念4.2 特征 五、拷贝对象时的一些编译器优化六、深…

【C++】C++11 ——— 类的新功能

​ ​📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:C学习 🎯长路漫漫浩浩,万事皆有期待 上一篇博客:【C】STL…

JAVA中的垃圾回收

JVM规范说了并不需要必须回收方法区,不具有普遍性,永久代使用的是JVM之外的内存 引用计数:效率要比可达性分析要强,随时发现,随时回收,实现简单,但是可能存在内存泄漏 局部变量表,静态引用变量 …

Radius OTP实现VPN登录认证 安当加密

实现Radius OTP认证来完成VPN登录,需要使用支持Radius协议的VPN设备和客户端,以及一个Radius服务器来处理用户认证。 安当ASP身份认证平台作为一个企业通用的身份认证系统,集成了Radius认证功能,可满足所有支持radius认证的设备登…

【string题解 C++】字符串相乘 | 翻转字符串III:翻转单词

字符串相乘 题面 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。 注意:不能使用任何内置的 BigIn…

基本微信小程序的电影票务系统-电影票预订系统

项目介绍 在传统的模式下,电影购票需要到当地的影院进行线下购票,既浪费时间,又消耗人力。线上购票可以满足消费者查看电影信息及购买电影票的需求,在一定程度上降低经济和时间成本[9]。目前已有一些手机app可以线上购票&#xf…

优化|优化处理可再生希尔伯特核空间的非参数回归中的协变量偏移

原文:Optimally tackling covariate shift in RKHS-based nonparametric regression. The Annals of Statistics, 51(2), pp.738-761, 2023.​ 原文作者:Cong Ma, Reese Pathak, Martin J. Wainwright​ 论文解读者:赵进 编者按: …

无名管道和有名管道

进程间通信的几种方式 无名管道(pipe) 无名管道(Unnamed Pipe)是一种在进程间进行单向通信的机制。它可以用于父进程与子进程之间的通信,或者同一父进程中不同子进程之间的通信。无名管道是一种特殊的文件&#xff0…

【(数据结构) —— 顺序表的应用-通讯录的实现】

(数据结构)—— 顺序表的应用-通讯录的实现 一.通讯录的功能介绍1.基于动态顺序表实现通讯录(1). 功能要求(2).重要思考 二. 通讯录的代码实现1.通讯录的底层结构(顺序表)(1)思路展示(2)底层代码实现(顺序表) 2.通讯录上层代码实现(通讯录结构…