好好学Java:从零基础到项目实战
上QQ阅读APP看书,第一时间看更新

2.2.3 一元运算符

前面讲到赋值运算符的时候,提到“x=x+7”可以被“x += 7”取代,当然Java编程中给某个变量自加7并不常见,常见的是给某个变量自加1,就像走台阶,一般都是一级一级台阶地走,用不着一下子跳上7级台阶。对于变量自加1的情况,既可以写成“x=x+1”,又可以写成“x += 1”,但是早期的Java设计师觉得前面的语句不够简洁,故而创造了新的运算符“++”,该运算符表示给变量自加1,于是“x += 1”可再简化为“x++”。同理,运算符“--”表示给变量自减1,语句“x--”等价于“x -= 1”和“x=x-1”。为深入理解“++”与“--”这两个运算符的作用,不妨运行下面的演示代码观察结果(完整代码见本章源码的src\com\arithmetic\operator\Unary.java):

int x=3;
System.out.println("初始 x="+x);
x++;  // 等同于x=x+1或者x+=1
System.out.println("自增1 x="+x);
x--;  // 等同于x=x-1或者x-=1
System.out.println("自减1 x="+x);

既然有了自加1运算“++”和自减1运算“--”,那么有没有自乘运算“**”和自除运算“//”呢?很遗憾Java不存在自乘与自除。倘若自乘运算指的是求某变量的平方,还是老老实实地写成 “x=x*x”或者“x *= x”;倘若自除运算指的是求某变量的倒数,也要老老实实地写成“double y=1.0/x”。求平方与求倒数的代码如下:

// 没有“**”这个运算符,求平方还是按照常规写法
x *= x;  // 也可以写成x=x*x
System.out.println("求平方 x="+x);
// “//”已经被用作注释标记了,求倒数也得按照常规写法,而且整数的倒数只能是小数
double y=1.0/x;  // 注意这里的1.0/x,由于x是整型数,因此1/x无法求得小数
System.out.println("求倒数 y="+y);

由于“++”和“--”从头到尾只有变量自身参与运算,并无其他的操作数,因此又被称作一元运算符。类似的一元运算符还有负号运算符“-”和正号运算符“+”,这两个符号其实也来源于数学,都放在数字前面,比如“-1”表示负1,“+1”表示正1。但在Java编程中,变量前面的正负号概念有所不同,例如“-x”指的是对x做负号运算,“x=-x”等价于“x=0-x”。倘若整型变量x原来是正值,则负号运算的结果为负值;但若x原来是负值,则负号运算的结果变为正值,也就是所谓的负负得正。至于“x=+x”等价于“x=0+x”,显然正号运算的结果与原值相同,正值的正号运算结果仍为正值,负值的正号运算结果仍为负值,而非数学上的正号意义。

要想验证上述的正负运算符,可运行以下代码观察测试结果:

x=-x;  // 等同于x=0-x
System.out.println("负数 x="+x);
x=+x;  // 等同于x=0+x
System.out.println("正数 x="+x);

注意到上面的正负运算符直接放在变量之前,实际上“++”和“--”也允许放在变量前面,单独的“++x”等价于“x++”,单独的“--x”等价于“x--”。之所以特别强调“单独”二字,是因为一旦它们放到了其他语句之中,运算结果就将大不相同。譬如以下代码演示了二者之间的区别:

int y1=7;
int z1=y1++;  // 后加加操作的优先级较低
System.out.println("z1="+z1);
int y2=7;
int z2=++y2;  // 前加加操作的优先级较高
System.out.println("z2="+z2);

运行上面的演示代码,会得到下面的日志信息:

z1=7

z2=8

可见此时z1的数值不等于z2。究其原因,乃是前加加与后加加的运行机制差异所致。对于“int z1=y1++;”,该语句在执行时会分解成两个步骤:先执行对z1的赋值操作,再执行对y1的自增操作。此时,最终的运行步骤如以下代码:

int z1=y1;      // 先执行赋值操作
y1=y1+1;          // 再执行自增操作

对于“int z2=++y2;”,该语句在执行时也会分解成两个步骤:先执行对y1的自增操作,再执行对z1的赋值操作。此时,最终的运行步骤如以下代码:

y2=y2+1;         // 先执行自增操作
int z2=y2;      // 再执行赋值操作

其实这种情况很好理解,计算机语言跟人类文字的书写顺序一样,都是从上到下、从左往右。定睛一看“x++”,果然先看到变量x,接着才看到自增运算++;回头再瞅“++x”,这下先看到自增运算,然后才看到变量x。同样是书面文字,计算机语言和人类语言的语法逻辑大不相同。

最后来一个脑筋急转弯,现有变量z1值为7,变量z2值为8,看下面代码的运算结果,变量z3的数值为多少?有兴趣的读者不妨一试。

int z1=7, z2=8;       //假设z1为7,z2为8
int z3=++z1+z2++;  //那么z3该为何值?