运算符 - 图1

算术运算符

运算符 说明
+
-
*
/
% 取余数

  加减乘的运算和数学中的使用没有区别,其中+、-运算符还可以作为数据的正负号,比如+5,-7。
  需要注意的是:加号两边的数据都是数的时候是加,是字串的话就是字符串的拼接。

  除法 /
  操作数都是整数时,和数学中相同的是,0不能作为除数(但是可以是0.0!!)。
  操作数都是整数时,和数学中不同的是,进行除法得到的是舍去小数部分的整数,此时并不是数学中的除法。
  0不可以做除数但是0.0可以做除数,这是因为0.0是double类型的数据,浮点型数据代表的不是准确值而是近似值,所以0.0代表的不是0,而是无限趋近于0(没错就是极限)

  1. public void mrxs() {
  2. double x = 0.0;
  3. double y = 64.0;
  4. System.out.println(y / x);
  5. }

  上面代码输出的结果是运算符 - 图2其中Infinity表示无限。

public void mrxs() {
    double x = 0.0;
    double y = 64.0;
    System.out.println(y % x);
}

  上面代码输出结果是运算符 - 图3其中NaN是Not a Number,非数。

  取余数 %
  注意取余和取模不是一回事。
  取余和取模的过程都是:
  c = a / b;
  r = a - b * c;
  但是取余和取模不同的地方在于c的选取,取余希望c的绝对值小(向0方向),而取模希望c的值小(向负无穷方向)
  取余:取余的结果和被除数同号
运算符 - 图4
  取模:模的结果和除数同号
运算符 - 图5

自加自减运算符

  自加运算符++和自减运算符—,就是加1减1的意思。

    a++;
    ++a;
    a = a + 1;

  上面的三条语句效果相同。

重点内容:a和a的区别

  像上面的a和a作为一条语句时,没有区别,但如果他们只是表达式中的一部分就会产生差别了。
  ++a:先将变量a加1,然后再取a的值去参加表达式的运算。
  a++:先取a的值,拿取出的a去参加表达式的运算,在取出a的值之后,a进行+1操作。
  a++程序演示代码:

    public static void main(String[] args) {
        int a = 0;
        int b = a++;
        System.out.println("b = " + b);
        System.out.println("a = " + a);
    }

  输出结果:运算符 - 图6
  可以看到,b = a++;是a先将值赋给b,再进行自加运算,所以b的值是0,而a的值是1。
  ++a程序演示代码:

    public static void main(String[] args) {
        int a = 0;
        int b = a++;
        System.out.println("b = " + b);
        System.out.println("a = " + a);
    }

  输出结果:运算符 - 图7
  可以看到,b = a++;是a先进行自加,再把自加之后的值赋给b,所以a和b的值都是1。

练习:

  练习1:下面程序输出结果是什么?

int p, k = 5;
p = ++k + ++k + k++;
System.out.println(p + "  " + k);
20 8

练习2:下面的代码中c和d的值分别是什么?

int a = 100, b = 50;
int c = a + --b;
int d = a-- - +--b;
c = 149, d = 52

  上面代码- -b前面的+号其实表示的是正负

int c = a + --b;
int d = a++ + -+b;
c = 149, d = 50

  d的赋值语句中+ - +b前面的加减号全是表示正负

int c = a + --b;
int d = a++ - ++b;;
c = 149, d = 51

赋值运算符

  赋值运算符以“=”表示。
  功能:将右边的操作数所含的值赋值给左边的操作数。
  注:有多个“=”,将从右往左依次赋值。
  赋值运算符和算术运算符结合使用产生的+=,-=,*=,/=,%=

    int a = 3;
    int b = 4;
    a += b;

  其中a += b相当于a = a + b,
  需要注意的是,只是相当于,并不是完全等价,比如下面代码

short s = 1;
s += 1;
s = s + 1;

  s += 1是正确的,s = s + 1会报错,这是数据类型转换的原因,详情见基本数据类型转换
  -、*、/、%和+相同。

比较运算符

  在程序中,对变量、自变量进行比较时使用的运算符,比较运算符的运算结果是boolean型当运算关系式成立,返回true,否则返回false

运算符 作用 操作数
> 左边是否大于右边 整型、浮点型、字符型
< 左边是否小于右边 整型、浮点型、字符型
>= 左边是否大于等于右边 整型、浮点型、字符型
<= 左边是否小于等于右边 整型、浮点型、字符型
== 左边是否等于右边 基本数据类型、引用型
!= 左边是否不等于右边 基本数据类型、引用型

  当==和!=的操作数时引用型的时候,需要注意引用型的比较和基本数据类型是不同的。

逻辑运算符

  逻辑运算符的操作数和运算结果都是boolean型,除了!(逻辑非)是一元运算符,其他两个都是二元运算符。运算方向是从左到右

运算符 说明 操作数
&&、& 逻辑与 boolean
|| 逻辑或 boolean
! 逻辑非 boolean

逻辑与

规则

  z = x && y
  仅在x和y都为true的情况下,z才为true,否则为false。都真才真

重点:短路现象

  短路现象:当左边的表达式已经能决定整个表达式的真假时,不会去运行右边的表达式的现象被称为短路现象。
  短路现象非常重要!!!!!

  &&和&区别
   1. x && y,如果x是false,那么直接结束返回false,不去计算y,&&是短路运算符,&是非短路运算符;而x & y,不论x是否是false,都需要计算y。
   2. &还可以用作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作。我们通常使用0x0f来与一个整数进行&运算,来获取该整数的最低4个bit位。

  程序代码:首先是&&

    public static void main(String[] args) {
        int a = 2,b = 0;
        System.out.println(a < 1 && ++b > 2);
        System.out.println(b);
    }

  输出结果是:运算符 - 图8

  而&的程序

    public static void main(String[] args) {
        int a = 2,b = 0;
        System.out.println(a < 1 & ++b > 2);
        System.out.println(b);
    }

  输出结果:运算符 - 图9
  可以看到&&在左侧已经是false的情况下,并不执行右侧的表达式,而&依旧执行。

逻辑或

  和&&一样||也是一个短路运算符

规则

  z = x || y
  仅在x和y都为false的情况下,z才为false,否则为true。都假才假

逻辑非

  x = !y,y为true,则x为false;y为false,则x为true。反着来

条件运算符

  ?:是唯一一个三元运算符。
  使用格式:条件式 ? 值x : 值y
  运算规则:若条件式为true,则整个表达式取值x,否则取值y。
  实例:

    public static void main(String[] args) {
        int a = 1, b = 2;
        int c = a > b ? a : b;
        System.out.println(c);
    }

  我们先看赋值运算符的右侧 a > b ? a : b 的过程是:a > b吗?false,所以这个表达式是取b的值,然后将这个值赋值给c。
这实际是c取a,b中大的那个值。

位运算符

  位运算符是针对二进制的位方面的运算操作。

运算符 说明 操作数
& 按位与 整型
| 按位或 整型
~ 按位取反 整型
^ 按位异或 整型
<< 左移 整型
>> 右移 整型
>>> 无符号右移 整型

按位与

规则

  1. 如果两个整型数据a,b对应位都是1,结果位才是1,否者为0。
  2. 如果两个a和b的精度不同,那么结果的精度与精度高的操作数相同。
    例如:0110 & 11010,结果是00010。

按位或

规则

  1. 如果两个整型数据a,b对应位都是0,结果位才是0,否者为1。
  2. 如果两个a和b的精度不同,那么结果的精度与精度高的操作数相同。
    例如:0110 | 11010,结果是11110。

按位异或

规则

  1. 如果两个整型数据a,b对应位相同,结果位为0,否者为1。
  2. 如果两个a和b的精度不同,那么结果的精度与精度高的操作数相同。
    例如:0110 ^ 11010,结果是11100。

按位取反

规则
  将操作数的每一位中的1修改为0,0修改为1。
  例如:~0110,结果为1001。

位移操作

  以左移为例,位移运算符左边是待操作的数据,右边是位移的位数,例如:y << 2;表示将y这个数据的二进制向左移动2位。

左移 <<

  左移比较简单,格式:操作数 << 位移的位数
  表示将运算符左边的操作数的二进制数据,按照运算符右边位移的位数向左移动对应位数,右边移空的部分补0。
  例如:0000 0110 << 3,结果是0011 0000。
  左移n位的效果和乘以2相同。

右移 >>

  右移需要注意符号,移动完,最高位补符号,移动前符号位置0,则还补0,移动前符号位是1,则补1,其他位补0。

无符号右移 >>>

  右移之后,空出来的高位全部补0。

运算符优先级

  最高:.、()、[ ]
  最低:=

  1. 一元运算符:++、--、!、~
  2. 算术运算符:+、-、*、/、%
  3. 位移运算:<<、>>、>>>
  4. 比较运算符
  5. 除了位移运算符之外的位运算符:&、|、^
  6. 逻辑与、逻辑或:&&、&、||
  7. 赋值运算符:=