`
thehim
  • 浏览: 2901 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

令我迷惑的 i++

阅读更多

令我迷惑的 i++

      我在准备面试时遇见了着样一道题:

java 代码
  1. public class Inc {   
  2.     public static void main(String[] args) {   
  3.         Inc inc = new Inc();   
  4.         int i = 0;   
  5.         inc.fermin(i);   
  6.         i = i++;      //陷阱   
  7.         System.out.println(i);   
  8.     }   
  9.     void fermin(int i){   
  10.         i++;   
  11.     }   
  12. }  

 

      令人不解的是最后的输出结果为什么不是我所期望的 1 ,而是 0 。希望能有人用通俗易懂的语言,深入地帮我解释一下,谢谢。 

分享到:
评论
18 楼 tedeyang 2007-11-26  
finaland 写道
和 thehim 探讨一下,他发帖的初衷是搞清楚  i++ 的自增在什么时候进行
觉得 tedeyang  和 Qieqie  两位解释得很清楚了 ,我续条狗尾
这个关于 i++ 的知识点,可能是考察赋值表达式运算优先级的问题,核心在于,赋值运算应该在最后进行

i=i++; 这个语句
第一步,表达式运算,计算 i++ 表达式的值(设为 x ,当前x=0),并保存到某个内存地址,当前 i=0;
第二步,自增变量值运算,计算 i++ 对 i 的影响 (i=i+1, i=1),并保存到变量 i 的内存地址,当前 i=1;
第三步,赋值预算,从内存地址中获取第一步的计算结果(表达式的值x,当前x=0)赋值给 i,当前 i=0;
运算结束后 i=0

个人总结:
一般的赋值表达式,计算优先级为:
1、计算各单元的值
2、计算表达式的值
3、赋值

如果 1 中计算单元为 i++ 形式,优先级为:
    1.1     计算 i++表达式的值(这个表达式的值 = i)
    1.2     i=i+1 自增在这里完成

例1:
i=i+++i+++(++i);[内存中 i=0]
运算过程
1、i=0+i+++(++i) [内存中 i=1];
2、i=0+1+(++i) [内存中 i=2];
3、i=0+1+(3) [内存中 i=3];
4、i=4 [内存中 i=4];

例2:
i=(--i)+i+++i++-(i--)+(++i) ;[内存中 i=0]
运算过程
i=(-1)+i+++i++-(i--)+(++i) [内存中 i=-1]
i=(-1)+(-1)+i++-(i--)+(++i) [内存中 i=0]
i=(-1)+(-1)+0-(i--)+(++i) [内存中 i=1]
i=(-1)+(-1)+0-(1)+(++i)[内存中 i=0]
i=(-1)+(-1)+0-(1)+1[内存中 i=1]
i=-2 [内存中 i=-2]

(以上2例仅在 java 1.4.2 中作过实验)

恩,也许只是 赋值运算 在先还是在后 的 基础问题
再往下深究也许真的是钻牛角了,但通过这几行代码揭开的细细一角,让我窥到了 java 编译之一斑,对研究 vm 又增添了兴趣
有乐趣如是,足矣

总结得不错。继续努力。
17 楼 finaland 2007-11-20  
和 thehim 探讨一下,他发帖的初衷是搞清楚  i++ 的自增在什么时候进行
觉得 tedeyang  和 Qieqie  两位解释得很清楚了 ,我续条狗尾
这个关于 i++ 的知识点,可能是考察赋值表达式运算优先级的问题,核心在于,赋值运算应该在最后进行

i=i++; 这个语句
第一步,表达式运算,计算 i++ 表达式的值(设为 x ,当前x=0),并保存到某个内存地址,当前 i=0;
第二步,自增变量值运算,计算 i++ 对 i 的影响 (i=i+1, i=1),并保存到变量 i 的内存地址,当前 i=1;
第三步,赋值预算,从内存地址中获取第一步的计算结果(表达式的值x,当前x=0)赋值给 i,当前 i=0;
运算结束后 i=0

个人总结:
一般的赋值表达式,计算优先级为:
1、计算各单元的值
2、计算表达式的值
3、赋值

如果 1 中计算单元为 i++ 形式,优先级为:
    1.1     计算 i++表达式的值(这个表达式的值 = i)
    1.2     i=i+1 自增在这里完成

例1:
i=i+++i+++(++i);[内存中 i=0]
运算过程
1、i=0+i+++(++i) [内存中 i=1];
2、i=0+1+(++i) [内存中 i=2];
3、i=0+1+(3) [内存中 i=3];
4、i=4 [内存中 i=4];

例2:
i=(--i)+i+++i++-(i--)+(++i) ;[内存中 i=0]
运算过程
i=(-1)+i+++i++-(i--)+(++i) [内存中 i=-1]
i=(-1)+(-1)+i++-(i--)+(++i) [内存中 i=0]
i=(-1)+(-1)+0-(i--)+(++i) [内存中 i=1]
i=(-1)+(-1)+0-(1)+(++i)[内存中 i=0]
i=(-1)+(-1)+0-(1)+1[内存中 i=1]
i=-2 [内存中 i=-2]

(以上2例仅在 java 1.4.2 中作过实验)

恩,也许只是 赋值运算 在先还是在后 的 基础问题
再往下深究也许真的是钻牛角了,但通过这几行代码揭开的细细一角,让我窥到了 java 编译之一斑,对研究 vm 又增添了兴趣
有乐趣如是,足矣
16 楼 Qieqie 2007-11-20  
xlincn 写道
xlincn 写道
++ 在前面 加了再赋值
++ 在后面 赋值了再加



给我打叉的同学们。不对的地方请指出。小弟谢了。

不清楚给你打叉的人怎么想。但

假设 i 初始值为0,按这个说法(++在后面的,赋值后再加) "i = i++;" 即是等价于 "i = i; i = i + 1;"(我理解没错吧?) 那执行完 i 岂不是为1。

实际上却是:
"i = i++;"(逻辑)等价"a = i; i = i + 1; i = a"
"i = ++i"(逻辑)等价"i = i + 1; a = i; i = a"
i = a赋值总是在i = i + 1操作的后头(原理是从右到左计算)

你可以把你表述中的“赋值”改为“取值”,这样才正确。
-------------------
讨论这种问题,往往给人钻牛角印象, 玩文字游戏
15 楼 xlincn 2007-11-20  
xlincn 写道
++ 在前面 加了再赋值
++ 在后面 赋值了再加



给我打叉的同学们。不对的地方请指出。小弟谢了。
14 楼 Qieqie 2007-11-19  
jigsaw 写道
to gigix: 如果你很清楚,大可指出上spec是怎么写的,所以这里必须是这种结果。如果你懒得说,可以只说一句“自己去spec上翻”。但是我很疑惑的是,你有什么资格说“还学人家写程序……”?也许你说“还学人家作记者”,我还更能理解一点。



别人在吃米粉,他在旁边喊:烫,烫,烫
13 楼 weiqingfei 2007-11-19  
你很奇怪呀,你是第一天看gigix的回帖么?
12 楼 jigsaw 2007-11-19  
to gigix: 如果你很清楚,大可指出上spec是怎么写的,所以这里必须是这种结果。如果你懒得说,可以只说一句“自己去spec上翻”。但是我很疑惑的是,你有什么资格说“还学人家写程序……”?也许你说“还学人家作记者”,我还更能理解一点。
11 楼 weiqingfei 2007-11-19  
gigix 写道
weiqingfei 写道
能出这样的面试题也够垃圾的,i=i++这种东西讨论起来一点意义都没有。不同的语言,即使是不同的编译器得出的结果也不一样

对于java这个问题还是比较好解决,反编译一下就可以了。
		int i=0;
		i=i++;

反编译结果
   0:   iconst_0
   1:   istore_1
   2:   iload_1
   3:   iinc    1, 1
   6:   istore_1

你编译一个不一样的结果来看看?
spec里面有的东西……


你说的spec只是java的。
试几个c的编译器再说话。
10 楼 gigix 2007-11-19  
weiqingfei 写道
能出这样的面试题也够垃圾的,i=i++这种东西讨论起来一点意义都没有。不同的语言,即使是不同的编译器得出的结果也不一样

对于java这个问题还是比较好解决,反编译一下就可以了。
		int i=0;
		i=i++;

反编译结果
   0:   iconst_0
   1:   istore_1
   2:   iload_1
   3:   iinc    1, 1
   6:   istore_1

你编译一个不一样的结果来看看?
spec里面有的东西……
9 楼 weiqingfei 2007-11-19  
能出这样的面试题也够垃圾的,i=i++这种东西讨论起来一点意义都没有。不同的语言,即使是不同的编译器得出的结果也不一样。

对于java这个问题还是比较好解决,反编译一下就可以了。
		int i=0;
		i=i++;

反编译结果
   0:   iconst_0
   1:   istore_1
   2:   iload_1
   3:   iinc    1, 1
   6:   istore_1
8 楼 gigix 2007-11-19  
thehim 写道
首先我说明一下,我自己很清楚 fermin(int i) 是按值传递,因此此方法的调用对调用程序没有影响,我想不清楚的是 i++ 的自增在什么时候进行.

还学人家写程序……
7 楼 thehim 2007-11-19  
首先我说明一下,我自己很清楚 fermin(int i) 是按值传递,因此此方法的调用对调用程序没有影响,我想不清楚的是 i++ 的自增在什么时候进行.
6 楼 tedeyang 2007-11-18  
相信楼主的疑问不是在函数参数传递上,因为代码中标明了“陷阱”。
主要的不解是在 i = i++ ;这行代码。

看到楼主就看到了当年的我,今天和女朋友约会没接上头,比较郁闷,就说一下:

    执行这一行代码前i=0,这是毫无疑问的,因为java中对基本类型是用的传值方式(是真实数值,而不是传递引用/指针的值),所以方法调用不会改变参数的原值。
对“i=i++”而言,首先要对i++求值,结果显然是0,原因如何相信看过java基础语法的人都知道。
然后内存中的i执行递增操作,i=1,
然后执行=,由于i++的结果是0,所以i又从1变成0。
over。

5 楼 xlincn 2007-11-18  
++ 在前面 加了再赋值
++ 在后面 赋值了再加
4 楼 daquan198163 2007-11-18  
bilang 写道
基础不牢,搞清楚java方法是传值还是传引用

lz应该不是错再这里:inc.fermin(i);
而是i = i++;
3 楼 daquan198163 2007-11-18  
i = i++;不同于i++;
2 楼 bilang 2007-11-18  
基础不牢,搞清楚java方法是传值还是传引用
1 楼 gigix 2007-11-18  
希望有人能把自己的Java教材读一遍再去应聘或者提问

相关推荐

    令人迷惑的是:模糊测试和数据处理框架(用于GNULinux)

    - 实施持续集成(CI),将模糊测试自动化,以便每次代码更新后都能立即进行安全检查。 8. **挑战与未来趋势**: 虽然模糊测试已取得了显著成果,但仍面临挑战,如如何生成更有针对性的输入、如何更高效地分析结果...

    GRE填空模拟题及答案:The politician’s....docx

    对于空白(i),我们看到三个备选词:bewildering(令人迷惑的),admirable(令人钦佩的),unappreciated(不受赏识的)。由于“account for her high standing”,说明她的记录应该是积极的,所以排除bewildering...

    人教版高中英语必修三unit4全共85张PPT学习教案.pptx

    例如:"I’ll see him in time." 表示将来某个时刻我会遇见他。 - `in/out of time` 分别表示"合拍/不合拍",常用来描述音乐或者动作是否与节奏一致。 2. **词汇与短语**: - `be harmful to` 和 `do harm to sb....

    MFC Windows程序设计(第2版修订版)--源代码

    我相信用这种方法可以使MFC的学习变得生动有趣而不是令人气馁。我认为一旦您认真地学完这本书,然后再站在老练的Windows程序员的角度来回顾学习过程中的甜酸苦辣,您将同意我的观点。  本书分为4个部分。第1部分,...

    外研高二英语PPT学习教案.pptx

    其形容词形式有**confused**(感到迷惑的)和**confusing**(令人迷惑的)。例如:“这个问题让我感到困惑”(This question confused me.) - **relax**:动词,意为“放松”。形容词形式有**relaxing**(使人...

    等六校_高二语文上学期期中联考试题.doc

    司马迁的《史记》启迪了我,从此,困境不能令我屈服,坚韧让我攀越历史的高峰;诋毁不能使我动摇,真实的力量助我书写永恒的篇章。 以上是对试卷部分内容的解析,涵盖了语文学习的基础知识,如汉字拼音、错别字、...

    MFC Windows程序设计(第2版修订版)--详细书签版2卷

    我相信用这种方法可以使MFC的学习变得生动有趣而不是令人气馁。我认为一旦您认真地学完这本书,然后再站在老练的Windows程序员的角度来回顾学习过程中的甜酸苦辣,您将同意我的观点。  本书分为4个部分。第1部分,...

    MFC Windows程序设计(第2版修订版)--详细书签版1卷

    我相信用这种方法可以使MFC的学习变得生动有趣而不是令人气馁。我认为一旦您认真地学完这本书,然后再站在老练的Windows程序员的角度来回顾学习过程中的甜酸苦辣,您将同意我的观点。  本书分为4个部分。第1部分,...

    人教英语必修三词汇知识点学习教案.pptx

    形容词"puzzled"表示"感到迷惑的","puzzling"则表示"令人迷惑的","puzzlement"是名词,意为"困惑"。 3. religion → religious: "religion"指"宗教;宗教信仰",形容词"religious"则表示"宗教的"。 4. violent → ...

    湖南省新田县第一中学高中英语Unit1Theworldofoursenses测试题无答案牛津译林版必修3

    - 我不知道你是否能来帮我:I wonder if you could come to my aid. - 事实是他误把你当成弟弟了:The fact is that he mistook you for your brother. - Polly found herself staring up at the face of a man ...

    山东省德州市乐陵一中高三语文天天练(5)

    例如,"人才荟( kuài )萃"应改为"人才荟( huì )萃","莅(wèi )临"应改为"莅(lì )临","囹圄( wú )"应改为"囹圄(yǔ)"。 2. 词语应用:题目的第二题考察了词语的恰当使用,如"遏制"与"遏止"的区别,"次序"与...

    七年级语文上册_皇帝的新装新课件_人教新课标版.ppt

    - **骇人听闻** (hài rén tīng wén):指事情极其令人震惊,超出常理。 5. **故事主线**:《皇帝的新装》这个故事主要围绕着皇帝、小孩、骗子大臣以及做新装的过程展开。故事中的皇帝痴迷于新装,骗子大臣利用...

    新视野大学英语第四册课后翻译 汉语原文和汉译英

    5. 复杂句子的翻译:"巴罗达太太对古韦内尔令人迷惑的性格颇为不解,并觉得很难打破他这种并非有意的沉默。"(Mrs. Baroda felt confused with Gouvernail’s puzzling nature and found it hard to penetrate the ...

    浙江省温州市平阳县鳌江镇第三中学七年级语文上册《论语十则》同步练习(1) 新人教版

    “罔”是迷惑,无所得;“殆”是危险,有害;“诲女知之”的“诲”是教导;“知”在此处通“智”,智慧;“三省吾身”的“省”是反省,检查;“信”指诚实;“传不习乎”的“传”指传授的知识;“弘毅”是宽广而坚定...

    七年级上语文第10课《〈论语〉十则》同步练习2精选.doc

    “殆”念dài,表示危险或疑惑。 3. 通假字是古汉语中常见的现象。在本课中: - “不亦说乎”中的“说”通“悦”,读yuè,表示愉快。 - “诲女知之乎”中的“女”通“汝”,读rǔ,意为你。 - “是知也”中的...

    常用英文口语日常生活口语表达

    #### I am speechless. 我无语了。 - **知识点**:这句话表达了一种强烈的惊讶或无言以对的情绪。通常用于当某人遇到令人震惊、意外或者非常难以置信的情况时。 - **应用场景**: - 当听到一个令人吃惊的消息时。 ...

    人教版中考语文一模试题及答案-文档资料决战中考2021系列.doc

    4. 注音和汉字填写部分考察学生的普通话发音和字形掌握,如“匿(nì)笑”、“枯涸(hé)”、“嗤(chī)笑”、“寐(mèi)以求”、“辜负(gū)”。 5. 古诗词填空涵盖了多个经典诗句,例如“一年之计在于春”(《春晓...

    高一语文游褒禅山记随堂练习.doc

    - “至于幽暗昏惑而无物以相之”意味着到了幽深昏暗、令人迷惑的地方,没有东西来辅助(如火把或向导),无法前行。 8. **文言文翻译**: - (1)“既其出,则或咎其欲出者,而余亦悔其随之而不得极夫游之乐也。...

    八年级语文下册 劳山道士同步测试题 上海五四制版.doc

    3. 字音标注:稽首(jī shǒu),分赉(fēn lài)诸徒,肴(yáo),逡巡(qūn xún),自诩(zì xǔ)遇仙,蓦然(mò rán)踣(bó)。 4. 词语解释: - 叩而与语:叩问并交谈。 - 薄暮毕集:傍晚时分全部聚集。 - 光鉴...

Global site tag (gtag.js) - Google Analytics