精确快速的计算能力是计算机最重要的能力之一,而这种能力是通过程序设计语言中各种五花八门的表达式来实现的。表达式(Expression)就像平常所用的数学公式一样,是由运算符(Operator)与操作数(Operand)所组成的。以下是一个简单的表达式:
d=a*b-123.4;
这个表达式中的d、a、b、123.4等常数或变量被称为操作数,而=、*、-等运算符号被称为运算符。Java语言的运算符除了基本的加、减、乘、除四则运算符之外,还有很多运算符,例如赋值运算符(=)。表2-8列出了Java中基本的四则运算符以及其他用途的运算符。
表2-8
表达式由操作数和运算符组成。操作数代表运算数据,运算符代表运算关系,例如算术运算符、关系运算符、逻辑运算符、移位运算符以及赋值运算符等。任何运算都与操作数和运算符有关,如图2-12所示。
图2-12 任何运算都与操作数和运算符有关
算术运算符(Arithmetic Operator)的用途类似一般数学运算中的加(+)、减(-)、乘(×)和除(÷)四则运算,是经常使用的数学运算符。这些算术运算符在Java语言中的用法及功能与它们在传统的数学中的用法及功能相同。不过,我们要注意的是加法运算符,在Java中,它除了可以执行数值加的运算,还具有“字符串串接”的功能。
(1)加、减、乘、除及求余数
加、减、乘、除及求余数运算符的用法可以参考表2-9。
表2-9
其中,四则运算符和数学上的功能一模一样,在此不多做介绍。而求余数运算符“%”用于计算两数相除后的余数,这个运算要求参与运算的两个操作数都必须是整数类型。
(2)递增(Increment)与递减(Decrement)运算
递增“++”和递减运算符“--”是对变量加1和减1的简写方式,这种运算只适用于整数类型的变量,属于一元运算符(或称为单目运算符),它们可增加程序代码的简洁性。要注意的是,递增或递减运算符在变量前后的位置不同,虽然都是对操作数执行加1或减1的运算,但是在表达式中的运算顺序还是有差别的,递增与递减运算符可以分为前缀(Prefix)和后缀(Postfix)两种。使用方式和运算结果可参考表2-10。
表2-10
(3)数值的正负数表示
正数默认不需要带加号,但负数则要使用负号(即减法运算符)来表示。当负数进行减法运算时,为了避免运算符的混淆,最好以空格符或小括号“()”隔开,例如:
int x=5; // 声明变量x为int整数类型,并把它的初值设为5 x=x- -2; // 用空格符隔开,避免和递减运算符相混淆 x=x-(-2); // 用小括号隔开
【范例程序:CH02_09】
01 /*文件名:CH02_09.java 02 *说明:水果礼盒 03 */ 04 public class CH02_09 { 05 public static void main(String args[]) { 06 int apple=15,banana=20;//声明变量 07 System.out.print("(1).小明买了苹果15个,香蕉20根,水果总共买了"); 08 System.out.println((apple+banana)+"个"); 09 System.out.print("(2).苹果每个3元,香蕉每根1元,总共花费了"); 10 System.out.println((apple*3+banana*1)+"元"); 11 System.out.print("(3).将苹果4个和香蕉3根装成一盒,共可装"); 12 System.out.println((apple/4)+"盒"); 13 System.out.println("(4).装盒后苹果剩下"+(apple%4)+"个,"+"香蕉剩下"+(20-apple/4*3)+"根"); 14 } 15 }
【程序的执行结果】
程序的执行结果可参考图2-13。
图2-13
【程序的解析】
第06行:声明变量apple(苹果)和banana(香蕉),并分别设置初值为15和20。根据数量的数据类型,因而声明这两个变量为int类型。
第07~13行:示范简单的算术运算。
关系运算符(Relational Operator)用于比较两个操作数之间的关系,是大于(>)、小于(<)还是等于(==),诸如此类的关系都可以用关系运算符来运算。运算的结果为布尔值,如果关系成立,就返回真(true);如果关系不成立,就返回假(false)。在Java中,关系比较运算符共有6种,如表2-11所示。
表2-11
需要注意的是,一般数学上使用“≠”表示不等于,但是“≠”符号在编辑软件中无法直接从键盘输入,因此Java语言使用“!=”来代替“≠”表示不等于。另外,等于关系的表示方式在数学上一般使用一个等于符号(=)来表示,不过在Java语言中是以两个等于符号(==)来表示的,因此读者在编写Java程序中要表达“不等于”和“等于”时要多加注意。
【范例程序:CH02_10】
01 /*文件名:CH02_10.java 02 *说明:关系运算 03 */ 04 public class CH02_10 { 05 public static void main(String args[]) { 06 System.out.print("15大于5 为"+(15>5)+"\n"); 07 System.out.print("15小于5 为"+(15<5)+"\n"); 08 System.out.print("15大于等于15 为"+(15>=15)+"\n"); 09 System.out.print("15小于等于5 为"+(15<=5)+"\n"); 10 System.out.print("15不等于5 为"+(15!=5)+"\n"); 11 System.out.print("15等于5 为"+(15==5)+"\n"); 12 } 13 }
【程序的执行结果】
程序的执行结果可参考图2-14。
图2-14
【程序的解析】
第06~11行:用关系运算符判断两个操作数之间的关系,判断的结果为布尔(Boolean)数据类型。
程序代码中使用“"\n"”表示“换行”的意思。
逻辑运算符(Logical Operator)用于基本的逻辑运算,判断的结果也是布尔数据类型,如果结果为真,其值为true(可用数字1表示);如果结果为假,其值为false(可用数字0表示)。&&和||运算符的运算顺序是从左到右,而!运算符的运算顺序是从右到左。
逻辑运算符在运用上可分为“布尔数据类型的逻辑运算”和“位的逻辑运算”。逻辑运算符用于判断两个关系运算符之间的关系,例如用于计算“a>0&&b>0”这类逻辑运算的结果。
(1)布尔数据类型的逻辑运算
Java中的逻辑运算符共有4种,如表2-12所示。
表2-12
“!”代表“非”,是求反的意思。“&&”(AND)和“||”(OR)逻辑运算的真值表可参考表2-13和表2-14。
表2-13
表2-14
(2)位的逻辑运算
操作数在计算机内存中存储的值实际上是以二进制方式存储的。我们可以使用位运算符(Bitwise Operator)来对两个整数操作数进行位与位之间的逻辑运算。我们将整数转换成二进制数值时必须注意不同整数类型占用的存储空间,byte类型的数值5占用一个字节,因而转换为二进制值为“00000101”,即8个二进制位(bit)。若是short类型,则占用两个字节,对应16个二进制位;int类型占用4个字节,对应32个二进制位;long类型占用8个字节,占用64个二进制位。
Java语言提供了4种位逻辑运算符,分别是&(AND,即“与”)、|(OR,即“或”)、^(XOR,即“异或”)与~(NOT,即“非”),如表2-15所示。
表2-15
【范例程序:CH02_11】
01 /*文件名:CH02_11.java 02 *说明:逻辑运算 03 */ 04 public class CH02_11 { 05 public static void main(String args[]) { 06 int a=15,b=3; 07 System.out.println("(a>10)&&(b>5)的返回值为 "+(a>10&&b>5)); 08 System.out.println("(a>10)||(b>5)的返回值为 "+(a>10||b>5)); 09 System.out.println("(a>10)&(b>5)的返回值为 "+(a>10&b>5)); 10 System.out.println("(a>10)|(b>5)的返回值为 "+(a>10|b>5)); 11 System.out.println("(a>10)^(b>5)的返回值为 "+(a>10^b>5)); 12 System.out.println(" 15 & 3 的返回值为 "+(a&b)); 13 System.out.println(" 15 | 3 的返回值为 "+(a|b)); 14 System.out.println(" 15 ^ 3 的返回值为 "+(a^b)); 15 System.out.println(" ~3 的返回值为"+(~b)); 16 } 17 }
【程序的执行结果】
程序的执行结果可参考图2-15。
图2-15
【程序的解析】
第07~11行:布尔类型的逻辑运算。
第12~15行:位的逻辑运算。
移位运算符(Shift Operator)应用于整数类型,将整数转换成二进制后,对二进制的各个位做向左或向右的移动。在Java语言中有两种移位运算符,可参考表2-16的说明。
表2-16
【范例程序:CH02_12】
01 /*文件名:CH02_12.java 02 *说明:移位运算 03 */ 04 public class CH02_12 { 05 public static void main(String args[]) { 06 System.out.println("5 << 2 的返回值为 "+(5<<2)); 07 System.out.println("-5 << 2 的返回值为 "+(-5<<2)); 08 System.out.println("5 >> 2的返回值为 "+(5>>2)); 09 System.out.println("-5 >> 2的返回值为 "+(-5>>2)); 10 } 11 }
【程序的执行结果】
程序的执行结果可参考图2-16。
图2-16
【程序的解析】
第06~09行:整数的移位运算。
赋值运算符(Assignment Operator)由至少两个操作数组成,主要作用是将等号“=”右方的值或者表达式的计算结果赋予等号左方的变量。由于是将“=”号右边的值赋值给“=”号左边,因此“=”号的左边必须是变量,而右边则可以是变量、常数或表达式等。
初学者很容易将赋值运算符“=”的作用和数学上的“等于”功能混淆,在程序设计语言中,“=”主要是赋值的概念。以下是赋值运算符的使用方式:
变量名称 = 要赋予的值或表达式;
例如:
a= a + 5; /* 将a值加5后赋值给变量a */ c ='A'; /* 将字符'A'赋值给变量c */
a=a+5在数学上根本不成立,不过在Java的世界中,我们可以这样解读:当声明变量之后,在内存中已经给这个变量分配了内存空间,在后续使用中就要使用赋值运算符来给该变量赋值。Java语言的赋值运算符除了一次给一个变量赋值外,还能够把同一个数值同时赋值给多个变量,例如:
int x,y,z; x=y=z=200; /* 把一个值同时赋给不同变量 */
在Java中还有一种复合赋值运算符,是由赋值运算符与其他运算符组合而成的。先决条件是赋值号“=”右边的源操作数必须有一个和左边接收赋值数值的操作数相同,如果一个表达式含有多个复合赋值运算符,运算过程必须从右边开始,逐步进行到左边。
例如以“A+=B;”语句来说,它就是语句“A=A+B;”的精简写法,也就是先执行A+B的计算,接着将计算结果赋值给变量A。这类运算符的说明及使用语法如表2-17所示。
表2-17
下面的范例程序用于说明复合赋值运算符的使用方式。要特别注意的是,在运算过程中,运算的顺序是从赋值号的右边开始的,而后逐步进行到左边。例如,复合赋值运算符在多重表达式中的使用:
a+=a+=b+=b%=4;
这个表达式的实际运算顺序和运算过程如下:
b =b%4 b=b+b; a=a+b; a=a+a;
【范例程序:CH02_13】
01 /*文件名:CH02_13.java 02 *说明:赋值运算 03 */ 04 public class CH02_13 { 05 public static void main(String args[]) { 06 int A=5; 07 System.out.println("A=5 "); 08 A+=3+2; 09 System.out.println("A+= 3+2 的值为 "+(A)); 10 A=5; 11 A-=5-4; 12 System.out.println("A-= 5-4 的值为 "+(A)); 13 A=5; 14 A*=2*3; 15 System.out.println("A*= 2*3 的值为 "+(A)); 16 A=5; 17 A/=10/5+3; 18 System.out.println("A/= 10/5+3 的值为 "+(A)); 19 A=5; 20 A%=15%4; 21 System.out.println("A%= 15%4的值为 "+(A)); 22 A=5; 23 A &=5-3; 24 System.out.println("A&= 5-3 的值为 "+(A)); 25 A=5; 26 A|=2; 27 System.out.println("A|= 2 的值为 "+(A)); 28 A=5; 29 A^=2+1; 30 System.out.println("A^= 2+1 的值为 "+(A)); 31 } 32 }
【程序的执行结果】
程序的执行结果可参考图2-17。
图2-17
【程序的解析】
第06~30行:变量A的赋值运算。
一个表达式中往往包含多个运算符,这些运算符执行的先后顺序如何呢?这时就需要按照运算符的优先级来建立运算规则。当表达式中使用多个运算符时,例如z=x+3*y,就必须按照运算符的优先级来进行运算。按照数学基本运算中“先乘除后加减”的规则,这个表达式会先执行3*y的运算,把运算的结果与x相加,再将相加的结果赋值给z,最后得到这个表达式的最终运算结果。在Java中,在处理含有多个运算符的表达式时,同样必须遵守一些规则与步骤,说明如下:
(1)当遇到一个表达式时,先区分运算符与操作数。
(2)按照运算符的优先级进行整理。
(3)将各个运算符根据其结合顺序进行运算。
在进行包含多种运算符的运算时,必须先了解各种运算符的“优先级”和“结合律”。假如表达式中有多个运算符,那么各个运算符要按照既定的顺序完成运算,这里所说的顺序就是运算符“优先运算的顺序”。表达式中常见的括号(如“()”)具有最高的优先级,即括号内的运算优先级高于括号外的运算优先级。表2-18列出了Java中各种运算符的优先级。
表2-18
表2-18中所列的优先级,1代表最高优先级,15代表最低优先级。“结合律”指在表达式中遇到同等级优先级时的运算规定,如“3+2-1”,加号“+”和减号“-”同属于优先级4,根据结合律,顺序是从左到右,先从最左边执行“3+2”的运算后,再往右执行减“-1”的运算。程序设计人员应该熟悉各个运算符的优先级和结合律,这样在编写程序时才不至于出现这类错误或不合理的问题。