Java 开发从入门到精通(第2版)
上QQ阅读APP看书,第一时间看更新

3.3 运算符

运算符是程序设计语言中重要的构成元素之一,运算符可以细分为算术运算符、位运算符、关系运算符、逻辑运算符和其他运算符。在本节的内容中,我们将详细讲解Java语言中运算符的基本知识。

知识点讲解:

3.3.1 算术运算符

在数学中有加减乘除运算,算术运算符(Arithmetic Operator)就是用来处理数学运算的符号,这是最简单、也最常用的符号。在数字处理中几乎都会用到算术运算符,算术运算符可以分为基本运算符、取余运算符和递增或递减运算符等。具体说明如表3-2所示。

表3-2 算术运算符

1.基本运算符

在Java程序中,使用最广泛的便是基本运算符。

实例3-8

使用基本运算符的加减乘除4种运算

源码路径:daima\3\JiBen1.java

实例文件JiBen1.java的主要实现代码如下所示。

        public static void main(String args[]) {
        ①           int a=12;
        ②           int b=4;
                    //下面开始使用4种运算符
        ③           System.out.println(a-b);
        ④           System.out.println(a+b);
        ⑤           System.out.println(a*b);
        ⑥           System.out.println(a/b);
          }

拓展范例及视频二维码

范例3-8-01:演示基本运算的过程

源码路径:演练范例\3-8-01\

范例3-8-02:实现加密处理

源码路径:演练范例\3-8-02\

行①②分别定义两个int类型的变量a和b,设置a的初始值是12,设置b的初始值是4。

行③使用println()函数输出变量a和变量b的差。

行④使用println()函数输出变量a和变量b的和。

行⑤使用println()函数输出变量a和变量b的乘积。

行⑥使用println()函数输出变量a除以b的结果。

执行后的结果如图3-8所示。

图3-8 使用基本运算符

注意:分母为零的情况要引起重视。计算机中的运算和数学运算有些不同,一般来说分母不能为零,为零会发生程序错误,但有时程序中分母为零并不是错误,例如下面的代码(daima\3\Jiben.java)。

        public class Jiben {
          public static void main(String args[]){
                int AAA=126;          //定义int类型变量AAA的值是126
                //整型数据的分母不能为零
                System.out.println(a/0);
          }
        }

编译上述代码后会得到图3-9所示的结果。

图3-9 运行结果

上面的结果提示用户分母不能为零,如果将上述代码中的“int AAA=126”改为“double AAA=126”,编译后会得到图3-10所示的结果。

图3-10 更改后的运行结果

对于基本运算符,只要将分子定义为double型,分母为零就是正确的,得到的值是无穷大,这一点希望初学者能够加以理解。

2.取余运算符

在现实应用中,除法运算的结果不一定总是整数,计算结果是使用第一个运算数除以第二个运算数,得到整数结果后剩下的值,就是余数。在Java程序中,取余运算符用于计算除法操作中的余数。由于取余运算符也需要进行除法运算,因此如果取余运算的两个运算数都是整数类型,则求余运算的第二个运算数不能是0,否则将引发除以零异常。如果取余运算的两个操作数中有1个或2个是浮点数,则允许第二个操作数是0或0.0,只是求余运算的结果是NaN(NaN是Java中的特殊数字,表示非数字类型)。0或0.0对零以外的任何数求余都将得到0或0.0。

注意:取余运算符是一种很奇怪的运算符,在数学运算中很少被提及,其实可以很简单地理解它。取余运算符一般被用在除法中,它的取值不是商,而是余数。例如5/2,取余运算符取的是余数,所以结果是1,而不是商值结果2.5。

实例3-9

使用“%”运算符

源码路径:daima\3\Yushu.java

实例文件Yushu.java的主要实现代码如下所示:

        public static void main(String[] args) {
          //求余数
        ①        int A=19%3;
        ②        int K=-19%-3;
        ③        int Q=19%-3;
        ④        int J=-19%3;
        ⑤        System.out.println("A=19%3的余数"+A);
        ⑥        System.out.println("K=-19%-3的余数"+K);
        ⑦        System.out.println("Q=19%-3的余数"+Q);
        ⑧        System.out.println("J=-19%3的余数"+J);
        }

拓展范例及视频二维码

范例3-9-01:演示取余运算的规律

源码路径:演练范例\3-9-01\

范例3-9-02:用三元运算符判断奇偶数

源码路径:演练范例\3-9-02\

行①定义1个int类型的变量A,设置其初始值是19除以3的余数。

行②定义1个int类型的变量K,设置其初始值是-19除以-3的余数。

行③定义1个int类型的变量Q,设置其初始值是19除以-3的余数。

行④定义1个int类型的变量J,设置其初始值是-19除以3的余数。

行⑤⑥⑦⑧分别使用println()函数输出4个变量A、K、Q和J的值。

执行后的结果如图3-11所示。

图3-11 取余运算

3.递增和递减运算符

递增和递减运算符分别是指“++”和“--”,每执行一次,变量将会增加1或减少1,它们可以放在变量的前面,也可以放在变量的后面。无论哪一种形式都能改变变量的结果,但它们有一些不同,这种变化让初学编程的人感到疑惑。递增、递减对于刚学编程的人来说是难点,读者一定要加强理解。理解的不是++与--的问题,而是在变量前用还是在变量后用的问题。

实例3-10

使用递增和递减运算符

源码路径:daima\3\Dione.java

实例文件Dione.java的主要实现代码如下所示。

        public static void main(String args[]){
        ①       int a=199;
        ②       int b=1009;
                //数据的递增与递减
        ③       System.out.println(a++);
        ④       System.out.println(a);
        ⑤       System.out.println(++a);
        ⑥       System.out.println(b--);
        ⑦       System.out.println(b);
        ⑧       System.out.println(--b);
        }

拓展范例及视频二维码

范例3-10-01:演示递增和递减运算符的用法

源码路径:演练范例\3-10-01\

范例3-10-02:更精确地运用浮点数

源码路径:演练范例\3-10-02\

行①②分别定义两个int类型的变量a和b,设置a的初始值是199,设置b的初始值是1009。

行③使用println()函数输出a++的值,此处先输出,然后才加1,所以结果是199。

行④使用println()函数输出a的值,因为在行②的最后加1了,所以这里的结果是200。

行⑤使用println()函数输出++a的值,此处先加1,再输出。这里要紧接着行④中a的值200,所以本行的结果是201。

行⑥使用println()函数输出b--的值,此处先输出b的值,再将b减1,所以本行的结果是1009。

行⑦使用println()函数输出b的值,因为在行⑥的最后减1了,所以这里的结果是1008。

行⑧使用println()函数输出--b的值,此处先减1,然后执行程序。这里要紧接着行⑦中b的值1008,所以本行的结果是1007。

执行后的结果如图3-12所示。

图3-12 使用递增和递减运算符

3.3.2 关系运算符和逻辑运算符

在Java程序设计中,关系运算符(Relational Operator)和逻辑运算符(Logical Operator)显得十分重要。关系运算符定义值与值之间的相互关系,逻辑(logical)运算符定义可以用真值和假值链接在一起的方法。

1.关系运算符

在数学运算中有大于、小于、等于、不等于关系,在程序中可以使用关系运算符来表示上述关系。表3-3中列出了Java中的关系运算符,通过这些关系运算符会产生一个结果,这个结果是一个布尔值,即true或false。在Java中,任何类型的数据,都可以用“= =”比较是不是相等,用“!=”比较是否不相等,只有数字才能比较大小,关系运算的结果可以直接赋予布尔变量。

表3-3 关系运算符

2.逻辑运算符

布尔逻辑运算符是最常见的逻辑运算符,用于对布尔型操作数进行布尔逻辑运算,Java中的布尔逻辑运算符如图3-4所示。

表3-4 逻辑运算符

逻辑运算符与关系运算符运算后得到的结果一样,都是布尔类型的值。在Java程序设计中,“&&”和“”布尔逻辑运算符不总是对运算符右边的表达式求值,如果使用逻辑与“&”和逻辑或“|”,则表达式的结果可以由运算符左边的操作数单独决定。通过表3-5,读者可以了解常用逻辑运算符“&&”、“”、“! ”运算后的结果。

表3-5 逻辑运算符

在接下来的内容中,将通过一个具体实例来说明关系运算符的基本用法。

实例3-11

使用关系运算符

源码路径:daima\3\guanxi.java

实例文件guanxi.java的主要实现代码如下所示。

        public static void main(String args[]){
        ①    char a='k';          //为a赋值
        ②    char b='k';          //为b赋值
        ③    char c='A';          //为c赋值
        ④    int d=100;           //为d赋值
        ⑤    int e=101;           //为e赋值
        ⑥     System.out.println(a==b);
               //下面开始分别输出对应的运算结果
        ⑦     System.out.println(b==c);
        ⑧     System.out.println(b! =c);
        ⑨     System.out.println(d<e);
          }

拓展范例及视频二维码

范例3-11-01:演示逻辑运算符的用法

源码路径:演练范例\3-11-01\

范例3-11-02:不用乘法运算符实现2×16

源码路径:演练范例\3-11-02\

行①②③分别定义3个cha类型的变量a、b和c,并分别设置它们的初始值。

行④⑤分别定义两个int类型的变量d和e,并分别设置它们的初始值。

行⑥使用println()函数输出a==b的结果。

行⑦使用println()函数输出b==c的结果。

行⑧使用println()函数输出b!=c的结果。

行⑨使用println()函数输出d<e的结果。

执行后的结果如图3-13所示。

图3-13 使用关系运算符

3.3.3 位逻辑运算符

在Java程序设计中,使用位逻辑运算符来操作二进制数据。读者必须注意,位逻辑运算符只能操作二进制数据。如果用在其他进制的数据中,需要先将其他进制的数据转换成二进制数据。位逻辑运算符(Bitwise Operator)可以直接操作整数类型的位,这些整数类型包括long、int、short、char和byte。Java语言中位逻辑运算符的具体说明如表3-6所示。

表3-6 位逻辑运算符

因为位逻辑运算符能够在整数范围内对位操作,所以这样的操作对一个值产生什么效果是很重要的。具体来说,了解Java如何存储整数值并且如何表示负数是非常有用的。表3-7中演示了操作数A和操作数B按位逻辑运算的结果。

表3-7 位逻辑运算结果

移位运算符把数字的位向右或向左移动,产生一个新的数字。Java的右移运算符有两个,分别是>>和>>>。

❑ >>运算符:把第一个操作数的二进制码右移指定位数后,将左边空出来的位以原来的符号位填充。即,如果第一个操作数原来是正数,则左边补0;如果第一个操作数是负数,则左边补1。

❑ >>>:把第一个操作数的二进制码右移指定位数后,将左边空出来的位以0填充。

在接下来的内容中,将通过一个具体实例来说明位逻辑运算符的基本用法。

实例3-12

使用位逻辑运算符

源码路径:daima\3\wei.java

实例文件wei.java的主要实现代码如下所示。

        public class wei {
              public static void main(String[] args){
        ①     int a=129;
        ②     int b=128;
        ③     System.out.println("a和b 与的结果是:"+(a&b));
              }
        }

拓展范例及视频二维码

范例3-12-01:演示与运算符的用法

源码路径:演练范例\3-12-01\

范例3-12-02:演示非运算符的用法

源码路径:演练范例\3-12-02\

行①②分别定义两个cha类型的变量ab,并分别设置它们的初始值。

行③使用println()函数输出a&b的结果。a的值是129,转换成二进制就是10000001;而b的值是128,转换成二进制就是10000000。根据与运算符的运算规律,只有两个位都是1,运算结果才是1,所以a&b的运算过程如下。

        a          10000001
        b          10000000
        a&b       10000000

由此可以知道10000000的结果就是10000000,转换成十进制就是128。执行后的结果如图3-14所示。

图3-14 执行结果

3.3.4 条件运算符

条件运算符是一种特殊的运算符,也被称为三目运算符。它与前面所讲的运算符有很大不同,Java中提供了一个三目运算符,其实这跟后面讲解的if语句有相似之处。条件运算符的目的是决定把哪个值赋给前面的变量。在Java语言中使用条件运算符的语法格式如下所示。

        变量=(布尔表达式)? 为true时赋予的值:为false时赋予的值;

实例3-13

使用条件运算符

源码路径:daima\3\tiao.java

实例文件tiao.java的主要实现代码如下所示。

          public static void main(String args[]){
          ①     double chengji=70;
          ②     String Tiao=(chengji>=90)? "已经很优秀":
                            "不是很优秀, 还需要努力!";
                //输出结果
          ③     System.out.println(Tiao);
          }

拓展范例及视频二维码

范例3-13-01:根据条件的不同实现赋值

源码路径:演练范例\3-13-01\

范例3-13-02:实现两个变量的互换

源码路径:演练范例\3-13-02\

行①定义double类型的变量chengji,设置其初始值是70。

行②定义String类型的变量Tiao,并赋值显示条件运算结果。如果设置变量chengji大于或等于90,则输出“已经很优秀”的提示;反之,就输出“不是很优秀,还需要努力!”的提示。

行③使用println()函数输出Tiao的值。因为在代码中设置了“chengji=70”,所以执行后的结果如图3-15所示。

图3-15 执行结果

3.3.5 赋值运算符

赋值运算符是等号“=”,Java中的赋值运算与其他计算机语言中的赋值运算一样,起到赋值的作用。在Java中使用赋值运算符的格式如下所示。

          var = expression;

其中,变量var的类型必须与表达式expression的类型一致。

赋值运算符有一个有趣的属性,它允许我们对一连串变量进行赋值。请看下面的代码。

          int x, y, z; x = y = z = 100;

在上述代码中,使用一条赋值语句将变量x、y、z都赋值为100。这是由于“=”运算符表示右边表达式的值,因此z = 100的值是100,然后该值被赋给y,并依次被赋给x。使用“字符串赋值”是给一组变量赋予同一个值的简单办法。在赋值时类型必须匹配,否则将会出现编译错误。

实例3-14

演示赋值类型不匹配的错误

源码路径:daima\3\fuzhi.java

实例文件fuzhi.java的主要实现代码如下所示。

          public static void main(String args[]){
              //定义的字节数据
          ①     byte a=9;
          ②     byte b=7;
          ③     byte c=a+b;
          ④     System.out.println(c);
          }

拓展范例及视频二维码

范例3-14-01:扩展赋值运算符的功能

源码路径:演练范例\3-14-01\

范例3-14-02:演示运算符的应用

源码路径:演练范例\3-14-02\

行①分别定义byte类型的变量a和b,设置a的初始值是9,设置b的初始值是7。

行②定义byte类型的变量c,并赋值为a和b的和。Java语言规定:byte类型的变量在进行加减乘除和余数运算时会自动变为int类型。所以,本行的变量a和b会在计算时自动转换成int类型,但是本行在左侧已经明确声明为了byte类型,所以会出错。

行③使用println()函数输出变量c的值。执行后会提示类型不匹配错误,执行结果如图3-16所示。

图3-16 类型不匹配错误

注意:在Java中可以对赋值运算符进行扩展,其中最为常用的有如下扩展操作。

❑ +=:对于x+=y,等效于x=x+y。

❑ -=:对于x-=y,等效于x=x-y。

❑ *=:对于x*=y,等效于x=x*y。

❑ /=:对于x/=y,等效于x=x/y。

❑ %=:对于x%=y,等效于x=x%y。

❑ &=:对于x&=y,等效于x=x&y。

❑ |=:对于x|=y,等效于x=x|y。

❑ ^=:对于x^=y,等效于x=x^y。

❑ <<=:对于x<<=y,等效于x=x<<y。

❑ >>=:对于x>>=y,等效于x=x>>y。

❑ >>>=:对于x>>>=y,等效于x=x>>>y。

另外,在后面的学习中我们会接触到equals()方法,此方法和赋值运算符= =的功能类似。要想理解两者之间的区别,我们需要从变量说起。Java中的变量分为两类,一类是值类型,它存储的是变量真正的值,比如基础数据类型,值类型的变量存储在内存的栈中;另一类是引用类型,它存储的是对象的地址,与该地址对应的内存空间中存储的才是我们需要的内容,比如字符串和对象等,引用类型的变量存储在内存中的堆中。赋值运算符= =比较的是值类型的变量,如果比较两个引用类型的变量,比较的就是它们的引用地址。equals()方法只能用来比较引用类型的变量,也就是比较引用的内容。

= =运算符比较的是左右两边的变量是否来自同一个内存地址。如果比较的是值类型(基础数据类型,如int和char之类)的变量,由于值类型的变量存储在栈里面,当两个变量有同一个值时,其实它们只用到同一个内存空间,所以比较的结果是true。

eqluals()方法是Object类的基本方法之一,所以每个类都有自己的equals()方法,功能是比较两个对象是否是同一个,通俗的理解就是比较这两个对象的内容是否一样。

3.3.6 运算符的优先级

数学中的运算都是从左向右运算的,在Java中除了单目运算符、赋值运算符和三目运算符外,大部分运算符也是从左向右结合的。单目运算符、赋值运算符和三目运算符是从右向左结合的,也就是说,它们是从右向左运算的。乘法和加法是两个可结合的运算,也就是说,这两个运算符左右两边的操作符可以互换位置而不会影响结果。

运算符有不同的优先级,所谓优先级,就是在表达式运算中的运算顺序。表3-8中列出了包括分隔符在内的所有运算符的优先级,上一行中的运算符总是优先于下一行的。

表3-8 Java运算符的优先级

根据表3-9所示的运算符的优先级,假设int a=3,开始分析下面变量b的计算过程。

          int b= a+2*a

程序先执行2*a得到6,再计算a+6得到9。使用圆括号( )可以改变程序的执行过程,例如:

          int b=(a+2)*a

先执行a+2得到5,再用5*a得到15。

实例3-15

使用表达式与运算符

源码路径:daima\3\biaoone.java

实例文件biaoone.java的主要实现代码如下所示。

          public static void main(String args[]){
          ①       int a=231;
          ②       int b=4;
          ③       int h=56;
          ④       int k=45;
          ⑤       int x=a+h/b;
          ⑥       int y=h+k;
          ⑦        System.out.println(x);
          ⑧        System.out.println(y);
          ⑨        System.out.println(x==y);
          }

拓展范例及视频二维码

范例3-15-01:演示运算符的优先级

源码路径:演练范例\3-15-01\

范例3-15-02:演示关系运算符的应用

源码路径:演练范例\3-15-02\

行①②③④分别定义4个int类型的变量a、b、h和k,设置a的初始值是231,设置b的初始值是4,设置h的初始值是56,设置k的初始值是45。

行⑤定义一个int类型的变量x,并赋值为a+h/b,根据优先级规则,先计算除法h/b,后计算加法。

行⑥定义一个int类型的变量y,并赋值为h+k。

行⑦⑧⑨使用println()函数分别输出变量x、y和表达式x= =y的值。

执行后的结果如图3-17所示。

图3-17 执行结果

注意:书写Java运算符有两点注意事项。

(1)不要把一个表达式写得过于复杂,如果一个表达式过于复杂,就把它分成几步来完成。

(2)不要过多地依赖运算符的优先级来控制表达式的执行顺序,这样可读性太差,尽量使用圆括号( )来控制表达式的执行顺序。