问题描述
- 同样是a++同样是*3结果为什么不一样呢
-
int a=2 ;int b=a+3*a++
int a=2 ;int b=(a++)+3*a
第一个b=8第二个b=11
结果为什么不一样啊
解决方案
哎,怎么还这帖子呀,这实际单纯是编译器谁写的就是什么规则。
从java来说,一个表达式来了,边扫描边取数,符合规则就计算,不是说一看到表达式就去计算运算符的优先级高的部分,它也得从左往后解析过去。
int b=a+3*a++
就比如上面这句话,表达式是a+3*a++,从左往后扫描,扫描到a,取a的值2,后面是+号,+号运算需要2个数,还需要往下扫描一个数,扫描到是3,但发现3后面是*,优先级高于+号,乘号也是需要2个数,接着取下一个数a(值是2),再往下扫描是++,优先级高于*号。
根据扫描顺序,你可以得到一个独立的指令列表(栈)2,3,2,++,*,+这么一组指令。执行++后,原来的a的值是3(这改的不是栈中的,是a变量的值),所以表达式计算中还是2*3+2
如果上面表达式改成
int b=3*a++ + a的话,那结果就不一样了
从左往右扫描,取常数3,往下扫描是乘号,需要再取一个数,是a,取a的值2,接着扫描下一个,发现是++,优先级高于乘号。接着往下扫描,发现是+号,优先级低于前面。则前面可以先运算了。
前面的指令列表是 3,2,++,*。执行++,原来的a的值是3(这改的不是栈中的,是a变量的值),执行乘,3*2=6,这是后再看是+号,取下一个数,是a,取值,这时候值是3了,已经改变了。所以变成6+3=9.
大概过程是这么一个过程。
各种语言同一行的编译和执行方式都有些差异的,这得看具体的语言,比如C语言就不会出现9。
如果自己还不清楚,建议去看看JVM相关的指令编译和执行过程相关的内容。
另外,把前面的帖子结了吧。
解决方案二:
再和你说一次,这是未定义行为。未定义行为的结果取决于编译器的实现,没有任何为什么可以问。
除非你拿编译器的实现,以及编译器产生的目标代码去分析,但是这是本末倒置的。
另外,a++表达式求值和a++表达式是两个不同的概念。
解决方案三:
还在纠缠这个问题啊。
这个问题解释了比不解释还不好。因为每个C/C++的实现可能是不一样的,不能保证在这个编译环境下的结果是11,就是所有的编译环境下都是11
简单来说就是.a++是先用后加.在这里我们看到的是按表达式的顺序来计算的.每个子表达式完成后,马上计算++;但是也有的编译器是把表达式全部计算完之后再统一计算++的.
所以最好的办法就是别用这样的方法
解决方案四:
就一点想不明白b=a+3*a++不应该是b=3+3*2呢
解决方案五:
非常感谢各位大神的解答 使我明白了 特别是caozhy和danielinbiti这两位大神对于我多次提同一个问题非但没有感到厌烦而且还多次悉心的回答 使我非常感动 我是新手菜鸟 未来学习编程的路还很长 希望得到各位大神的教导 希望各位大神能多传授我点经验和知识
谢谢
解决方案六:
蛋疼的想法。
为啥要搞出这些带有二义性的代码了,让后面维护的娃情可以堪。出于业界良心,还是加圆括号指明优先级吧。
int a=2 ;int b=(a++)+3*a
像这个,蛋碎一地呀,不要想当然a++会先被执行呀,加法是有交换律的,但是编译器并没有交换律!!!
解决方案七:
第一个是先*3再加,加的没有意义,等价于
int a=2 ;int b=a+3*a;;a=a+1;
第二个是先加,然后再乘,等价于
int a=2 ;a=a+1;int b=a+3*a;
解决方案八:
int a=2 ;int b=a+3*a++
int a=2 ;int b=(a++)+3*a
第一行b=2+3*2=8,然后a++,a=3;
第二行,先是括号中(a++);这个结果是(a++)=2,然后a++,a=3;
最后b=2+3*3=11
你可以对照着看看
解决方案九:
从左到右计算,注意a++是在a运算后再自己+1,就像a++和++a的区别一样