免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 846 | 回复: 0
打印 上一主题 下一主题

java解惑学习笔记3 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-02-04 18:51 |只看该作者 |倒序浏览
java解惑学习笔记3:
谜题7:互换内容
public class CleverSwap{
public static void main(String[] args){
  int x = 1984; // (0x7c0)
  int y = 2001; // (0x7d1)
  x^= y^= x^= y;
  System.out.println("x= " + x + "; y= " + y);
}
}
它会打印出什么呢?
x = 0111 1100 0000 ,y = 0111 1101 0001 x^=y,后 x = 0000 0001 0001
y^=x  后y = 0111 1100  0000  x^=y 后  x = 0111 1101  0001
所以 x =  0x7d1      y = 0x7c0
很好嘛!不用中间变量的swap方法。但是打印的结果出乎意料:x = 0; y = 1984
郁闷哪!
Java语言规范描述到:操作符的操作数是从左向右求值的。为了求表达式 x ^= expr的值,
x的值是在计算expr之前被提取的,并且这两个值的异或结果被赋给变量x。在CleverSwap程序中,
变量x的值被提取了两次——每次在表达式中出现时都提取一次——但是两次提取都发生在所有的
赋值操作之前。
按编译时引入中间变量的方法来分解x^= y^= x^= y,
x = x ^(y^x^y) : x与y两次xor, 结果还是x ,x xor x ,结果是0 ,故最终得0;
int tmp1 = x ; // x在表达式中第一次出现
int tmp2 = y ; // y的第一次出现
int tmp3 = x ^ y ; // 计算x ^ y
x = tmp3 ; // 最后一个赋值:存储x ^ y 到 x
y = tmp2 ^ tmp3 ; // 第二个赋值:存储最初的x值到y中
x = tmp1 ^ y ; // 第一个赋值:存储0到x中
solution:
丑陋而又无用的解法:
y = (x^= (y^= x))^ y
最好的方法是不要这么干!不想使用中间变量我们可以这样:{a = a + b; b = a - b;a = a - b};

谜题8:Dos Equis
public class DosEquis{
public static void main(String[] args){
  char x = 'X';
  int i = 0;
  System.out.println(true ? x : 0);
  System.out.println(false ? i : x);
}
}
和我一样性子急的人,看到这个问题就忍不住想说:
结果是 XX
很不幸,我们又被骗了,当表达式是复合类型的时候,事情往往没那么简单,
表达式结果的类型有时候让我觉得自己被玩了,让我们找出躲在阴暗的角落表达式规范,来增加对自己
代码的掌控能力。
确定条件表达式结果类型的规则的核心:
1.如果第二个和第三个操作数具有相同的类型,那么它就是条件表达式的类型。换句话说,
  你可以通过绕过混合类型的计算来避免大麻烦。
2.如果一个操作数的类型是T(byte,short,char),而另一个操作数是一个int类型的常量表达式,
  它的值是可以用类型T表示的,那么条件表达式的类型就是T。
3.否则,将对操作数类型运用二进制数字提升,而条件表达式的类型就是第二个和第三个操作数被提升之后的类型。
对于第一个输出,两个操作数是char和int型常量,采用规则2,输出是char型X,
对于第二个输出,采用规则3,其返回的类型是对int和char运用了二进制数字提升之后的类型,即int。
表达式的结果决定那一个重载print method 被调用,对第一个表达式来说,PrintStream.print(char)将被调用,而对第二个表达式来说,
PrintStream.print(int)将被调用。前一个重载方法将变量x的值作为Unicode字符(X)来打印,而后一个重载方法将其作为一个十进制整数
(88)来打印。
所以最终的结果是 X88
经验:总之,通常最好是在条件表达式中使用类型相同的第二和第三操作数。否则,你和你的程序的读者必须要彻底理解这些表达式行为的复杂规范。




本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/28187/showart_242719.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP