表达式求值的优先级,结合性及隐式类型转化

news2025/1/16 17:43:16

文章目录

  • 前言
  • 一,操作符的属性
  • 二、1,表达式求值的优先级
    • 1,什么是优先级
    • 2,表达式的优先级表格
  • 三、表达式的结合性
    • 1,什么是表达式的结合性
    • 2,表达式的结合性表格
  • 四,隐式类型转换
    • 1,什么叫整型提升?
    • 2,如何整型提升?
    • 3,习题练习
    • 4,算数转换
  • 五,求值顺序
  • 总结


前言

路漫漫其修远兮,吾将上下而求索,在上次内容中小编介绍了有关于操作符的基本知识,但是操作符用来干什么的呢?毫无置疑操作符使用于表达式,在本次内容中小编将会带大家学习一下表达式的优先级和结合性,虽然该章内容设计知识是需要记的,但是还是一句话:熟能生巧,实践出真知,我们只有不断的写代码才能记住这些内容,而不是去死记硬背。好啦不多唠嗑了,开始我们的新内容吧,go go go!!!


提示:以下是本篇文章正文内容,下面案例可供参考

一,操作符的属性

复杂表达式的求值有三个影响的因素
1,操作符的优先级
2,操作符的结合性
3,是否控制求值顺序
两个相邻的操作符先执行优先级高的,如果两者的优先级相同,取决于他们的结合性。

接下来就通过下面这个表达式来引出大家对于这个问题的疑惑吧:下面表达式在计算机中的运算过程是怎么样的。而通过学习操作符的属性可以判断自己写的代码是否存在逻辑上的bug

int main()
{
	int x = 3 + 3 * 4 + 6;
	return 0;
}

二、1,表达式求值的优先级

1,什么是优先级

优先级指的是,如果一个表达式包含多个运算符,优先级高的运算符先执行。各种操作符的优先级是不同的。

2,表达式的优先级表格

在这里重点看到我黑体的那些

操作符名称
()聚组,也被称为括号
()函数调用
[ ]下标引用
.访问结构成员
->访问结构指针成员
++后置++
后置–
逻辑反
~按位取反
+单目操作符,表示正值
-单目操作符,表示负值
++前置++
前置–
*间接访问
&取地址
sizeof求长度,单位字节
(类型)类型转换
*乘法
/除法
%取余操作符(只能是整数)
+加法
-减法
<<左移
>>右移
>大于
<小于
==等于
!=不等于
&按位与
^按位异或
按位或
&&逻辑与
逻辑或
三目操作符
=赋值
逗号
分析

具体参考 表达式优先级表格,在这里我们可以发现赋值优先级几乎是处于最低的,在上面表格中在我们平常编译中常用的就是上面黑体部分的。具体其他的可以参考小编给的链接加以理解,接下来小编带大家熟悉一点操作符的优先级

int main()
{
	int x = 2 + 6 / 3; 
	return 0;
}
分析
在该表达式中,乘法的优先级高于加法优先级,所以先执行乘法,然后在执行加法,最后执行赋值运算

三、表达式的结合性

1,什么是表达式的结合性

如果两个表达式优先级相同,优先级没办法确定先执行哪个,这时候就看结合性了,则根据运算符是做结合还是右结合,决定执行顺序。大部分运算符是左结合(也即是从左向右计算),少数运算符是从右向左计算,比如赋值操作符,下面就介绍一些操作符的结合性吧

2,表达式的结合性表格

操作符结合性
()无结合性
后置++从左向右
后置 - -从左向右
从右向左
~从右向左
前置++从右向左
前置–从右向左
乘法从左向右
/从左向右
%从左向右
+从左向右
-从左向右
<<从左向右
>>从左向右
小于,等于,大于,不等于从左向右
&从左向右
^从左向右
按位或从左向右
&&从左向右
逻辑或从左向右
=从右向左
从左向右
#include<stdio.h>      
int main()      
{
	int y = 2 + 3 + 4; //优先级情况相同的话就要考虑结合性的问题      
	return 0;      
}
分析

在这里都是加号,优先级相同的情况下考虑结合性,加法的结合性是从左向右的所以,先2+3然后最后加上4,然后赋值优先级是从右向左,所以把加法所得的总值赋值给了y。


四,隐式类型转换

1,什么叫整型提升?

注意整型提升是一个表达式里面的类型达不到整型大小的char和short类型才会整型提升

1,表达式求值的顺序一部分是由操作符的优先级和结合性决定
2,同样,有些表达式的操作数在求值的过程中可能需要转换成其他类型
3,c的整型运算总是至少以默认整型类型的精度进行的
4,为了获得这个精度,表达式中的字符和短整型操作数在使用之前会被转换为普通整型,这种转换被称为整形提升

证明整型提升如下:

int main()
{
	char a = 3;
	printf("%d\n", sizeof(a));
	printf("%d\n", sizeof(+a));
	printf("%d\n", sizeof(-a));
	return 0;
}

在这里插入图片描述

分析
在这里可以看到第一个,sizeof操作符求解的第一个为字符变量a的字节大小,为1个字节;按照道理字符变量的运算得到最后的结果还是字符变量字节为1,但是第二个第三个最后得到值为4个字节,这是因为第二个和第三个为字符变量参与了表达式运算,c的整型运算总是至少以默认整型类型的精度进行的,但是为了获得这个精度,表达式中的字符和短整型操作数在使用之前会被转换为普通整型也就是整型提升由一个字节转换为四个字节。
int main()
{
	//隐式类型转换
	char a = 5;
	char b = 126;
	char c = a + b;
	printf("%d\n",c);
	return 0;
}
分析

在这里a是字符型,b也是字符型,char类型的数据在做运算之前(这里指加法)我们得先把a和b转换为普通整型,然后让它进行加法运算。这是为啥呢?因为表达式的整型运算在cpu的相应运算器内执行,cpu内整型运算器的操作数的字节长度一般是int的字节长度同时也是cpu的通用寄存器的长度。因此,即使两个char类型的相加,在cpu执行时实际也要先转换为cpu内整型操作数的标准长度。通用cpu是难以直接实现两个8比特也就是一个字节直接相加运算。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入cpu去执行运算。

2,如何整型提升?

整型提升是按照变量的数据类型来提升的

int main()     
{
	//负数整型提升     
	char c1 = -1;     
	char c2 = 1;     
	return 0;     
}
分析

首先-1在内存中存储的是二进制位的补码形式32个比特位,而变量c1的二进制位(补码)只有8个比特位,所以发生了截断,取了后面的八个比特位11111111,假如要对c1进行整型提升,在这里c1是有符号字符型,所以我们默认他的最高位为符号位,要进行整型提升,所以要把它变为整型类型32个比特位,则剩下缺的用符号位来补上。第二个c2为正数,和负数一样截断取八位,最后整型提升用符号位补齐。也就是用0补齐。而无符号整型提升,高位直接补零。

3,习题练习

1,求解c的大小

int main()
{
	char a = 5;
	char b = 126;
	char c = a + b;
	printf("%d\n", c);
	return 0;
}
分析
首先a是字符变量5,b是字符变量126,在进行a加b的运算中,先要将a和b转换为整型大小,也就是整型提升,最高位用符号位补齐得到下图;然后得到c的值但是c是字符型变量于是发生截断,得到八位数也就是八个比特位,运行到下一步骤,在这里需要以%d的形式进行打印,于是需要整型提升,但是此时最高位为1也就是代表他的符号位,然后整型提升剩下用1补齐,此时得到反码将之转换为原码转换成十进制得到-125。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/4d885308b0af4aa3b1eaf50669adaafb.png)

2,整型提升的例子

int main()
{
	char a = 0xb6;
	//10110110 整型提升这里最高位默认为1所以剩下的用0补齐
	short b = 0xb600;
	//1011011000000000
	int c = 0xb6000000;
	if (a == 0xb6)
		printf("a");
	if (b = 0xb600)
		printf("b");
	if (c = 0xb6000000)
		printf("c");
	return 0;
}

在这里插入图片描述

分析

在这里例子中的a和b要进行整型提升,但是c不需要进行整型提升,a和b整型提升后变成了负数,所以表达式a==0xb6,b=0xb600的结果是假,但是c不发生整型提升,所以表达式c=0xb6000000的结果为真。最终结果就执行了第三个判断语句后面的结果。

4,算数转换

算数转换是那些类型大于等于整型大小的类型进行表达式运算的隐式转换

如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作就无法进行。下面的为寻常算术转换

操作数类型字节大小
long double8
double8
float4
unsigned long int4
long int4
unsigned int4
int4

在这里如果操作数的类型在上面的表格较低,那么首先要转换为另外一个操作数的类型后执行运算,也就是说如果包含int和float要转换为float类型进行运算

五,求值顺序

在这里求值顺序就几个我给大家列出来

操作符名称
&&逻辑与
逻辑或
三目操作符
逗号表达式
分析

在这里为啥会影响,在这之前小编讲述了有关与c语言操作符的知识: 详解c语言操作符(下篇),关于逻辑与操作符我们判断之前如果有假的话后面语句就不再执行,这就是影响了求值顺序,本来逻辑与操作符执行顺序是从左到右依次执行但是只要出现假的话后面语句就不会再执行了。同样的逻辑或也是一样的原理。对于三目操作符,表达式1为真,表达式2计算,表达式3不计算选择性的执行表达式的内容。逗号表达式从左向右依次计算,但是真正取到决定性作用的是最后一个表达式的结果,最后一个表达式的结果是整个表达式的结果。


总结

我们写出的表达式如果不能通过操作符的属性确定唯一的计算路径,那这个表达式就是存在问题的。
以上就是今天要讲的内容,本文仅仅简单介绍了表达式求值的优先级和结合性,而具体使用和记忆得各位读者在日常代码中了,学习不是一蹴而就的活,小编只是简单介绍了表达式求值的过程中遇到的相关计算,如果各位读者忘记了能有资料回头看看就收藏一下吧。

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

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

相关文章

032 - STM32学习笔记 - TIM基本定时器(一) - 定时器基本知识

032 - STM32学习笔记 - TIM定时器&#xff08;一&#xff09; - 基本定时器知识 这节开始学习一下TIM定时器功能&#xff0c;从字面意思上理解&#xff0c;定时器的基本功能就是用来定时&#xff0c;与定时器相结合&#xff0c;可以实现一些周期性的数据发送、采集等功能&#…

[JS设计模式]Mixin Pattern

Mixin是一个对象&#xff0c;我们可以使用它来为另一个对象或类添加可重用的功能&#xff0c;而无需使用继承。我们不能单独使用mixins:它们的唯一目的是在没有继承的情况下向对象或类添加功能。 假设对于我们的应用程序&#xff0c;我们需要创建多个狗。然而&#xff0c;我们…

JavaWeb笔记之JSP

一、引言 现有问题 在之前学习Servlet时&#xff0c;服务端通过Servlet响应客户端页面&#xff0c;有什么不足之处&#xff1f; 开发方式麻烦&#xff1a;继承父类、覆盖方法、配置Web.xml或注解。 代码修改麻烦&#xff1a;重新编译、部署、重启服务。 显示方式麻烦&#x…

Linux创建macvlan 测试bridge、private和vepa模式

Linux创建macvlan&#xff0c;测试bridge、private和vepa模式 最近在看Docker的网络&#xff0c;看到关于macvlan网络的介绍。查阅了相关资料&#xff0c;记录如下。 参考 1.Linux Macvlan 2.图解几个与Linux网络虚拟化相关的虚拟网卡-VETH/MACVLAN/MACVTAP/IPVLAN 环境 操…

[THUPC 2024 初赛] 二进制 (树状数组单点删除+单点查询)(双堆模拟set)

题解 题目本身不难想 首先注意到所有查询的序列长度都是小于logn级别的 我们可以枚举序列长度len&#xff0c;然后用类似滑动窗口的方法&#xff0c;一次性预处理出每种字串的所有出现位置&#xff0c;也就是开N个set去维护所有的位置。预处理会进行O(logn)轮&#xff0c;每…

Web前端复习

一、随堂练习 1.小题 margin vanish&#xff1a;border和inline-block都可以形成bfc二维数组转置&#xff1a;res[i] [];函数的不同声明定义&#xff1a; 有变量名字的函数&#xff0c;即便后面声明了同样的&#xff0c;以函数表达式为主&#xff1b;定义&#xff0c;运行。再…

智能优化算法应用:基于北方苍鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于北方苍鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于北方苍鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.北方苍鹰算法4.实验参数设定5.算法结果6.…

RocketMQ实践:确保消息不丢失与顺序性的高效策略

一、使用RocketMQ如何保证消息不丢失&#xff1f; 这个是在面试时&#xff0c;关于MQ&#xff0c;面试官最喜欢问的问题。这个问题是所有MQ都需要面对的一个共性问 题。大致的解决思路都是一致的&#xff0c;但是针对不同的MQ产品又有不同的解决方案。分析这个问题要从以 下几…

YOLOv5涨点技巧:一种新颖的多尺度滑窗注意力,助力小目标和遥感影像场景

💡💡💡本文全网独家改进:提出了一种新颖的多尺度滑窗注意力机制,有效的应用在遥感影像和小目标场景,实现涨点。 收录 YOLOv5原创自研 https://blog.csdn.net/m0_63774211/category_12511931.html 💡💡💡全网独家首发创新(原创),适合paper !!! �…

数据校园服务管理系统,教育平台可视化界面(教育资源信息化PS文件)

大屏组件可以让UI设计师的工作更加便捷&#xff0c;使其更高效快速的完成设计任务。现分享大数据校园服务管理系统、科技教育平台大数据可视化界面、教育资源信息化大数据分析等Photoshop源文件&#xff0c;文末提供完整资料&#xff0c;供UI设计师们工作使用。 若需其他 大屏…

Leetcod面试经典150题刷题记录 —— 哈希表篇

Leetcod面试经典150题刷题记录 —— 哈希表篇 1. 赎金信2. 同构字符串(按逻辑完整性&#xff0c;分次书写代码)3. 单词规律4. 有效的字母异位词4.1 进阶: 输入字符串包含 unicode 字符 5. 字母异位词分组6. 两数之和7. 快乐数hash集合检测循环隐式链表快慢指针&#xff08;弗洛…

非线性约束的优化问题_序列二次规划算法代码

1. 理论部分 2. 序列二次规划算法代码及解析 3.完整代码 1.理论部分 a.约束优化问题的极值条件 库恩塔克条件(Kuhn-Tucker conditions&#xff0c;KT条件)是确定某点为极值点的必要条件。如果所讨论的规划是凸规划&#xff0c;那么库恩-塔克条件也是充分条件。 &#xff…

JBoss JMXInvokerServlet 反序列化漏洞 CVE-2015-7501 已亲自复现

JBoss JMXInvokerServlet 反序列化漏洞 CVE-2015-7501 已亲自复现 漏洞名称漏洞描述影响版本 漏洞复现环境搭建漏洞利用 修复建议总结 漏洞名称 漏洞描述 在Oracle Rapid Planning 12.1/12.2.2中发现了一个被归类为“严重”的漏洞。受到影响的是一些未知的组件处理中间层。升…

SQL进阶理论篇(二十):什么是SQL注入

文章目录 简介SQL注入的原理SQL注入的实例搭建sqli-labs注入环境实例一&#xff1a;猜测where条件判断查询语句的字段数获取当前数据库和用户信息获取MySQL中的所有数据库名称查询wucai数据库中的所有数据表查询heros数据表中的所有字段参考文献 简介 这节是纯兴趣篇了。 web…

RocketMQ事务消息实现分布式事务

文章目录 简介实现原理实现逻辑 简介 RocketMQ事务消息 RocketMQ在4.3.0版中支持分布式事务消息&#xff0c;这里RocketMQ的事务消息是采用2PC(两段式协议) 补偿机制&#xff08;消息回查&#xff09;的分布式事务功能。提供消息发送与业务落库的一致性。 RocketMQ事务消息&am…

MicroPython的交互式解释器模式 REPL

MicroPython的交互式解释器模式又名REPL&#xff08;read-eval-print-loop&#xff09;&#xff0c;就是一种命令输入交互模式&#xff0c;跟Python的REPL是类似的&#xff0c;就是在命令行直接输入Python代码或表达式执行并打印结果。关于MicroPython的REPL跟通常的Python类似…

电子病历编辑器源码,提供电子病历在线制作、管理和使用的一体化电子病历解决方案

概述&#xff1a; 电子病历是指医务人员在医疗活动过程中,使用医疗机构信息系统生成的文字、符号、图表、图形、数据、影像等数字化信息,并能实现存储、管理、传输和重现的医疗记录,是病历的一种记录形式。 医院通过电子病历以电子化方式记录患者就诊的信息&#xff0c;包括&…

【常见的语法糖(详解)】

&#x1f7e9; 说几个常见的语法糖 &#x1f7e2;关于语法糖的典型解析&#x1f7e2;如何解语法糖&#xff1f;&#x1f7e2;糖块一、switch 支持 String 与枚举&#x1f4d9;糖块二、泛型&#x1f4dd;糖块三、自动装箱与拆箱&#x1f341;糖块四、方法变长参数&#x1f5a5;️…

Linux多线程:POSIX信号量,基于信号量的环形队列实现生产者消费者模型

目录 一、POSIX信号量1.1 初始化信号量1.2 销毁信号量1.3 等待信号量1.4 发布信号量1.5 基于环形队列的生产消费模型(用信号量控制生产者和消费者之间的同步互斥关系)1.5.1 makefile1.5.2 RingQueue.hpp1.5.3 Sem.hpp1.5.4 Task.hpp1.5.5 main.cc 二、信号量控制的环形队列原理…

.Net 访问电子邮箱-LumiSoft.Net,好用

序言&#xff1a; 网上找了很多关于.Net如何访问电子邮箱的方法&#xff0c;但是大多数都达不到想要的需求&#xff0c;只有一些 收发邮件。因此 花了很大功夫去看 LumiSoft.Net.dll 的源码&#xff0c;总算做出自己想要的结果了&#xff0c;果然学习诗人进步。 介绍&#xff…