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); } }