zoukankan      html  css  js  c++  java
  • 《Java从入门到失业》第三章:基础语法及基本程序结构(3.7):运算符(自增自减、关系运算、逻辑运算、条件运算、位运算、赋值运算、类型转换)

    3.7运算符

    3.7.2自增自减运算符

           在程序中,变量的加1、减1操作是经常会碰到的。Java和其他语言一样,给我们提供了自增、自减运算符来方便的完成这些操作。“++”表示自增,“--”表示自减。我们看一个例子:

    int a = 3;  
    a++;  
    System.out.println(a);// 结果是4  
    int b = 8;  
    b--;  
    System.out.println(b);// 结果是7  

    自增自减运算符会改变变量的值,因此它们的操作数不能是数值。例如5++就是一条非法的语句。另外这2个运算符还有另外一种形式,就是放在操作数的前面,我们看一个例子:

    int a = 3;  
    ++a;  
    System.out.println(a);// 结果是4  
    int b = 8;  
    --b;  
    System.out.println(b);// 结果是7 

    另外,我们还可以把变量和自增自减运算符当做一个整体,参与到赋值语句或者是运算表达式中。例如:

    int a1 = 3;  
    int b = a1++;  
    int a2 = 3;  
    int c = ++a2;  
    int a3 = 3;  
    int d = a3++ * 5;  
    int a4 = 3;  
    int e = ++a4 * 5;  
    System.out.println(b);// 结果是3  
    System.out.println(c);// 结果是4  
    System.out.println(d);// 结果是15  
    System.out.println(e);// 结果是20  

    我们可以看到,无论是赋值语句,还是运算表达式,当++在操作数后面的时候,都是先赋值或先参与运算,然后再自己增加1。当++在操作数前面的时候,都是先自己增加1,再赋值或参与运算。对于自减也是一样。可以总结一个规律:运算符在前面时先起作用,运算符在后面时后起作用。

      这里有一个小笑话,我们都知道C++语言,这门语言把++运算符用到语言命名上了,本意是C语言的扩展。但是根据运算法则,运算符在后面后起作用,因此反对C++的程序员说我们使用的它的时候还没起作用呢,应该命名为++C才对。

    3.7.3关系运算符

      前面的运算符对应数学中的加减乘除取余等运算,关系运算符对应的是比较2个数的关系,关系有等于、不等于、大于、大于等于、小于和小于等于。列表如下:

    运算符

    表达式

    结果(假设a=15,b=10)

    ==

    a==b

    false

    !=

    a!=b

    true

    a>b

    true

    >=

    a>=b

    true

    a<b

    false

    <=

    a<=b

    false

    使用和结果都很简单,没什么可讲的。

    3.7.4逻辑运算符

           逻辑运算包括3个:逻辑与、逻辑或、逻辑非,对应的运算符和说明如下:

    运算符

    表达式

    说明

    &&

    expression1 && expression2

    逻辑与。当且仅当两个操作数都为真,条件才为真

    ||

    expression1 || expression2

    逻辑或。如果任何一个为真,条件为真。

    !

    !expression1

    逻辑非。用来反转操作数的逻辑状态。

    例如:

    boolean a = true;  
    boolean b = false;  
    boolean c = a && b;// 结果是false  
    boolean d = a || b;// 结果是true  
    boolean e = !a;// 结果是false

    需要注意的是,逻辑与和逻辑或都是采用“短路”的方式进行运算的。就是某一个表示的结果已经能够确定整个运算表达式的结果的时候,剩下的表达式就不用再进行计算了。

    例如:

    int a = 5;  
    boolean b = (a < 4) && (a++ < 10);// a<4结果是false,整个表达式结果就是false,因此a++不会运算,a的值依然是5  
      
    int c = 5;  
    boolean d = (c < 6) || (c++ < 10);// c<6结果是true,整个表达式结果就是true,因此a++不会运算,c的值依然是5

    3.7.5条件运算符

      条件运算符也被称为三元运算符。该运算符有3个操作数,并且需要判断布尔表达式的值。该运算符的主要是决定哪个值应该赋值给变量,表达式为:

    condition ? expression1 : expression2

    当条件condition为真时,计算expression1并返回,否则计算expression2并返回。

    例如:

    int a = 5;  
    int b = 10;  
    int c = 20;  
    int d = a < b ? c + a : c + b;// a<b结果是true,因此d=c+a=25

    3.7.6位运算符

           在Java中,处理整型数值时,可以直接对数值的二进制的各个位进行操作,我们先列一个表,然后再进行例子演示:

    操作符

    说明

    &

    按位与操作符。如果相对应位都是1,则结果为1,否则为0

    |

    按位或操作符。如果相对应位都是0,则结果为0,否则为1

    ^

    按位异或操作符。如果相对应位值相同,则结果为0,否则为1

    ~

    按位取反操作符。翻转操作数的每一位,即0变成1,1变成0

    << 

    按位左移运算符。左操作数按位左移右操作数指定的位数

    >> 

    按位右移运算符。左操作数按位右移右操作数指定的位数

    >>> 

    按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充。

    我们看一个例子:

    int a = 55; // 二进制为 0011 0111  
    int b = 18; // 二进制为 0001 0010  
    int c = a & b;// 结果二进制为 0001 0010,18  
    int d = a | b;// 结果二进制为 0011 0111,55  
    int e = a ^ b;// 结果二进制为0010 0101,37  
    int f = ~a;// 结果二进制为 1100 1000,-56  
    int g = a << 2;// 结果二进制为 1101 1100,220  
    int h = a >> 2;// 结果二进制为 0000 1101,13  
    int i = a >>> 2;// 结果二进制为 0000 1101,13 

    对于按位与&运算,有个小技巧,就是可以快速判断一个整数m的二进制从右往左数第n位是否为1,判断方法为看m&2n-1的值,值为0,则第n位为0,值为2n-1,则第n为为1。

    对于<<运算,要注意几点:

    1. 对byte、short、char型进行左移运算,移位之前,它们会自动转换为int
    2. 右侧的参数,需要进行模32运算,其实就是保证右侧的参数小于32(当左侧是long,则模64,保证右侧的参数小于64),因为左移超过32没有意义。
    3. 因为右侧参数不可能超过32(64),所以其实符号位是不变的。
    4. 左移n位,其实相当于乘以2n(由十进制转二进制公式可以得出)

    例如:

    20的二进制补码:0001 0100,左移两位后:0101 0000,结果是80  

    -20的二进制补码:1110 1100,左移两位后:1011 0000,结果是-80

    对于>>运算,需要注意几点:

    1. 右移是带符号移动的,即如果是正数,高位补0,如果负数,高位补1
    2. 右移n位,相当于除以2n取整

    例如:

    20的二进制补码:0000 0000 0000 0000 0000 0000 0001 0100

    右移两位后:0000 0000 0000 0000 0000 0000 0000 0101,结果是5

    -20的二进制补码:1111 1111 1111 1111 1111 1111 1110 1100

    右移两位后:1111 1111 1111 1111 1111 1111 1111 1011,结果是-5

    对于>>>运算,需要注意几点:

    1. 右移是不带符号的,即不管正负,高位都补0

    例如:

    20的二进制补码:0000 0000 0000 0000 0000 0000 0001 0100

    右移两位后:0000 0000 0000 0000 0000 0000 0000 0101,结果是5

    -20的二进制补码:1111 1111 1111 1111 1111 1111 1110 1100

    右移两位后:0011 1111 1111 1111 1111 1111 1111 1011,结果是1073741819

     3.7.7赋值运算符

           Java还支持把一些二元运算符和赋值符号联合起来使用,我们把它们称为赋值运算符,归结如下:

    操作符

    说明

    举例

    +=

    左操作数加右操作数,结果赋值给左操作数

    C += A即C = C + A

    -=

    左操作数减右操作数,结果赋值给左操作数

    C -= A即C = C - A

    *=

    左操作数乘右操作数,结果赋值给左操作数

    C *= A即 C = C * A

    /=

    左操作数除以右操作数,结果赋值给左操作数

    C /= A即C = C / A

    %=

    左操作数对右操作数取模,结果赋值给左操作数

    C %= 2即C = C % 2

    <<=

    左操作数左移右操作数,结果赋值运算符

    C <<= 2即C = C << 2

    >>=

    左操作数右移右操作数,结果赋值运算符

    C >>= 2即C = C >> 2

    >>>=

    左操作数右移右操作数,结果赋值运算符

    C >>>= 2即C = C >>> 2

    &=

    左操作数和右操作数按位与,结果赋值给左操作数

    C &= 2即C = C & 2

    ^=

    左操作数和右操作数按位异或,结果赋值给左操作数

    C ^= 2即C = C ^ 2

    |=

    左操作数和右操作数按位或,结果赋值给左操作数

    C |= 2即C = C | 2

    3.7.8运算优先级

           Java可以在一个表达式中进行多个运算,这就涉及到运算符优先级问题了。下表按优先级从高到底给出运算符的排序(排在一行的优先级相同):

    操作符

    结合性

    [] 、()、 .(点操作符)

    从左向右

    ++、--、 +(一元运算)、-(一元运算)、!、~

    从右向左

    *、/、%

    从左向右

    +、-

    从左向右

    <<、>>、.>>>

    从左向右

    <、<=、>、>=

    从左向右

    ==、!=

    从左向右

    &

    从左向右

    ^

    从左向右

    |

    从左向右

    &&

    从左向右

    ||

    从左向右

    ?:

    从右向左

    =、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=、>>>=

    从右向左

    是不是看着头都大了?笔者也头大,笔者强烈不推荐在一个表达式中使用多个运算符,可读性太差了。

    3.7.9数值类型转换

           在程序的运行过程中,经常会碰到一种数值转换为另一种数值类型。有时候是程序自动转换的,有时候是我们用代码显性转换的。下图列出了数值类型转换的过程:

     

    需要注意的是,对于int转float、long转float,long转double,是可能会丢失精度的。例如:

    int n = 123456789;  
    float f = n;// n包含的位数比float多,结果f为1.23456792E8

    3.7.9.1自动类型转换

           自动类型转换经常发生在2个不同类型操作数进行二元操作时。例如:

    int n = 123;  
    float f = 456.3f;  
    float ff = n + f;// 自动将n转换为float,然后相加,结果是579.3  

    对于这种自动转换,遵循如下规则:

    • 如果两个操作数中有一个double,则另一个会转换为double。
    • 否则如果有一个操作数是float,另一个会转换为float。
    • 否则如果有一个操作数是long,另一个会转换为long。
    • 否则两个操作数都被转换为int。

    3.7.9.2强制类型转换

           上面我们知道了自动类型转换,有时候我们想把double转换为int,可以吗?Java中是允许这种数值转换的,方法就是用强制类型转换,但是会丢失精度。强制类型转换的格式为:

    (type)value

    type是最终想要的类型,value是被强制转换的原数值,例如:

    float f = 456.3f;  
    int nf = (int) f;// 截断小数部分,结果是456

    需要注意的是,如果将一个数值从一种类型转换为另一种类型,但是又超出目标类型的范围,结果就会无法预料。例如把300转换为byte类型:

    byte b = (byte) 300;// 结果是44  
  • 相关阅读:
    PPT_标题
    产品需求撰写-架构图
    测试
    SparkLauncher 1.6 版本bug
    Github fork同步
    Maven 配置远程仓库
    Sqoop2中传入配置文件中url之【坑】
    Spark性能优化-coalesce(n)
    面试算法题目
    Git 基本概念及常用命令
  • 原文地址:https://www.cnblogs.com/javadss/p/13584419.html
Copyright © 2011-2022 走看看