操作符详解2(二)

简介: 本文介绍了编程中的操作符转换和表达式解析规则。当操作数类型不同时,会进行寻常算术转换,按照long double、double、float等类型顺序进行向上转换。表达式求值时,虽然操作符有优先级,但不能决定操作数的求值顺序,例如`a*b + c*d + e+f`中乘法先于加法,但具体计算顺序不确定,可能导致不同结果。同样,如`c++ + c--`这样的表达式也是有歧义的,因为++和--的左右结合性不能确定操作数的获取顺序。文章强调,复杂的表达式可能因编译器差异产生不同结果,应避免使用可能导致非唯一计算路径的表达式以减少潜在风险。

操作符详解2(一)+https://developer.aliyun.com/article/1520146?spm=a2c6h.13148508.setting.14.5a334f0ewLfWrY



2.算术转换


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


1. long double


2. double


3. float


4.unsigned long int


5.long int


6.unsigned int


7.int


如果某个操作数的类型在上面这个列表中排名靠后,那么首先要转换为另外一个操作数的类型后执行运算。


向上转换



三、问题表达式解析


1.表达式1


表达式的求值部分由操作符的优先级决定。


a*b + c*d + e+f


表达式1在计算的时候,由于*比+的优先级高,只能保证*的计算是比+早,但是优先级并不能决定第三个*比第一个+早执行


所以表达式的计算机顺序就可能是:


1 a*b


2 c+d


3 a*b + c*d


4 e+f


5 a*b + c*d + e*f



或者


1 a*b


2 c*d


3 e*f


4 a*b+c*d


5 a*b + c*d+ e*f



2.表达式2


c + -- c  ;


同上,操作符的优先级只能决定自减﹣﹣的运算在+的运算的前面,但是我们并没有办法得知,+操作符的左操作数的获取在右操作数之前还是之后求值,所以结果是不可预测的,是有歧义的。



3.表达式3


int main()

int i =10;

i=i-- - --i*( i = -3)+ i++ + ++i;

printf("i =%d\n", i);

return 0;


表达式3在不同编译器中测试结果:非法表达式程序的结果





4.表达式4


#include <stdio.h>

int fun()

{

static int count=1;

return ++count;

}

int main()

{

int answer;

answer= fun()- fun()* fun();

printf( "%d\n", answer);

return 0;

}

上述代码

answer = fun()- fun() * fun()

我们只能通过操作符的优先级得知:先算乘法,再算减法。

函数的调用先后顺序无法通过操作符的优先级确定。




5.表达式5


#include <stdio.h>

int main()

{

int i =1;

int ret=(++i)+(++i)+(++i);

printf("%d\n",ret);

printf("%d\n",i);

return 0;

}


VS2022编译结果:



gcc编译结果:



6.总结


即使有了操作符的优先级和结合性,我们写出的表达式依然有可能不能通过操作符的属性确定唯一的计算路径,那这个表达式就是存在潜在风险的,建议不要写出特别负责的表达式。

目录
相关文章
|
Ubuntu Windows
【Ubuntu/Arm】Ubuntu 系统如何链接有线网络(非虚拟机)?
【Ubuntu/Arm】Ubuntu 系统如何链接有线网络(非虚拟机)?
|
运维 监控 Linux
Centos开启snmp服务
Centos开启snmp服务
248 1
【最佳实践】如何用宜搭做商品进销存
宜搭支持通过直接配置实现进销存场景。支持的常用进销存场景有: 图书管理系统、会议室预定系统、积分管理系统等。现在,就以商品进销存为例,示意操作过程。
【最佳实践】如何用宜搭做商品进销存
|
9月前
|
Java 数据库连接 Maven
【YashanDB知识库】私有maven使用崖山JDBC驱动
本文介绍如何将YashanDB的JDBC驱动包(yashandb-jdbc-1.5.1.jar)安装到Maven本地仓库。通过使用`mvn install:install-file`命令,指定参数如`-Dfile`(jar路径)、`-DgroupId`、`-DartifactId`和`-Dversion`等,可完成打包。之后,在项目中只需在`pom.xml`中添加对应依赖即可使用该驱动,方便集成与管理。
|
机器学习/深度学习 PyTorch 算法框架/工具
彻底告别微调噩梦:手把手教你击退灾难性遗忘,让模型记忆永不褪色的秘密武器!
【10月更文挑战第5天】深度学习中,模型微调虽能提升性能,但也常导致灾难性遗忘,即学习新任务时遗忘旧知识。本文介绍几种有效解决方案,重点讲解弹性权重巩固(EWC)方法,通过在损失函数中添加正则项来防止重要权重被更新,保护模型记忆。文中提供了基于PyTorch的代码示例,包括构建神经网络、计算Fisher信息矩阵和带EWC正则化的训练过程。此外,还介绍了其他缓解灾难性遗忘的方法,如LwF、在线记忆回放及多任务学习,以适应不同应用场景。
1503 8
|
存储 编译器 C语言
|
Linux Windows
Installing, this may take a few minutes...WslRegisterDistribution failed with error: 0x80370114Err
Installing, this may take a few minutes...WslRegisterDistribution failed with error: 0x80370114Err
3939 3
|
前端开发 JavaScript
Select2(4.0.6)城市搜索
实现了城市列表的前端搜索,输入汉字、拼音首字母均可搜索,前端搜索。
1109 0
Select2(4.0.6)城市搜索
|
人工智能 大数据 云计算
拥抱不确定性:在技术迭代中寻找平衡点
【5月更文挑战第28天】 在快速变革的技术世界里,不确定性已成为常态。本文探讨了如何在不断的技术更新与个人技能提升之间找到平衡点。通过分析技术发展的趋势,提出了适应和利用不确定性的策略,并强调了持续学习的重要性。文章旨在为技术人员提供一种心态和方法论,帮助他们在不断变化的环境中保持竞争力。
|
前端开发 JavaScript
Bootstrap 5 保姆级教程(十三):滚动监听 & 侧边栏导航
Bootstrap 5 保姆级教程(十三):滚动监听 & 侧边栏导航