操作符—奇奇怪怪的表达式

🎸
作者:爱弹吉他的小奔同学
🎸
专栏:《C语言》
🎸
仓库:gitee(所有的代码都在这个仓库里面)
🎸
如果感觉学累了,那么就看一个视频放松一下吧,猜猜点进去你会看到什么😜(视频)
🎸
我向往以后悠闲的生活,但现在的我们正处于需要努力的年华

在这里插入图片描述
点赞收藏关注啦啦啦啦啦

在我们进行表达式相关的计算时,我们会用到操作符,就例如1+1啦,5*2啦,+4等等,我们需要遵守操作符相关的规则——优先级,结合性和是否控制求值顺序

但是,我们知道这些规则就可以写出没有问题的代码吗?

如果认为不可以,那么接下来看看有哪些例子
如果认为可以,那就更应该来看看有哪些例子,来丰富一下自己对操作符参与表达式运算的理解

表达式一🎸

a*b+c*d+e*f

有问题吗?

当然有问题了,我都写出来了怎么会没有问题嘞,你认为它操作符计算顺序有哪些呢?
请添加图片描述
(应该还有其他顺序,但是举出这两个)

我们可以看到,它的计算路径不唯一,但都符合操作符的运算规则,假如里面都是些5,6,1这些数字,那么我们计算出来的结果都是一样的
但是假如a,b,c这些里面是表达式呢?
你还持有没有问题的观念吗?

假如一个表达式的计算对另一个表达式的计算有所影响,那么计算顺序对计算结果是不是有很大的影响

因此我们在计算的时候,要确定唯一的计算路径,这是一个好习惯,可以有效的预防bug的出现

表达式二🎸

int c = 2;
c+ --c

请添加图片描述

--的优先度是大于+

c+ (--c)和c+ --c运算顺序都是一样的

它的计算路径唯一,那么有问题吗?
有问题

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

如果第一个c在进行–前就准备好了,存在了寄存器变量里面,就会是这样2+1=3
如果第一个c在进行–时还没有准备好,还没储存在寄存器变量里面,就是这样1+1=2

同一计算路径,两个输出结果,这个也是问题表达式

表达式三🎸

int main()
{
 int i = 10;
 i = i-- - --i * ( i = -3 ) * i++ + ++i;
 printf("i = %d\n", i);
 return 0;
}

看到这个代码,编译器都傻了,人都麻了,来看看不同编译器给的结果

结果编译器
-128Tandy 6000 Xenix 3.2
-95Think C 5.02(Macintosh)
-86IBM PowerPC AIX 3.2.5
-85Sun Sparc cc(K&C编译器)
-63gcc,HP_UX 9.0,Power C 2.0.0
4Sun Sparc acc(K&C编译器)
21Turbo C/C++ 4.5
22FreeBSD 2.1 R
30Dec Alpha OSF1 2.0
36Dec VAX/VMS
42Microsoft C 5.1

可以看到,如果你写出这样的代码,离炒咸鱼就不远了

表达式四🎸

int fun()
{
     static int count = 1;
     return ++count;
}
int main()
{
     int answer;
     answer = fun() - fun() * fun();
     printf( "%d\n", answer);//输出多少?
     return 0;
}

它的计算顺序是唯一的,先*-但是fun函数什么时候调用是不确定的,所以我们无法确定最后的结果是什么。就像这个图一样
请添加图片描述
这个也是问题表达式

表达式五🎸

#include <stdio.h>

int main()
{
 int i = 1;
 int ret = (++i) + (++i) + (++i);
 printf("%d\n", ret);
 printf("%d\n", i);
 return 0;
}

看完前面那些问题表达式,再看这个是不是有种感觉,它是有问题的
我们在两个环境下运行一下这个代码VS2019/Linux

在Linux环境下:
在这里插入图片描述

在VS2019环境下:
在这里插入图片描述

可以看到,结果也是不一样的,为什么呢?
我们来看看它们各自的运算顺序

Linux:
请添加图片描述

VS2013:
请添加图片描述

这也是问题表达式,这段代码中的第一个 + 在执行的时候,第三个++是否执行,这个是不确定的,因为依靠操作符的优先级和结合性是无法决定第一个 + 和第三个前置 ++ 的先后顺序

至于为什么会这样运算,看看汇编代码就可以很清楚的了解,至于如何看汇编代码可以查一查,我也会写关于这个的博客

总结🎸

总之,我们写出的表达式如果不能通过操作符的属性确定唯一的计算路径,那这个表达式就是存在问题的,我们要写出可以确定唯一的计算路径的表达式

  • 16
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小奔同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值