C语言---详解问题表达式

目录

1.表达式1

2.表达式2

3.表达式3

4.表达式4

5.表达式5


1.表达式1

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

表达式的求值部分又操作符的优先级和结合性决定。但是并不能完全决定计算顺序,这会根据编译器的不同而体现不同的计算顺序;

表达式1中,在计算的时候,由于乘法*的优先级高于加法,只能保证相邻情况下,*的计算比+的计算更早,如:并不能决定表达式中的第三个乘号*比第一个加号+更早执行。

所以表达式的计算顺序可能会分为两种。

第一种第二种
第1步a*b第1步a*b
2c*d2c*d
3a*b+c*d3e*f
4e*f4a*b+c*d
5a*b+c*d+e*f5a*b+c*d+e*f

 有人可能会想,虽然计算顺序不同,但是结果是一样的。那么这个表达式到底有没有问题呢?

其实是有的。如果表达式中的abcdef不单纯是变量,也是表达式的话。不同的计算顺序就会对abcdef的值造成影响,而导致不同的结果。

2.表达式2

c + --c;

 同理,--的优先级高于+只能决定--操作符在+的前面计算,但是我们并没有办法知道+操作符的左操作数的获取是在右操作数进行--之前还是之后;

假设c的值是4

第一种情况:左边的c是在右边的c自减之前就已经准备好了,那么结果就是4+3;

第二种情况:左边的c是在右边的c自减之后才准备好,那么结果就是3+3;

所以这个表达式仍然是有问题的,会造成歧义;

3.表达式3

#include<stdio.h>
int main()
{
    int i = 10;
    i = i-- - --i * (i = -3) * i++ + ++i;
    printf("%d\n",i);
    return 0;
}

经过上面两个表达式的讲解,我们可能已经无法明确知道这个表达式结果是什么了 。

事实也是如此,不同的编译器得到的结果也是不同的。

这道题出自《C和指针》;

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

有兴趣的读者,可以自行了解是什么运算顺序导致这些结果。 

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();中我们只能通过操作符的优先级得知:先计算乘法再计算加法;但是我们函数的调用先后顺序是不能用操作符的优先级决定的;

在vs2022上,我经过测试得到的结果是-10,那么这个结果是怎么得到的呢?

 就只能是 2 - 3 * 4;先调用第一个fun()再第二个fun()然后第三个fun(),最后再加减;

但是也有可能是4 - 2 * 3;得到-2的结果;

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;
}

在屏幕上会打印什么??

经过上次++,毫无疑问i的值肯定是4;

而在linux 环境gcc编译器,和vs2022上ret的结果分别是10和12;

这两种情况可能是3+3+4和4+4+4导致的;这是因为在执行第一个+号的时候第三++是否执行;仅凭借操作符的优先级和结合性是无法判断的;也就无法决定第一个+和第三个前置++的向后顺序。

  • 37
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值