`

一个操作符优先级顺序引起的问题

阅读更多


近日在J2ME里做汉字编解码运算时,遇到一诡异问题,起初让我百思不得其解,并直叫见鬼了。

将问题简单描述如下:

汉字“国”的Unicode 编码值为22269,高字节为0x56 ,低字节为0xFD,于是我按照算法int ch=0x56<<8+0xfd ch理所当然地视为“国”的Unicode编码值ch==22269,但 char letter=(char)ch后,我发现letter=’是一乱码,而不是我所期待的“国”字。经验告诉我,debug的时候到了,通过debug发现,int ch=0x56<<8+0xfd计算得到的ch值是2752

我百思不得其解,开始心烦意乱地胡乱猜疑,怀疑0x56<<80x56*256两个表达式的数值不相等,但大学里的知识告诉我将一个整数右移N位肯定等于该数乘以2N次幂,Sytem.out.println((0x56<<8)==(0x56*256))运行的实际结果也否定了这次猜疑。于是我写了如下测试语句:

int highByte=0x56;

int lowByte=0xfd;

int chValue1=highByte<<8+lowByte;//2752

int chValue2=highByte*256+lowByte;//22269

char ch1=(char)chValue1;//乱码

char ch2=(char)chValue2;//''

通过debug发现,chValue1值为2752,转为char后是一个乱字符。chValue2值为22269,转为char后是我梦寐以求的“国”字,绝望地看着屏幕半小时后,我小心翼翼地分别给highByte<<8highByte*256加了括号,发现得到的chValue1chValue2都是我所期望的22269,于是我想到了运算符优先级的问题,猜测在java<<的优先级低于+,在表达式highByte<<8+lowByte中,现计算8+lowByte,然后将得到的数值右移8位,实际程序的运行结果验证了我的想法, highByte<<8+lowBytehighByte<<(8+lowByte)结果相同都是2752。通过查找java运算符优先级顺序表(见下图),发现<<运算符确实低于+,是我没有注意正确的运算顺序导致了该问题的出现。

Java操作符的优先级和结合性

优先级

结合性

1

[ ].( ) (函数呼叫)

从左到右

2

!~++--+(单操作数)–(单操作数)( ) (类型转化)new

从右到左

3

*/%

从左到右

4

+-

从左到右

5

<<>>>>>

从左到右

6

<<=>>=instanceof

从左到右

7

==!=

从左到右

8

&

从左到右

9

^

从左到右

10

|

从左到右

11

&&

从左到右

12

||

从左到右

13

? :

从右到左

14

=+=-=*=/=%=^=<<=>>=>>>=

从右到左

结论:Java优先级顺序是很基本的常识,一个看起来让人悲伤欲绝的bug,查找出原因来很可能是因为一些很基本的常识没有注意到。在解决bug时,尽量保持平静的心态和,客观理性地查找原因。

分享到:
评论

相关推荐

    c-minus词法分析器

    简单表达式由无结合的关系操作符组成(即无括号的表达式仅有一个关系操作符)。简单表达式在它不包含关系操作符时,其值是加法表达式的值,或者如果关系算式求值为t u r e,其值为1,求值为f a l s e时值为0。 22. ...

    自己动手写操作系统(含源代码).part2

    书中的步骤遵循由小到大、由浅入深的顺序,跟随这些步骤,读者可以由一个最简单的引导扇区开始,逐渐完善代码,扩充功能,最后形成一个小的操作系统。 本书不仅介绍操作系统的各要素,同时涉及开发操作系统需要的...

    自己动手写操作系统(含源代码).part1

    书中的步骤遵循由小到大、由浅入深的顺序,跟随这些步骤,读者可以由一个最简单的引导扇区开始,逐渐完善代码,扩充功能,最后形成一个小的操作系统。 本书不仅介绍操作系统的各要素,同时涉及开发操作系统需要的...

    SQL语法大全

    Source参数可以是一个Command对象名称、一段SQL命令、一个指定的数据表名称或是一个Stored Procedure。假如省略这个参数,系统则采用Recordset对象的Source属性。 ActiveConnection Recordset对象可以通过...

    Altium Designer Beta 19.0.10完整版安装包+安装教程+和谐文件

    修复了一个问题,即在重命名相关的PCB文档后,Draftsman会崩溃。 26542 修复了回归,其中未选择丝网印刷图形的组件的装配视图中缺少阴影线(BC:9416)。 26867 修复了回归,其中没有显示缺少3D体的Not Fitted组件的...

    2009达内SQL学习笔记

    select:从一个或多个表中检索一个或多个数据列。包含信息:想选择什么表,从什么地方选择。必须要有From子句。(最常用) 当从多张表里查询的时候,会产生笛卡尔积;可用条件过滤它。 当两个表有相同字段时必须加...

    c++ 面试题 总结

    15.用C++写个程序,如何判断一个操作系统是16位还是32位的?不能用sizeof()函数 A1: 16位的系统下, int i = 65536; cout ; // 输出0; int i = 65535; cout ; // 输出-1; 32位的系统下, int i = 65536; cout ; ...

    java 面试题 总结

    Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。 10、&和&&的区别。 &是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and)。 11、HashMap...

    Windows 系统错误代码简单分析

     0301 系统接收了一个无效的操作锁定确认。  0317 在 %2 的消息文件中,系统无法找到消息号为 0x%1 的消息文本。  0487 试图访问无效地址。 0534 运算结果超过 32 位。  0535 该管道的另一方有一进程。...

    飞鸽传书(IPMessenger) 源码

     (如果你安装的 IE 是 5.x 或更高版本, 那么就不必担心这个问题了)  注意: Windows 3.1(和 NT3.5x), 请使用 IP Messenger for Win16. 使用说明  安装/卸载 &gt;  执行 setup.exe 你可以将 IPMsg 安装到指定目录, ...

    谭浩强C语言程序设计,C++程序设计,严蔚敏数据结构,高一凡数据结构算法分析与实现.rar

    10.2.4 指针变量几个问题的进一步说明 140 810.3 数组指针和指向数组的指针变量 141 10.3.1 指向数组元素的指针 142 10.3.2 通过指针引用数组元素 143 10.3.3 数组名作函数参数 146 10.3.4 指向多维数组的指针和指针...

    谭浩强C语言程序设计,C++程序设计,严蔚敏数据结构,高一凡数据结构算法分析与实现.rar )

    10.2.4 指针变量几个问题的进一步说明 140 810.3 数组指针和指向数组的指针变量 141 10.3.1 指向数组元素的指针 142 10.3.2 通过指针引用数组元素 143 10.3.3 数组名作函数参数 146 10.3.4 指向多维数组的指针和指针...

    计算机应用技术(实用手册)

    让默认的就可以了,但是超频玩者是肯定不会放过任何可以提高性能的东西的,所以如果你想在这里让你的电脑提升一点性能的话,就必须慢慢试验,选择一个适当的参数才能让你的计算机达到性能和稳定的最佳状态!...

    飞鸽传书Ver2.06

    (如果你安装的 IE 是 5.x 或更高版本, 那么就不必担心这个问题了) 注意: Windows 3.1(和 NT3.5x), 请使用 IP Messenger for Win16. ---------------------------------------------------------------------...

    双系统修复工具

    8. 修改引导菜单显示:当只有一个NT5.x和n个NT6.x系统时,如对"早期版本windows"或"Earlier Version of Windows"菜单感到不爽,直接"自动修复/手动修复"将自动修改相应菜单为实际系统类型模式 9. 实例 - Ghost系统...

    轻松学C#(图解版)

    1.3 第一个程序—Hello World 8 1.4 小结 11 1.5 习题 12 第二篇 面向对象基础篇 第2章 类和对象 16 2.1 分析Hello World程序 16 2.2 语法规范 17 2.2.1 标识符 17 2.2.2 关键字 18 2.2.3 注释 19 2.3 定义类 20 ...

    飞鸽传书Ver2.06源码

    (如果你安装的 IE 是 5.x 或更高版本, 那么就不必担心这个问题了) 注意: Windows 3.1(和 NT3.5x), 请使用 IP Messenger for Win16. ---------------------------------------------------------------------...

    (重要)AIX command 使用总结.txt

    //用下面命令可以得到一个硬盘的微码级别: # lscfg -vl pdisk* //IBM小型机AIX5.1操作系统密码文件丢失或者误删的恢复方法 进入维护模式: 1、将安装盘第一张放入光驱; 重启小型机选择主控台,按屏幕上提示的数字;...

Global site tag (gtag.js) - Google Analytics