`
wuhua
  • 浏览: 2111266 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

再次复习 : 运算符和表达式

    博客分类:
  • J2SE
阅读更多

出自 http://www.3geye.net/?3/viewspace-3425

这里我怎么排版都不好看,有兴趣到原文哪里看。哪里的排版好点。

 

 

运 算 符 指 明 对 操 作 数 所 进 行 的 运 算 。 按 操 作 数 的 数 目 来 分 ,可 以 有 一 元 运 算 符 (如 ++、

  -),二 元 运 算 符 (如 +、 >)和 三 元 运 算 符 (如 ?:),它 们 分 别 对 应 于 一 个 、 两 个 和 三 个 操 作 数 。 对

  于 一 元 运 算 符 来 说 ,可 以 有 前 缀 表 达 式 (如 ++i )和 后 缀 表 达 式 (如 i++),对 于 二 元 运 算 符 来 说 则

  采 用 中 缀 表 达 式 (如 a+b)。 按 照 运 算 符 功 能 来 分 ,基 本 的 运 算 符 有 下 面 几 类 :

  1.算 术 运 算 符 (+,-,*,/,%,++,--)

  2.关 系 运 算 符 (>,<,>=,<=,==,!=)

  3.布 尔 逻 辑 运 算 符 (!,&&,||)

  4.位 运 算 符 (>>,<<,>>>,&,|,^,~ )

  5.赋 值 运 算 符 (=,及 其 扩 展 赋 值 运 算 符 如 +=)

  6.条 件 运 算 符 ( ?:)

  7.其 它 (包 括 分 量 运 算 符 ? ,下 标 运 算 符 [],实 例 运 算 符 instanc eof,内 存 分 配 运 算 符 new,强 制 类

  型 转 换 运 算 符 (类 型 ),方 法 调 用 运 算 符 () 等 )

  本 章 中 我 们 主 要 讲 述 前 6类 运 算 符 。

  § 3.1算 术 运 算 符

  算 术 运 算 符 作 用 于 整 型 或 浮 点 型 数 据 ,完 成 算 术 运 算 。

  一 、 二 元 算 术 运 算 符 ,如 下 表 所 示

  运算符 用法 描述

  + op1+op2 加

  - op1-op2 减

  * op1*op2 乘

  / op1/op2 除

  % op1%op2 取模(求余)

  Java对 加 运 算 符 进 行 了 扩 展 ,使 它 能 够 进 行 字 符 串 的 连 接 ,如 "abc"+"de",得 到 串 "abcde"。 我

  们 将 在 第 七 章 中 讲 解 。

  与 C、 C++不 同 ,对 取 模 运 算 符 %来 说 ,其 操 作 数 可 以 为 浮 点 数 , 如 37.2%10=7.2。

  二 、 一 元 算 术 运 算 符 ,如 下 表 所 示 :

  运算符 用法 描述

  + +op 正值

  - -op 负值

  ++ ++op,op++ 加1

  -- --op,op-- 减1

  i++与 ++i的 区 别

  i++在 使 用 i之 后 ,使 i的 值 加 1,因 此 执 行 完 i++后 ,整 个 表 达 式 的 值 为 i,而 i的 值 变 为 i+1。

  ++i在 使 用 i之 前 ,使 i的 值 加 1,因 此 执 行 完 ++i后 ,整 个 表 达 式 和 i的 值 均 为 i+1。

  对 i--与 --i同 样 。

  例 3.1.下 面 的 例 子 说 明 了 算 术 运 算 符 的 使 用

  public class ArithmaticOp{

  public static void main( String args[] ){

  int a=5+4; //a=9

  int b=a*2; //b=18

  int c=b/4; //c=4

  int d=b-c; //d=14

  int e=-d; //e=-14

  int f=e%4; //f=-2

  double g=18.4;

  double h=g%4; //h=2.4

  int i=3;

  int j=i++; //i=4,j=3

  int k=++i; //i=5,k=5

  System.out.println("a = "+a);

  System.out.println("b = "+b);

  System.out.println("c = "+c);

  System.out.println("d = "+d);

  System.out.println("e = "+e);

  System.out.println("f = "+f);

  System.out.println("g = "+g);

  System.out.println("h = "+h);

  System.out.println("i = "+i);

  System.out.println("j = "+j);

  System.out.println("k = "+k);

  }

  }

  其结果为:

  C:\>java ArithmaticOp

  a = 9

  b = 18

  c = 4

  d = 14

  e = -14

  f = -2

  g = 18.4

  h = 2.4

  i = 5

  j = 3

  k = 5

  § 3.2关 系 运 算 符

  关 系 运 算 符 用 来 比 较 两 个 值 ,返 回 布 尔 类 型 的 值 true或 false。 关 系 运 算 符 都 是 二 元 运 算

  符 ,如 下 表 所 示 :

  运算符 用法 返回true的情况

  > op1>op2 op1大于op2

  >+ op1>=op2 op1大于或等于op2

  < op1<op2 op1小于op2

  <= op1<=op2 op1小于或等于op2

  == op1==op2 op1与op2相等

  != op1!=op2 op1与op2不等

  Java中 ,任 何 数 据 类 型 的 数 据 (包 括 基 本 类 型 和 组 合 类 型 )都 可 以 通 过 ==或 !=来 比 较 是 否

  相 等 (这 与 C、 C++不 同 )。

  关 系 运 算 的 结 果 返 回 true或 false,而 不 是 C、 C++中 的 1或 0。

  关 系 运 算 符 常 与 布 尔 逻 辑 运 算 符 一 起 使 用 ,作 为 流 控 制 语 句 的 判 断 条 件 。 如

  if( a>b && b==c)

  § 3.3布 尔 逻 辑 运 算 符

  布 尔 逻 辑 运 算 符 进 行 布 尔 逻 辑 运 算 ,如 下 表 所 示 :

  op1 op2 op1&&op2 op1||op2 !op1

  false false false false true

  false true false true true

  true false false true false

  true true true true false

  }@@@

  ?&&、‖

  为二元运算符,实现逻辑与、逻辑或。

  ?! 为一元运算符,实现逻辑非。

  ?对于布尔逻辑运算,先求出运算符左边的表达式的值,对或运算如果为true,则整个表

  达式的结果为true,不必对运算符右边的表达式再进行运算;同样,对与运算,如果左边表达式

  的值为false,则不必对右边的表达式求值,整个表达式的结果为false。

  下面的例子说明了关系运算符和布尔逻辑运算符的使用。

  @@@[

  public class RelationAndConditionOp{

  public static void main( String args[] ){

  int a=25,b=3;

  boolean d=a<b; //d=false

  System.out.println("a<b = "+d);

  int e=3;

  if(e!=0 && a/e>5)

  System.out.println("a/e = "+a/e);

  int f=0;

  if(f!=0 && a/f>5)

  System.out.println("a/f = "+a/f);

  else

  System.out.println("f = "+f);

  }

  }

  其运行结果为:

  C:\>java RelationAndConditionOp

  a<b = false

  a/e = 8

  f = 0

  注 意 :上 例 中 ,第 二 个 if语 句 在 运 行 时 不 会 发 生 除 0溢 出 的 错 误 ,因 为 e!=0为 false,所 以 就 不 需

  要 对 a/e进 行 运 算 。

  § 3.4位 运 算 符

  位 运 算 符 用 来 对 二 进 制 位 进 行 操 作 ,Java中 提 供 了 如 下 表 所 示 的 位 运 算 符 :

  位 运 算 符 中 ,除

  ~

  以 外 ,其 余 均 为 二 元 运 算 符 。

  操 作 数 只 能 为 整 型 和 字 符 型 数 据 。

  3.4.1补 码

  Java使 用 补 码 来 表 示 二 进 制 数 ,在 补 码 表 示 中 ,最 高 位 为 符 号 位 ,正 数 的 符 号 位 为 0,负 数

  为 1。 补 码 的 规 定 如 下 :

  对 正 数 来 说 ,最 高 位 为 0,其 余 各 位 代 表 数 值 本 身 (以 二 进 制 表 示 ),如 +42的 补 码 为

  00101010。

  对 负 数 而 言 ,把 该 数 绝 对 值 的 补 码 按 位 取 反 ,然 后 对 整 个 数 加 1,即 得 该 数 的 补 码 。 如

  -42的 补 码 为 11010110 (00101010 按 位 取 反 11010101 +1 11010110 )

  用 补 码 来 表 示 数 ,0的 补 码 是 唯 一 的 ,都 为 00000000。 (而 在 原 码 ,反 码 表 示 中 ,+0和 -0的 表 示

  是 不 唯 一 的 ,可 参 见 相 应 的 书 籍 )。 而 且 可 以 用 111111表 示 -1的 补 码 (这 也 是 补 码 与 原 码 和 反

  码 的 区 别 )。

  3.4.2按 位 取 反 运 算 符

  ~

  ~

  是 一 元 运 算 法 ,对 数 据 的 每 个 二 进 制 位 取 反 ,即 把 1变 为 0,把 0变 为 1。

  例 如 :

  0010101

  ~

  1101010

  注 意 ,~ 运 算 符 与 - 运 算 符 不 同 ,~ 21≠ -21。

  3.4.3按 位 与 运 算 符 &

  参 与 运 算 的 两 个 值 ,如 果 两 个 相 应 位 都 为 1,则 该 位 的 结 果 为 1,否 则 为 0。 即 :

  0 & 0 = 0,0 &1 = 0,1 & 0 = 0,1 & 1 = 1

移位运算符

    包括:
    “>> 右移”;“<< 左移”;“>>> 无符号右移”

例子:
-5>>3=-1
1111 1111 1111 1111 1111 1111 1111 1011
1111 1111 1111 1111 1111 1111 1111 1111
其结果与 Math.floor((double)-5/(2*2*2)) 完全相同。

-5<<3=-40
1111 1111 1111 1111 1111 1111 1111 1011
1111 1111 1111 1111 1111 1111 1101 1000
其结果与 -5*2*2*2 完全相同。

5>>3=0
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0000
其结果与 5/(2*2*2) 完全相同。

5<<3=40
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0010 1000
其结果与 5*2*2*2 完全相同。

-5>>>3=536870911     
1111 1111 1111 1111 1111 1111 1111 1011
0001 1111 1111 1111 1111 1111 1111 1111

无论正数、负数,它们的右移、左移、无符号右移 32 位都是其本身,比如 -5<<32=-5、-5>>32=-5、-5>>>32=-5。
一个有趣的现象是,把 1 左移 31 位再右移 31 位,其结果为 -1。
0000 0000 0000 0000 0000 0000 0000 0001
1000 0000 0000 0000 0000 0000 0000 0000
1111 1111 1111 1111 1111 1111 1111 1111


 
Java 定义的位运算(bitwise operators )直接对整数类型的位进行操作,这些整数类型包括long,int,short,char,and byte 。表4-2 列出了位运算: 

    运算符 结果 
    ~ 按位非(NOT)(一元运算) 
    & 按位与(AND) 
    | 按位或(OR) 
    ^ 按位异或(XOR) 
    >> 右移 
    >>> 右移,左边空出的位以0填充 
    运算符 结果 
    << 左移 
    &= 按位与赋值 
    |= 按位或赋值 
    ^= 按位异或赋值 
    >>= 右移赋值 
    >>>= 右移赋值,左边空出的位以0填充 
    <<= 左移赋值 


    既然位运算符在整数范围内对位操作,因此理解这样的操作会对一个值产生什么效果是重要的。具体地说,知道Java 是如何存储整数值并且如何表示负数的是有用的。因此,在继续讨论之前,让我们简短概述一下这两个话题。

    所有的整数类型以二进制数字位的变化及其宽度来表示。例如,byte 型值42的二进制代码是00101010 ,其中每个位置在此代表2的次方,在最右 边的位以20开始。向左下一个位置将是21,或2,依次向左是22,或4,然后是8,16,32等等,依此类推。因此42在其位置1,3,5的值为1(从 右边以0开始数);这样42是21+23+25的和,也即是2+8+32 。

    所有的整数类型(除了char 类型之外)都是有符号的整数。这意味着他们既能表示正数,又能表示负数。Java 使用大家知道的2的补码 (two’s complement )这种编码来表示负数,也就是通过将与其对应的正数的二进制代码取反(即将1变成0,将0变成1),然后对其结果加 1。例如,-42就是通过将42的二进制代码的各个位取反,即对00101010 取反得到11010101 ,然后再加1,得到11010110 ,即 -42 。要对一个负数解码,首先对其所有的位取反,然后加1。例如-42,或11010110 取反后为00101001 ,或41,然后加1,这样就 得到了42。

    如果考虑到零的交叉(zero crossing )问题,你就容易理解Java (以及其他绝大多数语言)这样用2的补码的原因。假定byte 类型的 值零用00000000 代表。它的补码是仅仅将它的每一位取反,即生成11111111 ,它代表负零。但问题是负零在整数数学中是无效的。为了解决负 零的问题,在使用2的补码代表负数的值时,对其值加1。即负零11111111 加1后为100000000 。但这样使1位太靠左而不适合返回到 byte 类型的值,因此人们规定,-0和0的表示方法一样,-1的解码为11111111 。尽管我们在这个例子使用了byte 类型的值,但同样的基 本的原则也适用于所有Java 的整数类型。

    因为Java 使用2的补码来存储负数,并且因为Java 中的所有整数都是有符号的,这样应用位运算符可以容易地达到意想不到的结果。例如,不管你如何 打算,Java 用高位来代表负数。为避免这个讨厌的意外,请记住不管高位的顺序如何,它决定一个整数的符号。

    4.2.1 位逻辑运算符
位逻辑运算符有“与”(AND)、“或”(OR)、“异或(XOR )”、“非(NOT)”,分别用“&”、“|”、“^”、“~”表示,4-3 表显示了每个位逻辑运算的结果。在继续讨论之前,请记住位运算符应用于每个运算数内的每个单独的位。
    表4-3 位逻辑运算符的结果 
   A 0 1 0 1 B 0 0 1 1 A | B 0 1 1 1 A & B 0 0 0 1 A ^ B 0 1 1 0 ~A 1 0 1 0 

    按位非(NOT)

    按位非也叫做补,一元运算符NOT“~”是对其运算数的每一位取反。例如,数字42,它的二进制代码为:

    00101010 

    经过按位非运算成为

    11010101 

    按位与(AND)

    按位与运算符“&”,如果两个运算数都是1,则结果为1。其他情况下,结果均为零。看下面的例子:

    00101010 42 &00001111 15 

    00001010 10 

    按位或(OR)

    按位或运算符“|”,任何一个运算数为1,则结果为1。如下面的例子所示:

    00101010 42 | 00001111 15 

    00101111 47 

    按位异或(XOR)

    按位异或运算符“^”,只有在两个比较的位不同时其结果是 1。否则,结果是零。下面的例子显示了“^”运算符的效果。这个例子也表明了XOR 运算符的 一个有用的属性。注意第二个运算数有数字1的位,42对应二进制代码的对应位是如何被转换的。第二个运算数有数字0的位,第一个运算数对应位的数字不变。 当对某些类型进行位运算时,你将会看到这个属性的用处。

    00101010 42 ^ 00001111 15 

    00100101 37
    位逻辑运算符的应用

下面的例子说明了位逻辑运算符:

// Demonstrate the bitwise logical operators. 
class BitLogic { 
public static void main(String args[]) { 


String binary[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"  

}; 
int a = 3; // 0 + 2 + 1 or 0011 in binary 
int b = 6; // 4 + 2 + 0 or 0110 in binary 
int c = a | b; 
int d = a & b;  
int e = a ^ b;  
int f = (~a & b) | (a & ~b); 
int g = ~a & 0x0f;  


System.out.println(" a = " + binary[a]); 
System.out.println(" b = " + binary); 
System.out.println(" a|b = " + binary[c]); 
System.out.println(" a&b = " + binary[d]); 
System.out.println(" a^b = " + binary[e]); 
System.out.println("~a&b|a&~b = " + binary[f]); 
System.out.println(" ~a = " + binary[g]); 


} 
} 







<!---->

    在本例中,变量a与b对应位的组合代表了二进制数所有的 4 种组合模式:0-0,0-1,1-0 ,和1-1 。“|”运算符和“&”运算符分 别对变量a与b各个对应位的运算得到了变量c和变量d的值。对变量e和f的赋值说明了“^”运算符的功能。字符串数组binary 代表了0到15 对应 的二进制的值。在本例中,数组各元素的排列顺序显示了变量对应值的二进制代码。数组之所以这样构造是因为变量的值n对应的二进制代码可以被正确的存储在数 组对应元素binary[n] 中。例如变量a的值为3,则它的二进制代码对应地存储在数组元素binary[3] 中。~a的值与数字0x0f (对应 二进制为0000 1111 )进行按位与运算的目的是减小~a的值,保证变量g的结果小于16。因此该程序的运行结果可以用数组binary 对应的元 素来表示。该程序的输出如下:

a = 0011 b = 0110 a|b = 0111 a&b = 0010 a^b = 0101 ~a&b|a&~b = 0101 ~a = 1100  




<!---->

    4.2.2 左移运算符
    左移运算符<<使指定值的所有位都左移规定的次数。它的通用格式如下所示:

    value << num
    这里,num 指定要移位值value 移动的位数。也就是,左移运算符<<使指定值的所有位都左移num位。每左移一个位,高阶位都被移出 (并且丢弃),并用0填充右边。这意味着当左移的运算数是int 类型时,每移动1位它的第31位就要被移出并且丢弃;当左移的运算数是long 类型 时,每移动1位它的第63位就要被移出并且丢弃。

    在对byte 和short类型的值进行移位运算时,你必须小心。因为你知道Java 在对表达式求值时,将自动把这些类型扩大为 int 型,而且,表 达式的值也是int 型。对byte 和short类型的值进行移位运算的结果是int 型,而且如果左移不超过31位,原来对应各位的值也不会丢弃。但 是,如果你对一个负的byte 或者short类型的值进行移位运算,它被扩大为int 型后,它的符号也被扩展。这样,整数值结果的高位就会被1填充。 因此,为了得到正确的结果,你就要舍弃得到结果的高位。这样做的最简单办法是将结果转换为byte 型。下面的程序说明了这一点:


// Left shifting a byte value. 
class ByteShift {



public static void main(String args[]) { 
byte a = 64, b;

int i;  


i = a << 2; 
b = (byte) (a << 2); 



System.out.println("Original value of a: " + a);

System.out.println("i and b: " + i + " " + b); 
} 
} 




<!---->

    该程序产生的输出下所示:

Original value of a: 64 
i and b: 256 0 
<!---->
因变量a在赋值表达式中,故被扩大为int 型,64(0100 0000 )被左移两次生成值256 (10000 0000 )被赋给变量i。然而,经过左移后,变量b中惟一的1被移出,低位全部成了0,因此b的值也变成了0。

    既然每次左移都可以使原来的操作数翻倍,程序员们经常使用这个办法来进行快速的2 的乘法。但是你要小心,如果你将1移进高阶位(31或63位),那么该值将变为负值。下面的程序说明了这一点:

// Left shifting as a quick way to multiply by 2. 
class MultByTwo { 


public static void main(String args[]) { 
int i; 
int num = 0xFFFFFFE;  


for(i=0; i<4; i++) { 
num = num << 1;  
System.out.println(num); 


} 
} 





<!---->

    这里,num 指定要移位值value 移动的位数。也就是,左移运算符<<使指定值的所有位都左移num位。每左移一个位,高阶位都被移出 (并且丢弃),并用0填充右边。这意味着当左移的运算数是int 类型时,每移动1位它的第31位就要被移出并且丢弃;当左移的运算数是long 类型 时,每移动1位它的第63位就要被移出并且丢弃。

    在对byte 和short类型的值进行移位运算时,你必须小心。因为你知道Java 在对表达式求值时,将自动把这些类型扩大为 int 型,而且,表 达式的值也是int 型。对byte 和short类型的值进行移位运算的结果是int 型,而且如果左移不超过31位,原来对应各位的值也不会丢弃。但 是,如果你对一个负的byte 或者short类型的值进行移位运算,它被扩大为int 型后,它的符号也被扩展。这样,整数值结果的高位就会被1填充。 因此,为了得到正确的结果,你就要舍弃得到结果的高位。这样做的最简单办法是将结果转换为byte 型。下面的程序说明了这一点:

// Left shifting a byte value. 
class ByteShift { 


public static void main(String args[]) { 
byte a = 64, b; 
int i;  


i = a << 2; 
b = (byte) (a << 2);  


System.out.println("Original value of a: " + a); 
System.out.println("i and b: " + i + " " + b); 
} 
} 





<!---->

    该程序产生的输出下所示:

<!----> Original value of a: 64 i and b: 256 0

    因变量a在赋值表达式中,故被扩大为int 型,64(0100 0000 )被左移两次生成值256 (10000 0000 )被赋给变量i。然而,经过左移后,变量b中惟一的1被移出,低位全部成了0,因此b的值也变成了0。

    既然每次左移都可以使原来的操作数翻倍,程序员们经常使用这个办法来进行快速的2 的乘法。但是你要小心,如果你将1移进高阶位(31或63位),那么该值将变为负值。下面的程序说明了这一点:

// Left shifting as a quick way to multiply by 2. 
class MultByTwo { 


public static void main(String args[]) { 
int i; 
int num = 0xFFFFFFE;  


for(i=0; i<4; i++) { 
num = num << 1;  
System.out.println(num); 


} 
} 
}  





<!---->

    该程序的输出如下所示:

536870908  
1073741816  
2147483632  
-32 
<!---->


因变量a在赋值表达式中,故被扩大为int 型,64(0100 0000 )被左移两次生成值256 (10000 0000 )被赋给变量i。然而,经过左移后,变量b中惟一的1被移出,低位全部成了0,因此b的值也变成了0。

    既然每次左移都可以使原来的操作数翻倍,程序员们经常使用这个办法来进行快速的2 的乘法。但是你要小心,如果你将1移进高阶位(31或63位),那么该值将变为负值。下面的程序说明了这一点:

// Left shifting as a quick way to multiply by 2. 
class MultByTwo { 


public static void main(String args[]) { 
int i; 
int num = 0xFFFFFFE;  


for(i=0; i<4; i++) { 
num = num << 1;  
System.out.println(num); 


} 
} 





<!---->

    这里,num 指定要移位值value 移动的位数。也就是,左移运算符<<使指定值的所有位都左移num位。每左移一个位,高阶位都被移出 (并且丢弃),并用0填充右边。这意味着当左移的运算数是int 类型时,每移动1位它的第31位就要被移出并且丢弃;当左移的运算数是long 类型 时,每移动1位它的第63位就要被移出并且丢弃。

    在对byte 和short类型的值进行移位运算时,你必须小心。因为你知道Java 在对表达式求值时,将自动把这些类型扩大为 int 型,而且,表 达式的值也是int 型。对byte 和short类型的值进行移位运算的结果是int 型,而且如果左移不超过31位,原来对应各位的值也不会丢弃。但 是,如果你对一个负的byte 或者short类型的值进行移位运算,它被扩大为int 型后,它的符号也被扩展。这样,整数值结果的高位就会被1填充。 因此,为了得到正确的结果,你就要舍弃得到结果的高位。这样做的最简单办法是将结果转换为byte 型。下面的程序说明了这一点:

// Left shifting a byte value. 
class ByteShift { 


public static void main(String args[]) { 
byte a = 64, b; 
int i;  


i = a << 2; 
b = (byte) (a << 2);  


System.out.println("Original value of a: " + a); 
System.out.println("i and b: " + i + " " + b); 
} 
} 





<!---->

    该程序产生的输出下所示:

<!----> Original value of a: 64 i and b: 256 0

    因变量a在赋值表达式中,故被扩大为int 型,64(0100 0000 )被左移两次生成值256 (10000 0000 )被赋给变量i。然而,经过左移后,变量b中惟一的1被移出,低位全部成了0,因此b的值也变成了0。

    既然每次左移都可以使原来的操作数翻倍,程序员们经常使用这个办法来进行快速的2 的乘法。但是你要小心,如果你将1移进高阶位(31或63位),那么该值将变为负值。下面的程序说明了这一点:

// Left shifting as a quick way to multiply by 2. 
class MultByTwo { 


public static void main(String args[]) { 
int i; 
int num = 0xFFFFFFE;  


for(i=0; i<4; i++) { 
num = num << 1;  
System.out.println(num); 


} 
} 
}  





<!---->

    该程序的输出如下所示:

536870908  
1073741816  
2147483632  
-32 
<!---->


}; 
byte b = (byte) 0xf1;  


System.out.println("b = 0x" + hex[(b >> 4) & 0x0f] + hex[b & 0x0f]);}}  





<!---->

    该程序的输出如下:

b = 0xf1 
<!---->
    4 .2.4 无符号右移
    正如上面刚刚看到的,每一次右移,>>运算符总是自动地用它的先前最高位的内容补它的最高位。这样做保留了原值的符号。但有时这并不是我们想 要的。例如,如果你进行移位操作的运算数不是数字值,你就不希望进行符号位扩展(保留符号位)。当你处理像素值或图形时,这种情况是相当普遍的。在这种情 况下,不管运算数的初值是什么,你希望移位后总是在高位(最左边)补0。这就是人们所说的无符号移动(unsigned shift )。这时你可以使用 Java 的无符号右移运算符>>> ,它总是在左边补0。

    下面的程序段说明了无符号右移运算符>>> 。在本例中,变量a被赋值为-1,用二进制表示就是32位全是1。这个值然后被无符号右移24位,当然它忽略了符号位扩展,在它的左边总是补0。这样得到的值255被赋给变量a。

    int a = -1; a = a >>> 24; 

    下面用二进制形式进一步说明该操作:

    11111111 11111111 11111111 11111111 int型-1的二进制代码>>> 24 无符号右移24位00000000 00000000 00000000 11111111 int型255的二进制代码

    由于无符号右移运算符>>> 只是对32位和64位的值有意义,所以它并不像你想象的那样有用。因为你要记住,在表达式中过小的值总是 被自动扩大为int 型。这意味着符号位扩展和移动总是发生在32位而不是8位或16位。这样,对第7位以0开始的byte 型的值进行无符号移动是不可 能的,因为在实际移动运算时,是对扩大后的32位值进行操作。下面的例子说明了这一点:
// Unsigned shifting a byte value. 
class ByteUShift { 
static public void main(String args[]) { 
int b = 2; 
int c = 3;  


a |= 4; 
b >>= 1;  
c <<= 1;  
a ^= c; 
System.out.println("a = " + a); 
System.out.println("b = " + b); 
System.out.println("c = " + c); 


} 
} 

<!---->
    该程序的输出如下所示:
a = 3  
b = 1  
c = 6 

<!---->

1
2
分享到:
评论
3 楼 jzitliuyang 2009-06-27  
谢谢
2 楼 wuhua 2008-04-17  
没办,很难搞。
1 楼 mingkg21 2008-04-17  
老大编辑一下,看的好辛苦。。

相关推荐

    C语言复习题 郭浩志版

    【C语言复习题郭浩志版】主要涵盖了C语言的基础概念和语法知识,包括标识符、程序结构、数据类型、运算符、表达式以及控制结构等多个方面。以下是这些知识点的详细解析: 1. **标识符**:在C语言中,合法的标识符由...

    c语言全部章节习题集20090301(参考答案).pdf

    还测试了表达式的计算,如赋值运算符、关系运算符和算术运算符的优先级。例如,算术运算符优先级高于赋值运算符,而赋值运算符优先级最低。表达式求值问题,如自增运算符`++`的使用,以及条件运算符`?`的等效表达式...

    计算机二级C语言(完整复习资料).doc

    计算机二级C语言考试是针对C语言编程能力的评估,这份完整的复习资料涵盖了C语言的基础概念、语法和常用操作。以下是对这些知识点的详细解析: 1. **C语言概述**: - C语言是一种结构化编程语言,适用于系统开发和...

    高级语言程序设计复习题及答案.doc

    `(逻辑非)具有最高的优先级,其次是关系运算符(如`、`&gt;`),再次是算术运算符(如`+`、`-`),最低的是赋值运算符(如`=`)。 6. **C语言的关键字**:`int`是C语言的关键字,而`Float`、`abc`和`CASE`不是。 7....

    C语言基础知识复习串讲资料.pdf

    总之,C语言的基础知识涵盖了许多方面,从程序结构到数据类型,再到运算符和表达式,这些概念是理解和编写C程序的关键。熟练掌握这些基础知识,对于进一步学习C语言的高级特性以及进行实际编程至关重要。

    java复习题及答案.pdf

    - 题目18的表达式涉及逻辑运算符和自增运算。正确答案是D:`a + b &gt;= c + d`。逻辑运算符的优先级比算术运算符低,所以首先会计算`a + b` 和 `c + d`,然后比较它们的值。 17. Java逻辑判断和自增问题: - 题目19...

    C语言程序设计试题及答案解析.doc

    在上述题目的解答过程中,我们复习了C语言的基本概念,如程序结构、数据类型、运算符、表达式、注释、条件判断等方面的知识,这些都是C语言学习的基础。熟练掌握这些知识点对于编写和理解C语言程序至关重要。

    C语言复习题选择结构[归类].pdf

    题目中的示例程序将输出`x=15,y=5`,因为case 1和default都会被执行,x增加1,然后x和y的值相加,y减去1,最后x再次减去1。 通过这些复习题,我们可以深入理解C语言中选择结构的使用和逻辑运算的细节,这对于软件...

    2010二级C语言南开100题

    2. **运算符与表达式**:赋值运算符、算术运算符、关系运算符、逻辑运算符、位运算符等,以及运算符的优先级和结合性。 3. **控制结构**:条件语句(if-else, switch-case)、循环语句(for, while, do-while)和...

    初中信息技术第一课用python编程优质复习知识点试卷试题.pdf

    在本篇复习资料中,涉及了多个关键概念和语法点: 1. **基本数据类型**:Python支持的数据类型包括字符串(str),整型(int),浮点型(float)等。题目中提到的`char`并不是Python的标准数据类型,Python通常用单引号或...

    本科《C++语言程序设计》期末复习模拟训练题.doc

    设题目中的部分内容是《C++语言程序设计》课程的一些复习训练题,这些题目涉及了C++编程的基础概念和语法知识。下面将详细解释这些题目所涵盖的知识点: 1. 主函数`main`:C++程序的入口点是`main`函数,因此每个...

    C语言最终模拟题含复习资料.doc

    3. **运算符优先级**:表达式`(int)((double)9/2)-(9)%2`中,浮点除法先进行,得到4.5,转换为整数是4,然后是取模运算,9%2等于1,所以整个表达式的值为3,选B。 4. **自减运算符**:表达式`x-=x+x`相当于`x = x -...

    Programming Languages Lecture Notes (Washington CSE341)

    除了上述内容外,本单元还涉及了其他重要的表达式和运算符,比如算术运算符、逻辑运算符以及模式匹配等。 ##### 缺乏变异性的优点 由于ML强调不可变性,这使得程序更容易理解和调试。不可变的数据结构可以确保一旦...

    Delphi程序设计复习资料.doc

    10. 数学表达式与Object Pascal表达式:例如,`sqrt(x^2+y^2)`在Object Pascal中为`Sqrt(Sqr(x) + Sqr(y))`,其中`Sqrt`是平方根函数,`Sqr`是平方函数。 11. 结束程序关闭窗体的方法:通常调用主窗体的`Close`或`...

    C语言习题huizong[借鉴].pdf

    C语言是计算机编程的基础之一,广泛应用于软件开发领域。它是一种高级语言,具有简洁、高效的特点。学习C语言,首先要了解其基本概念和语法。...对于红色加粗的题目,应重点复习和记忆,以确保在考试中不会再次出错。

    Python期末复习题(必考)(4).doc

    2. **运算优先级**:在 Python 表达式中,可以使用圆括号(())来控制运算的优先顺序,这被称为括号运算符。其他选项B(方括号 [])、C(花括号 {})和D(尖括号 )分别用于列表、字典和元组的定义,并不改变运算...

    C语言期中复习题PPT学习教案.pptx

    以上内容详尽解析了C语言期中复习题中的各个知识点,包括逻辑运算符、条件语句、循环控制、浮点数处理、数组操作以及级数求和等,这些是C语言学习的基础和核心。通过深入理解和练习,能够提高C语言编程能力。

    C语言复习题及答案定义.pdf

    以上是对C语言复习题的部分解析,这些题目涵盖了变量类型、逻辑运算符、循环结构、指针、结构体和联合体、文件操作等多个知识点,对于理解和掌握C语言的基本概念和语法至关重要。在实际编程中,熟练掌握这些知识能...

    C复习题.doc

    - 主函数中再次打印 `a` 和 `b` 的值; - **输出结果**:`a=3,b=5` 和 `a=3,b=5`(因为 `fun` 中的 `a` 和 `b` 是局部变量,不影响主函数中的 `a` 和 `b`)。 29. **循环与 switch 语句** - **流程分析**: - ...

Global site tag (gtag.js) - Google Analytics