2020年7月21日 运算符及练习

/*
运算符:
2、赋值运算符
(1)基本的赋值运算符:=

赋值操作:永远是把=右边的常量值、变量中值、表达式计算的值赋值给=左边的变量,
即=左边只能是一个变量。

运算的顺序:把右边的整个表达式先算完,才会做最后的赋值操作。

(2)扩展的赋值运算符
例如:
+=
-=
*=
/=
%=
...


*/
class Test09_Assign{
    public static void main(String[] args){
        int x = 1;
        int y = 2 ;
        int z = 3;
        //x + y = z;//=左边只能是一个变量
        
        byte b1 = 1;
        byte b2 = 2;
        //b2 = b1 + b2;//右边byte + byte结果是int
        b2 += b1;//等价于  b2 = (byte)(b2 + b1);
        System.out.println("b1 = " + b1);//1
        System.out.println("b2 = " + b2);
        
        System.out.println("---------------------------");
        int i = 1;
        int j = 5;
    
        j *= i++ + j;
        System.out.println("i = " +  i);//2
        System.out.println("j = " +  j);//30
    }
}
class Test09_Modify{
    public static void main(String[] args){
        int i = 1;
        int j = 5;
        //j *= i++ + j; 等加于 j = j * (i++ + j);
        /*
        第一步:先把j的值“5”放起来        
        
        第二步:i++
        (1)先取i的值“1”,放起来
        (2)i自增,i=2
        第二步:求和
        1 + 5 = 6
        第三步:乘
        j * (和) = 5 * 6 = 30
        第四步:赋值,把乘积赋值给j
        */
        j *= i++ + j;
        System.out.println("i = " +  i);//2
        System.out.println("j = " +  j);//30
    }
}
class Test09_Modify2{
    public static void main(String[] args){
        int i = 1;
        int j = 5;
        //j *= i++ + j++; 等加于 j = j * (i++ + j++);
        /*
        第一步:先把j的值“5”放起来        
        
        第二步:i++
        (1)先取i的值“1”,放起来
        (2)i自增,i=2
        第三步:j++
        (1)先取j的值“5”
        (2)在j自增 j = 6
        第四步:求和
        1 + 5 = 6
        第三步:乘
        用“5” * (和) = 5 * 6 = 30
        第四步:赋值,把乘积赋值给j
        */
        j *= i++ + j++;
        System.out.println("i = " +  i);//2
        System.out.println("j = " +  j);//30
    }
}
/*
运算符:
3、比较运算符
大于:>
小于:<
大于等于:>=
小于等于:<=
等于:==        
    注意,谨防与赋值的=混淆
不等于:!=

比较运算符,计算完后的结果只有两个:true,false
说明比较运算符的表达式,可以作为(1)判断的条件(2)逻辑运算符的操作数

比较运算符能够用于基本数据类型,不能用于引用数据类型。
除了==和!=,关于引用数据类型时它俩的意义后面再讲。

一元运算符:操作数只有一个
    例如:a++  其中a就是操作数
        -a   其中a就是操作
二元运算符:需要两个操作数
    例如:求和   a+b  其中a和b就是操作
          比较大小  age>=18  其中的age和18都是操作数
三元运算符:需要三个操作数
    ...
*/
class Test10_Compare{
    public static void main(String[] args){
        /*
        有一个变量age,表示年龄,判断是否成年(满足18岁)
        
        */
        int age = 26;
        
        System.out.println("是否成年:" + (age>=18));
        
        /*
        比较运算符作为条件
        */
        if(age >= 18){
            System.out.println("祝你玩得愉快!");
        }else{
            System.out.println("未成年不得进入!");
        }
        
        /*
        有一个变量,存储的是boolean类型的值
        */
        boolean flag = false;
        if(flag == true){//不会修改flag里面的值
            System.out.println("条件成立");
        }
        //与上面的语句是等价的
        if(flag){
            System.out.println("条件成立");
        }
        
        if(flag = true){//不是比较,而是赋值,结果仍然是布尔值,只要是布尔值就可以作为条件
            System.out.println("条件成立");
        }
        System.out.println("flag = " + flag);
        
        /*
        有一个变量,存储的是其他类型的值
        */
        int num = 1;
        if(num == 1){
            System.out.println("num=1");
        }
        
        //if(num = 1){//错误的,因为num=1是赋值表达式,结果还是int,int值是不能作为条件的
        //    System.out.println("num=1");
        //}
    }
}
/*
运算符:
4、逻辑运算符
逻辑与:&
    类似于:且
    true & true 结果为true
    true & false 结果为false
    false & true 结果为false
    false & false 结果为false
逻辑或:|
    类似于:或
    true | true 结果为true
    true | false 结果为true
    false | true 结果为true
    false | false 结果为false
逻辑非:!
    类似于:取反
    !true 结果为false
    !false 结果为true
逻辑异或:^
    类似于:求不同
    true ^ true 结果为false
    true ^ false 结果为true
    false ^ true 结果为true
    false ^ false 结果为false
短路与:&&
    结果:和&是一样的
    运算规则:如果&&的左边已经是false,右边就不看了
    true & true 结果为true
    true & false 结果为false
    false & ? 结果为false
    false & ? 结果为false
短路或:||
    结果:和|是一样的
    运算规则:如果||左边已经是true,右边就不看了
    true | ? 结果为true
    true | ? 结果为true
    false | true 结果为true
    false | false 结果为false
*/
class Test11_Logic{
    public static void main(String[] args){
        /*
        判断成绩是否在70和80之间
        数学:70<=score<=80
        Java中:
        */
        int score = -78;
        
        /*
        Test11_Logic.java:14: 错误: 二元运算符 '<=' 的操作数类型错误
                if( 70<=score<=80){
                             ^
          第一个类型:  boolean   70<=score的运算结果是true或false
          第二个类型: int
        1 个错误
        */
        //if( 70<=score<=80){
        //    System.out.println("良好");
        //}
        
        if(70<=score & score<=80){
            System.out.println("良好");
        }
        
        /*
        假设成绩合理范围[0,100]
        判断成绩是否小于0 或 大于100,输出成绩有误
        */
        if(score<0 | score>100){
            System.out.println("成绩有误");
        }
        
        /*
        假设成绩合理范围[0,100]
        判断成绩是否在合理范围内
        */
        if(score>=0 & score<=100){
            
        }
        //或下面这么写
        if(!(score<0 | score>100)){
            
        }
        
        System.out.println(true ^ true);
        System.out.println(true ^ false);
        System.out.println(false ^ true);
        System.out.println(false ^ false);
        
        /*
        短路与:&&
        短路或:||
        */
        int i = 1;
        int j;
        /*
        第一步:i++
        (1)先取i的值“1”,放起来
        (2)在i自增,i=2
        第二步:算比较
        放起来的“1” == 1比较,成立
        &&左边是true,不会短路
        第三步:++i
        (1)先自增i=3
        (2)再取i的值“3”,放起来
        第四步:比较
        放起来的“3” == 2比较,结果是false,不成立
        第五步:
        左边的true && 右边的false运算,结果为false,总的if不成立,走else
        */
        //if(i++ == 1 && ++i == 2){
        //    j = 1;
        //}else{
        //    j = 2;
        //}
        
        /*
        第一步:i++
        (1)先取i的值“1”,放起来
        (2)在i自增,i=2
        第二步:算比较
        放起来的“1” == 1比较,成立
        ||左边是true,会发生短路,右边不看了(++i == 2)没运算
        
        第三步:
        true || ?,结果为true,总的if成立
        */
        if(i++ == 1 || ++i == 2){
            j = 1;
        }else{
            j = 2;
        }
        System.out.println("i = " + i);
        System.out.println("j = " + j);
    }
}
class Test12_Exer1{
    public static void main(String[] args){
        int x = 1;
        int y = 1;
        /*
        第一步:x++
        (1)先取x的值“1”
        (2)再x自增x = 2
        第二步:比较
        用“1”与2比较, 1==2,不成立,false
        
        因为&不是短路与,不管左边是怎么样,右边继续
        
        第三步:++y
        (1)自增 y = 2
        (2)取y的值“2”
        第四步:比较
        用“2”与2比较  2 == 2,成立,true
        
        第五步:逻辑
        false & true,结果为false,总的if不成立
        */
        if(x++ == 2 & ++y==2){
            x = 7;
        }
        System.out.println("x = " + x + ",y = " + y);//x = 2,y = 2
    }
}
class Test12_Exer2{
    public static void main(String[] args){
        int x = 1;
        int y = 1;
        /*
        第一步:x++
        (1)先取x的值“1”
        (2)再x自增x = 2
        第二步:比较
        用“1”与2比较, 1==2,不成立,false
        
        因为&&是短路与,左边为false,右边就不看了
        
        
        
        第三步:逻辑
        false & ?,结果为false,总的if不成立
        */
        if(x++ == 2 && ++y==2){
            x = 7;
        }
        System.out.println("x = " + x + ",y = " + y);//x = 2,y = 1
    }
}
class Test12_Exer3{
    public static void main(String[] args){
        int x = 1;
        int y = 1;
        /*
        第一步:x++
        (1)先取x的值“1”
        (2)再x自增x = 2
        第二步:比较
        用“1”与1比较, 1==1,成立,true
        
        中间是|,不是短路或,右边要继续
        第三步:++y
        (1)y先自增,y=2
        (2)再去y的值“2”
        第四步:比较
        用“2”与1比较  2==1,不成立,结果为false
        
        
        第五步:逻辑
        true & false,结果为true,总的if成立,要执行x = 7
        */
        if(x++ == 1 | ++y==1){
            x = 7;
        }
        System.out.println("x = " + x + ",y = " + y);//x = 7,y = 2
    }
}
class Test12_Exer4{
    public static void main(String[] args){
        int x = 1;
        int y = 1;
        /*
        第一步:x++
        (1)先取x的值“1”
        (2)再x自增x = 2
        第二步:比较
        用“1”与1比较, 1==1,成立,true
        
        中间是||,是短路或,左边已经为true,会发生短路现象,右边不看了
                
        
        第五步:逻辑
        true & ?,结果为true,总的if成立,要执行x = 7
        */
        if(x++ == 1 || ++y==1){
            x = 7;
        }
        System.out.println("x = " + x + ",y = " + y);//x = 7,y = 1
    }
}
class Test13_Exer{
    public static void main(String[] args){
        boolean x = true;
        boolean y = false;
        short z = 42;
        /*
        第一步:z++
        (1)先取z的值“42”
        (2)z自增 z=43
        第二步:比较
        用“42”与42比较,条件成立,true
        
        中间是&&,短路与,但是没有满足短路现象。右边继续
        第三步:
        取y的值false
        第四步:
        比较,用"false"与true比较,条件不成立,false
        第五步:
        true && false,结果为false,if条件不成立,z++不执行
        */
        if((z++==42) && (y==true))
            z++;
        
        /*
        ||左边:x=false,这是赋值运算,结果仍然是false
        中间||,是短路或,但是没有满足短路现象,右边继续
        右边:
        ++z:先自增z=44,然后取z的值“44”,然后与45进行比较,结果为false
        左边的false || 右边的false,结果还是false,if不成立,z++不执行
        */
        if((x=false) || (++z==45))
            z++;
        System.out.println("z = " + z);//44
    }
}
class Test13_Exer2{
    public static void main(String[] args){
        boolean x = true;
        boolean y = false;
        short z = 42;
        
        
        /*
        这里y=true是赋值,结果还是true,表示条件成立,并且y的值已经变为true
        */
        if(y=true)
        /*
        第一步:z++
        (1)先取z的值“42”
        (2)z自增 z=43
        第二步:比较
        用“42”与42比较,条件成立,true
        
        中间是&&,短路与,但是没有满足短路现象。右边继续
        第三步:
        取y的值true
        第四步:
        比较,用"true"与true比较,条件成立,true
        第五步:
        true && true,结果为true,if条件成立,z++执行
        z = 44
        */
        if((z++==42) && (y==true))
            z++;
        
        /*
        ||左边:x=false,这是赋值运算,结果仍然是false
        中间||,是短路或,但是没有满足短路现象,右边继续
        右边:
        ++z:先自增z=45,然后取z的值“45”,然后与45进行比较,结果为true
        左边的false || 右边的true,结果还是true,if成立,z++执行,z=46
        */
        if((x=false) || (++z==45))
            z++;
        System.out.println("z = " + z);//46
    }
}
/*
运算符:
5、条件运算符,
因为它是唯一的三元运算符,所以也称为三元运算符

条件表达式 ? 结果表达式1 : 结果表达式2

整个表达式包含三个部分。
运算规则:如果条件表达式成立,就取结果表达式1的值,否则就取结果表达式2的值

*/
class Test14_Condition{
    public static void main(String[] args){
        boolean marry = false;
        System.out.println(marry ? "已婚" : "未婚");
        
        //找出x和y中的最大值
        int x = 4;
        int y = 4;
        int max = x>=y ? x : y;
        /*
        等价于
        if(x>=y){
            max = x;
        }else{
            max = y;
        }
        */
        System.out.println(x + "," + y + "中的最大值是:" + max);
    }
}
/*
运算符:(了解)
6、位运算符
效率很高,但是可读性不好
因为它是基于二进制补码直接运算的。

左移:<<
    运算规则:<<几位,就乘以2的几次方
            二进制补码左移n位,右边补0
右移:>>
    运算规则:>>几位,就除以2的几次方
            二进制补码右移n位,左边补0还是1,看最高位
无符号右移:>>>
    运算规则:二进制补码右移n位,左边补0,对于负数来说,移完后,变为正数
按位与:&
    1 & 1 结果1
    1 & 0 结果0
    0 & 1 结果0
    0 & 0 结果0
按位或:|
    1 | 1 结果1
    1 | 0 结果1
    0 | 1 结果1
    0 | 0 结果0
按位异或:^
    1 ^ 1 结果0
    1 ^ 0 结果1
    0 ^ 1 结果1
    0 ^ 0 结果0
按位取反:~(一元运算符)
    ~1为0
    ~0为1

*/
class Test15_Bit{
    public static void main(String[] args){
        /*
        4的二进制:0000 0100
        4<<3:0 0100000
        */
        System.out.println(4 << 3);//等价于4乘以2的3次方,4*8=32
        
        /*
        32的二进制:0010 0000
        32>>4:0000 0010 
        */
        System.out.println(32 >>4);//等价于32除以2的4次方,32/16 =2
        
        /*
        -32的二进制:
            原码:1010 0000
            反码:1101 1111
            补码:1110 0000
        -32>>4:1111 1110 
            补码:1111 1110 
            反码:1111 1101
            原码:1000 0010
        */
        System.out.println(-32 >>4);
        
        System.out.println(32 >>> 4);//和>>一样,左边补0
        /*
        -32的二进制:
            原码:1000 0000 0000 0000 0000 0000 0010 0000
            反码:1111 1111 1111 1111 1111 1111 1101 1111
            补码:1111 1111 1111 1111 1111 1111 1110 0000
        -32>>>4:0000 1111 1111 1111 1111 1111 1111 1110
            最高位是0,是正数
        */
        System.out.println(-32 >>> 4);
        
        /*
        32:0000 0000 0000 0000 0000 0000 0010 0000
        25:0000 0000 0000 0000 0000 0000 0001 1001
        32 & 25:0000 0000 0000 0000 0000 0000 0000 0000
        */
        System.out.println(32 & 25);
        
        /*
        32:0000 0000 0000 0000 0000 0000 0010 0000
        25:0000 0000 0000 0000 0000 0000 0001 1001
        32 | 25:0000 0000 0000 0000 0000 0000 0011 1001
        */
        System.out.println(32 | 25);
        
        /*
        32:0000 0000 0000 0000 0000 0000 0010 0000
        25:0000 0000 0000 0000 0000 0000 0001 1001
        32 | 25:0000 0000 0000 0000 0000 0000 0011 1001
        */
        System.out.println(32 ^ 25);
        
        /*
        3:0000 0000 0000 0000 0000 0000 0000 0011
        ~3:1111 1111 1111 1111 1111 1111 1111 1100
        补码:1111 1111 1111 1111 1111 1111 1111 1100
        反码:1111 1111 1111 1111 1111 1111 1111 1011
        原码:1000 0000 0000 0000 0000 0000 0000 0100 -4
        */
        System.out.println(~3);
    }
}
/*
运算符优先级:
(1)赋值类运算符是最低的,即赋值最后算
(2)条件运算符
(3)||-> &&-> |-> ^-> &
(4)比较运算符
(5)左移右移的位运算符
(6)算术运算符
    乘、除、模高于加和减
(7)自增,自减,以及按位取反,非
(8).(面向对象用)和()

我们如果要准确的记忆每一种运算符的优先级是困难的。
我们遵循一个原则:
(1)表达式不要写太复杂,可以分为多行
(2)如果非要混合运算,那么先算的用()括起来    


关于&,|,^,看左右两边的操作数是boolean值,还是整数,来决定是逻辑运算符还是位运算符。
*/
class Test16_Priority{
}
/*
交换两个变量的值
*/
class Test17_Swap{
    public static void main(String[] args){
        int x = 1;
        int y = 2;
        
        /*
        通用的方案:适用于任意的数据类型
                借助于第三个通样类型的临时变量
        */
        int temp = x;//x变量中值就赋值给了temp  temp = 1
        x = y;//再把y中的值放到x中,x = 2
        y = temp;//再把temp中的值赋值给y  y=1
        System.out.println("x = " + x);
        System.out.println("y = " + y);
        
        x = 1;
        y = 2;
        /*
        方案二:只适用于int等整数类型
        */
        x = x ^ y;
        y = x ^ y;//(新的x) ^ 原来的y = (原来的x ^ 原来的y) ^ 原来的y = 原来的x  (求不同)
        x = x ^ y;//(新的x) ^ 新的y = (原来的x ^ 原来的y) ^ 原来的x = 原来的y
        System.out.println("x = " + x);
        System.out.println("y = " + y);
        
        x = 1;
        y = 2;
        /*
        方案三:只适用于int等整数类型
            有风险,可能会溢出
        */
        x = x + y;//有风险,可能会溢出
        y = x - y;//(新的x) - 原来的y = (原来的x + 原来的y)- 原来的y  = 原来的x
        x = x - y;//(新的x) - 新的y = (原来的x + 原来的y) - 原来的x = 原来的y
        System.out.println("x = " + x);
        System.out.println("y = " + y);
        
        /*
        以下不推荐
        */
        x = 1;
        y = 2;
        x = x * y;//风险更大
        y = x / y;
        x = x / y;
    }
}
/*
1、定义一个int类型变量,保存年份,判断这个年份是否是闰年
注:判断一年是否是闰年的标准:
       1)可以被4整除,但不可被100整除
       2)可以被400整除
       */
class Test18_Exer{
    public static void main(String[] args){
        int year = 2000;
        
        boolean result = year%4==0 && year%100!=0 || year%400==0;
        System.out.println(year + (result?"是闰年":"不是闰年"));
    }
}
//2、定义三个int类型的变量,x,y,z,随意赋值整数值,求最大值
class Test19_Exer{
    public static void main(String[] args){
        int x = 23;
        int y = 34;
        int z = 49;
        
        //int max = x>=y ? x : y;//运行完这句max中存的是x与y中的最大值
        //max = max >=z ? max : z;//用新的max与z比较
        
        int max = (x>=y ? x : y) >= z ? (x>=y ? x : y) : z;
        System.out.println("max = " + max);
        
        
    }
}

 

posted @ 2020-07-21 23:48  窦云鹏  阅读(203)  评论(0编辑  收藏  举报