论坛首页 入门技术论坛

令我迷惑的 i++

浏览 5994 次
该帖已经被评为新手帖
作者 正文
   发表时间: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里面有的东西……
0 请登录后投票
   发表时间: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的编译器再说话。
0 请登录后投票
   发表时间:2007-11-19  
to gigix: 如果你很清楚,大可指出上spec是怎么写的,所以这里必须是这种结果。如果你懒得说,可以只说一句“自己去spec上翻”。但是我很疑惑的是,你有什么资格说“还学人家写程序……”?也许你说“还学人家作记者”,我还更能理解一点。
0 请登录后投票
   发表时间:2007-11-19  
你很奇怪呀,你是第一天看gigix的回帖么?
0 请登录后投票
   发表时间:2007-11-19  
jigsaw 写道
to gigix: 如果你很清楚,大可指出上spec是怎么写的,所以这里必须是这种结果。如果你懒得说,可以只说一句“自己去spec上翻”。但是我很疑惑的是,你有什么资格说“还学人家写程序……”?也许你说“还学人家作记者”,我还更能理解一点。



别人在吃米粉,他在旁边喊:烫,烫,烫
0 请登录后投票
   发表时间:2007-11-20  
xlincn 写道
++ 在前面 加了再赋值
++ 在后面 赋值了再加



给我打叉的同学们。不对的地方请指出。小弟谢了。
0 请登录后投票
   发表时间: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操作的后头(原理是从右到左计算)

你可以把你表述中的“赋值”改为“取值”,这样才正确。
-------------------
讨论这种问题,往往给人钻牛角印象, 玩文字游戏
0 请登录后投票
   发表时间: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 又增添了兴趣
有乐趣如是,足矣
0 请登录后投票
   发表时间: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 又增添了兴趣
有乐趣如是,足矣

总结得不错。继续努力。
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics