A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 了无尘 于 2012-5-14 20:56 编辑

                x = 5;
                System.out.println((x++)+1);
                System.out.println(x);

请问为什么x不是7,这个真是送分的。。。。如果你的回答是表达式完成之后,x才自增,那么看下边
第一题:答案
首先(x++)+1中的小括号毫无意义,小括号并不会改变++运算的优先级,对表达式自增运算符加括号绝大部分是因为需要进行代码的格式化,并告诉java++应该是如何被解释的,否则x+++x只会有一种解释方式。但要注意是否该自增变量的后一表达式元素是否为常量。如都为变量+++就存在2种情况。
其次,这一题里x+++1,也只能进行x++ + 1 这种分割,++1是不行的,常量无法自增。


                x = 5;
                System.out.println(x+++x++);
请问,为什么是11,不是10?
第二题:答案
这一题否定了一部分人所说的自增是表达式运算之后进行的,而另一个模糊的解释是x参加一次运算之后,看起来好像是对的。
分析表达式,会发现,如果是x参加一次运算,那么这个表达式就成了x+x    x++    syso(x)    x++,所以严格来说,是参与一次不为自己的运算,就好像是第一题一样。
我习惯用另一种方式来理解他,虽然这与实际赋值的顺序不一致,因为压后了,但是它好理解,x++的自增将会出现在下次x取值之前,有人用x++ + ++x来阐述。


好吧,有些人可能没有仔细想过我为什么要这么问,有些答案也很有出入,那么追加一个问题

                x=5;
                System.out.println(x+++1+x++);

请问为什么是12,++ 很多人都一知半解,第一题到第三题花了我点心思,希望你们能真的认真思考过,而不是照搬答案,那没有意义,如果你没有仔细查看第一到第三的变化,你会丢失一些知识,呵呵
第三题:答案
这一题将前两题综合了一下,表达式为 x+1   ++x  (5+1)+6  x++


                x=5;
                System.out.println(x+++x);

第四题很有意思,请问为什么是11,我对于你们的小括号很蛋疼,这个怎么加括号,呵呵,开个小玩笑
第四题:答案
这题我说的有意思是指,(x++) + x 和 x + (++x)虽然执行顺序上完全不一致,但是很神奇的是他们结果是一致的,原因不在多说。


以上4次能说明一些东西,但也还缺少一部分
                x=5;
                System.out.println(x++ + 1);
                System.out.println(x++ + x);

第五题,对比以上两行,为什么++的执行顺序完全不一致
第五题:答案
对于前4题,基本该说的,该看的,都差不多了,这里的第三题之所以我加了空格,这很好理解,因为x+++x并不会被java理解成x +  ++x。
而这个题也解释了我上边说为什么参与一次运算是错的,细想一下就可以明白。
x++ + 1被解释成x+1 x++
x++ + x被解释成 x++  x+x   这里为什么是这样呢,因为+x之前,x已经是6了


而这个问题可以使用
        x = 5;
        y = x;
        System.out.println(x+++y);

这样会发现结果为10,也就是说,x++ + y

后记:
自增和自减在实际应用是经常用到的,而在复杂的表达式中,你仍然需要用小括号合理解释到底是先加还是后加。

我的答案可以用来理解,但细微上解释跟字节码执行并不相同,如果想仔细了解,可以javap -c <class文件名>来查看字节码得到正规的执行顺序

如果本帖能让你学到一些东西,那么,恭喜^_^

点评

希望以后你能多发点这种帖子,对大家的学习很有帮助~  发表于 2012-5-14 22:54

评分

参与人数 4技术分 +2 黑马币 +61 收起 理由
kevindavid + 30 赞一个!
李斌 + 1 8楼和9楼的理解哪一个才是正确的啊 好晕哦~.
贠(yun)靖 + 1 + 30
职业规划-刘倩老师 + 1

查看全部评分

32 个回复

倒序浏览
x++应该这样理解:先使用x,使用一次后再+1;
System.out.println(x+++x++);和System.out.println((x++)+(x++));是等效的
第一次使用x++后x就变成了6所以运算结果就是11.
class Test
{
        public static void main(String[] args)
        {
                int x=5;

        //        System.out.println((x++)+1);
        System.out.println(x);

//                System.out.println(x+++x++);
//                System.out.println((x++)+(x++));
                //先使用x,x使用一次后就变成了6
                System.out.println(x+++x);
        }
}
回复 使用道具 举报
(x++)+1是一个表达式 相当于  int b = (x++)+1,x还是6
x+++x++ 从左到右,x先参与运算再加1,参与运算的是5,x变为6了
后面也是一样6参与运算,x变成7
总的值是5+6=11
回复 使用道具 举报
这个与运算符的优先级别有关。++的运算级别是高于+的,所以会先于运算。
                 x = 5;  
                System.out.println((x++)+1);//x=5先自取,再加1的运算结果为6,输出。之后再自增+1,x=6,
                简单的讲就是((x++)+1) =(x+1)。
                System.out.println(x);//上面x自增后x=6。

请问为什么x不是7,这个真是送分的。。。。如果你的回答是表达式完成之后,x才自增,那么看下边

                x = 5;
                System.out.println(x+++x++);//相当于(x++)+(x++) 相当于5+6=11。
   
Java中具体运算优先顺序为:
                                                                        
运算符优先级表                                                                                                           
优先级
运算符
结合性
1
() [] .
从左到右
2
! +(正)  -(负) ~ ++ --
从右向左
3
* / %
从左向右
4
+(加) -(减)
从左向右
5
<< >> >>>
从左向右
6
< <= > >= instanceof
从左向右
7
==   !=
从左向右
8
&(按位与)
从左向右
9
^
从左向右
10
|
从左向右
11
&&
从左向右
12
||
从左向右
13
?:
从右向左
14
= += -= *= /= %= &= |= ^=  ~=  <<= >>=   >>>=
从右向左


点评

你参见我的第三问,你说的++优先于+并不正确  发表于 2012-5-13 23:56
回复 使用道具 举报
因为++运算优先级大于+,所以=(x++)+(x++)
因为第一个(x++)中先取值再加1,所以应该是取5后x自增1,x=6了
因为第二个(x++)中也先取值再加1,所以应该取6后x自增1,x=7了
所以应该=5+6=11
回复 使用道具 举报
x++是自增以前参与运算, 如:int x=2;  System.out.print(x++); System.out.print(x) 结果为 2,3
++x是自增以后参与运算,如:int x=2;  System.out.print(++x); System.out.print(x) 结果为 3,3
回复 使用道具 举报
四楼已经解决。
回复 使用道具 举报
马浩 中级黑马 2012-5-13 12:12:29
8#
   x = 5;
                System.out.println((x++)+1);//x在完成运算后才自增
               System.out.println(x);

请问为什么x不是7,这个真是送分的。。。。如果你的回答是表达式完成之后,x才自增,那么看下边

                x = 5;
                System.out.println(x+++x++);//在运算过程中,第一个x++自增后参与了运算,而第二个是运算后才自增,所以是6+5=11
请问,为什么是11,不是10?

所以,按照运算顺序,如果只有一个x++,x将在运算后才自增;当存在多个x++参与运算时,最后一个参与运算的x++将在x参与运算后,才自增,
如x+++x+++x++=6+7+5=18,最后一个x在运算和前面做加法运算时,没自增

点评

你这个我觉得刘老师分给少了,呵呵  发表于 2012-5-13 23:54
回复 使用道具 举报
本帖最后由 龚正军 于 2012-5-15 18:28 编辑

我怎么感觉4楼,8楼全部错了啊!! 怎么可能X++还会在表达式还没结束前就开始自增了。--------表示解释无法说得走啊!

楼上解释方法我表示很郁闷!老师加了分就仿佛解释正确的了。我觉得其实全部错了,好不!!!


计算机在运算的时候没你们想的那么复杂,我先在楼上5道题目解释下,然后再把正确答案一一解释,所有人在提出自己论点的时候希望跟我一样,认真的实践过,用JAVA编程验证下,别误人子弟!!!

第一题: x = 5;
               System.out.println((x++)+1);------------------------------------答案:6     -------------------------------原因如同上面所说:X++,是表示X仍然是5,等表达式结束后变成6,但是(X++)+1=6,然后计算机知道X=6被赋值了,但是已经打不出来了,千万注意前6和后6完全两码事!  前一个6是X+1得的,后一个6,是X表达式结束后X++得的。

               System.out.println(x);-----------------------------------------------答案:6 ----------------------------------由于上面X++已经被重新赋值了,所以X现在是后一个6,也就是X++重新赋值的6.



第二题: x = 5
              System.out.println(x+++x++);------------------------------------答案:11---------------------------------  相当于:x+(++x++);  问题关键是:计算机读取在同优先级时是从左读到右的,也就是先读X然后再读+,这时计算机认为X准备+后面的数据,于是后面 就成为了:
                                                                                            (x+)(++x++) =5+6=11,  ++X大家都应该清楚是属于先加,这点的X是6。后面的++是表达式过后才加,对于结果无影响,忽略掉,后面都如此,不再累述!
                                                                                               所以5+6=11.      

                                                                                                                       

第三题  x=5;
              System.out.println(x+++1+x++);---------------------------------答案:12--------------------------------- 相当于:x+(++(1+x)++); 基本道理同上,唯一区别是增加了基本数据 1,因为计算机读取到X然后+,也就是计算机,
                                                                                             认为X+准备加后面数据了,但是后面是非法数据++1,只有变量才能自增,常数是非法自增的,所以1+X然后再自曾:++(1+x),最后得5+7=12.



第四题 x=5;
              System.out.println(x+++x);----------------------------------------答案:11---------------------------------上面已解释 相当于:x+(++x);得:5+6=11



第五题   x=5;
               System.out.println(x++ + 1); -----------------------------------答案:6--------------------------------- 区别是多了空格,但空格无意义,有跟没有一个样子 相当于:x++ +1 =x+++1=5+1=6;但要说明下为什么这点X后面“+”没判定成+而是++,原因是++1是非法的,所以计算机自动调整成(x++)+1;------------原因是出现了常数1,同时说明下x++1是非法的。
               System.out.println(x++ + x);-------------------------------------答案:11--------------------------------- 跟上面一样,有跟没有一样 相当于:x+(++x);

注意:后面追加的括号()是为了方便解释计算机运行的先后,但是如果直接加括号代替会出现很多非法错误,比如:++X++类错误!




---------------------------------------------------------------------------------割掉啊,都焦了!!----------------------------------------------------------------------------------------------





重点题目:x+++x+++x++ =(x+)(++x+)(++x++)=5+6+7=18;-----------------------------------------第一个X+是5,但是到第2个++X+的时候X在前面赋值后还是5,自增变6,第3个X时候,++X++本身为上一次赋值(就是第2个X的赋值)的6,自增为7,

然后我们再追加:X+++X+++X+++X+++X+++X+++X++=5+6+7+8+9+10+11=56;同上面的道理,自己验证,
然后我们再再追加:++x+++x+++x++      =(++x+)(++x+)(++x++)=这题是错误的,但是错误的提示会直接告诉你X后面跟的是+号这个问题,他的错误提示是:运算符+不能应用于<any>.int.但是这个问题是第一个"+"号引起的引用不明确错误,但从这点可以知道第3个“+”是加号。
            




点评

虽然有细微地方略有不妥,不过基本上都对了,你这么仔细的我还是首次在论坛看见,已经请刘老师多给分了,呵呵,祝你早日到黑马  发表于 2012-5-14 20:44

评分

参与人数 4技术分 +3 黑马币 +43 收起 理由
李斌 + 10 向你学习~~
Akm + 3 不错就是这格式 太不美观了 了无尘 你是黑.
贠(yun)靖 + 3 很给力!
刘蕴学 + 30 赞一个!

查看全部评分

回复 使用道具 举报
第一题 6,6,第一个是5+1,第一个是X自增后+1
第二题是 11,第一个x先参与运算在++自增了1,在加上6++
第三题是12,x先参与运算后自增为6,然后5+1+6++   
第四题是11,因为最后一个X后面没有++,所以是x+(++x)=11  
第五题是 6,,13  ,第一个x+++1因为常量不能自增,所以是x先++在+1,第二问因为上面x自增完等于6了,x+(++x)等于13,原因和第四问一样!

虽然考试天天考这些坑人的自增自减题,但是不知道我的理解对不对,希望指点下

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

回复 使用道具 举报
同学们,看下这个


class YunSuanDemo
{
        public static void main(String[] args)
        {
                int y1,y2,y3,y4,y5,y6,y7,y8,x1=5,x2=5,x3=5,x4=5,x5=5,x6=5,x7=5,x8=5;
               
                //第一个算法:
                y1 = x1++;
                sop("第一个算法:y1="+y1+"...x1="+x1);        //第一个算法:y1=5...x1=6
               
                //第二个算法:
                y2 = ++x2;
                sop("第二个算法:y2="+y2+"...x2="+x2);        //第二个算法:y2=6...x2=6
       
                //第三个算法:
                y3 = (x3++ +1);
                sop("第三个算法:y3="+y3+"...x3="+x3);        //第三个算法:y3=6...x3=6

                //第四个算法:
                y4 = x4++ + x4++;
                sop("第四个算法:y4="+y4+"...x4="+x4);        //第四个算法:y4=11...x4=7

                //第五个算法:
                y5 = x5++ +1+ x5++;
                sop("第五个算法:y5="+y5+"...x5="+x5);        //第五个算法:y5=12...x5=7

                //第六个算法:
                y6 = x6++ +1+ x6;
                sop("第六个算法:x6="+y6+"...x6="+x6);        //第六个算法:x6=12...x6=6
        }
        public static void sop(Object obj)
        {
                System.out.println(obj);
        }
}




评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1 赞一个!

查看全部评分

回复 使用道具 举报
观看中,求分。
回复 使用道具 举报
x++是先操作再自增
++x是先自增在操作
回复 使用道具 举报
好帖!!!
回复 使用道具 举报

回帖奖励 +10

金钱数目有什么用?还有,我注册的时候没用真实姓名,如果更改?
回复 使用道具 举报
顶一下楼主,太给力了!
回复 使用道具 举报
第一题答案,对于(x++)+1,是先运算x+1后,在将x自增,然后重新赋值给x。即(x++)+1=6,x=6.
第二题答案,x+++x++,可以理解成x+(++x++),就可以理解为5+(6++)小括号内的x自增,然后将x与x++的和再自增后重新赋值给x,即该运算结束后,表达式结果为11,但x=12.
追加题这时候根据第一题第二题就可以理解为x+(++(1+x)++),即先运行x+1=6,然后就变为x+(++y++),此时y=6,这时候同第二题。
第四题就理解为x+(++x),即5+6=11.
第五题应该是计算机不认识++1的过程,所以转换成(x+1)++,同理x++ +x可以表示为(x++) +x,即先自增,在求和。
有错指出请指教。


回复 使用道具 举报
孙峰 黑马帝 2012-5-15 13:40:05
18#
请问9楼的第二题里,“ 相当于:x+(++x++);  ”那我这么写程序就提示错误啊

QQ截图20120515133455.png (5.56 KB, 下载次数: 83)

QQ截图20120515133455.png
回复 使用道具 举报
呵呵!却是学好好多东西!!9楼的得自己去研究下!!
回复 使用道具 举报
本帖最后由 龚正军 于 2012-5-15 18:32 编辑
孙峰 发表于 2012-5-15 13:40
请问9楼的第二题里,“ 相当于:x+(++x++);  ”那我这么写程序就提示错误啊



其实我在上面已经在最后讲解过这问题了我说了++x+++x是指向错误!!!
这个错误是由于前面说了:我再用一个例子解释下这个问题的发生 ,避免其他同学也遇到这问题:

如在:++x++时候,java判定前两个++x已经累加了X一次,但是后面两个++就“不是”X++了(你的误会就产生在这),他会认为X是+(加)上了一个“+”(此+号算字符所代替的ASCII代码数字)java不允许+去加一个“+”这个非int,所以提示了错误(上面最后我已经提示过这问题的发生了)。
而你吧X+++X++加括号成:x+(++x++),那么括号里面就具备了优先级,所以相当于++x++,JAVA是不允许你加一个加号的。--------所以报错!(我上面就是用这个错误来证明第3个+是JAVA优先识别成加号的)

PS:我9楼的回答是我凌晨学习的时候弄的,当时很累了,论坛回答的那个排版不熟,郁闷我半天,修改N次,弄了我快2小时,所以很多字打错啊,还有解释得很模糊啊,请大家多谅解啊,抱歉,抱歉!!)
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马