java表达式问题-同样是a++同样是*3结果为什么不一样呢

问题描述

同样是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的区别一样

时间: 2024-09-12 07:08:53

java表达式问题-同样是a++同样是*3结果为什么不一样呢的相关文章

Java表达式类型自动提升

[一道经典的Java面试题] short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错? 答案是:前者错,后者对.相信不管是否经历过java面试过,大家一定对这道题很熟悉.因为这道题确实太经典了,以至于成为了基本每个老师都会拿出来,当作课堂例题来讲.要说清这道题,首先看看java表达式类型转换规则. [java表达式类型转换] java是一门强类型语言,不仅每个变量具有指定的数据类型,它的表达式也有指定的数据类型.因此在不同类型之间进行

java表达式

问题描述 下列语句片段:inta=-67,b=116,c=78;intd=-a|b&c;System.out.println(d)的结果为(A)A.70 B.67C.78 D.56请问这题为什么选A?可以详细点么?谢谢 解决方案 解决方案二:整个表达式的运算顺序是:先对a取反,再对b和c取与,最后对前两部分取或,楼主可以运行下面的代码,然后手动计算一下结果:publicclassIntgerTest{publicstaticvoidmain(String[]args){inta=-67,b=11

求助,java表达式!!!!

问题描述 看java解惑pdf这本书遇到一个问题:当i是一个负奇数时,i%2等于-1而不是1,因此isOdd方法将错误地返回false.为了防止这种意外,请测试你的方法在为每一个数值型参数传递负数.零和正数数值时,其行为是否正确.这个问题很容易订正.只需将i%2与0而不是与1比较,并且反转比较的含义即可:publicstaticbooleanisOdd(inti){returni%2!=0;}如果你正在在一个性能临界(performance-critical)环境中使用isOdd方法,那么用位操

Java实现表达式二叉树_java

什么是二叉树,这里不再介绍,可以自行百度:二叉树.在这里利用java实现"表达式二叉树".  表达式二叉树的定义  第一步先要搞懂表达式二叉树是个什么东东?举个栗子,表达式:(a+b×(c-d))-e/f.将数字放在叶子节点,将操作符放在分支节点,就构成了一个二叉树,由于存储的是一个表达式,称之为"表达式二叉树". 童靴们可能好奇这个到底是怎么构建的?就拿45+23*56/2-5来说吧.首先取出第一个数字45放在叶子节点,遇到"+"后将其放到分支

一起爪哇Java 8(二)——Lambda表达式和方法引用

定义 Java 表达式有很多种,声明一个class是一个表达式,定义一个变量是一个表达式,写一个=赋值逻辑是一个表达式-- Lambda表达式是这样一个表达式: lambdaParameters -> lambdaBody 在lambdaParameters传递参数,在lambdaBody中编写逻辑.lambda表达式生成的结果就是一个函数式接口(上文提到过的).lambdaBody中的逻辑内容(各种表达式)不会在定义时执行,在实际函数式接口调用时才会执行. 举几个官方的例子看看: () ->

Java核心技术 卷Ⅰ 基础知识(原书第10版)

Java核心技术系列 Java核心技术 卷Ⅰ 基础知识 (原书第10版) Core Java Volume I-Fundamentals (10th Edition) [美] 凯S.霍斯特曼(Cay S. Horstmann) 著 周立新 陈 波 叶乃文 邝劲筠 杜永萍 译 图书在版编目(CIP)数据 Java核心技术 卷Ⅰ 基础知识(原书第10版) / (美)凯S. 霍斯特曼(Cay S. Horstmann)著:周立新等译. -北京:机械工业出版社,2016.8 (Java核心技术系列) 书

JSP由浅入深(3)— 通过表达式增加动态内容

js|动态  在我们前面的章节中,任何的HTML文件都可以转变成JSP文件,做法是通过改变它的扩展名为.jsp.当然,我们要知道是什么使得JSP有用呢?答案是嵌入Java的能力.将下列文本放置在一个以.jsp为扩展名的文件中,比如说这个文件为myjsp.jsp,然后将这个文件放置到你的JSP目录下并且在浏览器上看它.以下是具体的代码: <HTML> <BODY> Hello! The time is now <%= new java.util.Date() %> <

JSP由浅入深(3)-- 通过表达式增加动态内容

js|动态 在我们前面的章节中,任何的HTML文件都可以转变成JSP文件,做法是通过改变它的扩展名为.jsp.当然,我们要知道是什么使得JSP有用呢?答案是嵌入Java的能力.将下列文本放置在一个以.jsp为扩展名的文件中,比如说这个文件为myjsp.jsp,然后将这个文件放置到你的JSP目录下并且在浏览器上看它.以下是具体的代码: <HTML> <BODY> Hello! The time is now <%= new java.util.Date() %> <

EL表达式详细解析

<%@ page isELIgnored="true"%> 表示是否禁用EL语言,TRUE表示禁止.FALSE表示不禁止.JSP2.0中默认的启用EL语言. JSTL 标签 库由标签库和 EL 表达式语言两个部分组成. EL 在 JSTL 1.0 规范中被引入,当时用来作为 Java 表达式来工作,而该表达式必须配合 JSTL 的标签库才能得到需要的结果. 说明:在 JSTL 1.1 规范中, JSP2.0 容器已经能够独立的理解任何 EL 表达式. EL 可以独立出现在