5-运算符与优先级
5-1 运算符
1) 算术运算符:+、-、*、/、%、++、--
表达式:由变量、常量运算符组成的式子。
++:如果是前缀,先对此变量加1,在执行其他操作;如果是后缀,先执行其他的操作,再对此变量加1。【--:同理。】
运算符 | 描述 | 示例 | 结果 |
+ | 加法 | 5+5 | 10 |
- | 减法 | 5-3 | 2 |
* | 乘法 | 2*3 | 6 |
/ | 除法 | 10/3 | 3 |
% | 取余(取模) | 10%3 | 1 |
++ | 自增(前、后) |
|
|
-- | 自减(前、后) |
|
|
public class Test3{
public static void main(String[] args){
int a = 1;
int b = 2;
int c = a + b;
System.out.println(c);
a = 10;
b = 3;
System.out.println(a/b);
a = b++; //先赋值后自增1 —> 先把b的值赋给a,然后a再+1
System.out.println("a="+a);
System.out.println("b="+b);
//结果:a = 3,b = 4
a = ++b; //先自增1后赋值 —> 先把b+1,然后再把b的值赋给a
System.out.println("a="+a);
System.out.println("b="+b);
//结果:a = 5,b = 5
int x = 1;
int y = 2;
y = x + y - (++y);
System.out.println("x="+x);
System.out.println("y="+y);
//字符串数据和任何数据使用+ 都是相连接,最终都会变成字符串
//String m = "你"+"好";
System.out.println("你"+"好");
}
}
2) 赋值运算符
运算符 | 描述 | 示例 | 结果 |
= | 赋值 | a=10 | a=10 |
+= | 加等于 | a=1,a+=3 | a=4 |
-= | 减等于 | a=6,a-=3 | a=3 |
*= | 乘等于 | a=1,a*=3 | a=3 |
/= | 除等于 | a=10,a/=3 | a=3 |
%= | 模等于 | a=10,a%=3 | a=1 |
public class Test4{
public static void main(String[] args){
short s = 1;
//s = s + 1; //两次运算,编译失败,因为s会被提升为int类型,运算后的结果还是int类型,无法赋值给short类型,容易丢失精度。
s+=1; //一次运算,编译通过,因为+=运算符在给s赋值时,自动完成了强转操作。
System.out.println(s);
}
}
3) 关系运算符
运算符 | 描述 | 示例 | 结果 |
== | 相等于 | a=10,a==8 | false |
!= | 不等于 | a=1,a!=3 | true |
< | 小于 | a=6,a<3 | false |
> | 大于 | a=10,a>3 | true |
<= | 小于等于 | a=10,a<=3 | false |
>= | 大于等于 | a=10,a>=3 | true |
import java.util.Scanner; //接收键盘输入的工具类
public class Test5{
public static void main(String[] args){
int x = 1;
int y = 2;
System.out.println(x == y);
System.out.println(y >= x);
//创建一个键盘输入的工具
Scanner input = new Scanner(System.in);
System.out.println("请输入一个整数");
int x1 = input.nextInt(); //从键盘接受一个整数
System.out.println(x1);
System.out.println("请输入一个字符");
String s = input.next();
System.out.println(s);
}
}
4) 逻辑运算符
用于对boolean型结果的表达式进行运算,运算结果总是Boolean型。
运算符 | 描述 | 示例 | 结果 |
& | 与 | false & ture | false |
| | 或 | false & ture | true |
^ | 异或 | false ^ ture | true |
! | 非 | !false | true |
&& | 短路与 | false && ture | false |
|| | 短路或 | false || ture | true |
在计算机中,非0即真,0为假;逻辑或,或1则1;逻辑与,全1才1。
public class Test6{
public static void main(String[] args){
boolean x = true;
boolean y = false;
System.out.println(x & y);
//与运算,分别计算表达式两边的结果再做&运算,只有两边都为ture,结果才为true,否则为false
System.out.println(y | x);
//或运算,分别计算表达式两边的结果再说|运算,只要有一个为true,结果就为true,两边都为false则为false
System.out.println(y ^ x);
//异或运算,两边相同为false,两边不同为true
System.out.println(!x);
//非运算
System.out.println(x && y);
//短路与
System.out.println(x || y);
//短路或
}
}
5) 位运算符
对两个操作数中的每一个二进制位都进行运算
位运算符的功能:
1、按位取反 ~
2、按位与 &
3、按位或 |
4、按位异或 ^
二进制数 | 运算 | 结果 |
01001111 | 按位取反 ~ | 10110000 |
11001011 & 01101101 | 按位与 & | 01001001 |
11001011 | 01101101 | 按位或 | | 11101111 |
11001011 ^ 01101101 | 按位异或 ^ | 10100110 |
6) 位移运算符
左移:“a<<b;”将二进制形式的a 逐位左移b位,最低位空出的b位补0;
带符号右移:“a>>b;”将二进制形式的a 逐位右移b位,最高位空出的b位补原来的符号位;
无符号右移:“a>>>b;”将二进制形式的a 逐位右移b位,最高位空出的b位补0
位移运算符正数示例:
100 00000000 00000000 00000000 01100100
100<<3 00000000 00000000 00000011 00100000
100>>3 00000000 00000000 00000000 00001100
100>>>3 00000000 00000000 00000000 00001100
左移小规律:
3<<1——3*2^1 相当于乘以2的倍数
3<<2——3*2^2
3<<3——3*2^3
位移运算符负数示例:
-100 11111111 11111111 11111111 10011100
-100<<3 11111111 11111111 11111100 11100000
-100>>3 11111111 11111111 11111111 11110011
-100>>>3 00011111 11111111 11111111 11110011
右移小规律:
6>>1——6/2^1=3 相当于除以2的倍数
6>>2——6/2^2=1
位运算符的细节 | |
<< | 空位补0,被移除的高位丢弃,空缺位补0 |
>> | 被移位的二进制最高位为0,右移后空缺位补0;最高位是1,空缺位补1; |
>>> | 被移位的二进制最高位为0或1,右移后空缺位都补0; |
& | 二进制位进行&运算,只有1&1时结果是1,否则是0; |
| | 二进制位进行|运算,只有0|0时结果是0,否则是1; |
^ | 任何相同二进制位进行^运算,结果是0,1^1=0,0^0=0; 不相同二进制位进行^运算,结果是1,1^0=1,0^1=1; |
7) 三目运算符
格式:X ? Y : Z
X:boolean类型表达式,先计算X的值,若为true,整个三目运算的结果为表达式Y的值;若为false,整个运算结果为表达式Z的值。
//如:从键盘输入一个成绩,判断该分数是否及格
import java.util.Scanner;
public class Test12{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
System.out.println("请输入第一个成绩:");
int score = input.nextInt();
//String表示一个字符串类型,不是基本数据类型
String result = score>=60?"及格":"不及格";
System.out.println(result);
}
}
//用代码的形式将十进制60转成16进制
public class Test23 {
public static void main(String[] args)
{
//System.out.println(Integer.toBinaryString(60));
int num = 60;
//获取60的最低4位,通过&15实现;
int n1 = 60 & 15;
System.out.println(n1>9?(char)(n1-10+'A'):n1);
/*
0-9 'A' 'B' 'C' 'D' 'E' 'F'
65 66 67 68 69 70
10 11 12 13 14 15
12 - 10 = 2 + 'A' = (char)67
*/
//获取下一组4位,将60右移4位
int temp = 60 >>> 4;
//对temp的值进行最低四位的获取
int n2 = temp & 15;
System.out.println(n2>9?(char)(n2-10+'A'):n2);
//三元运算符(三目运算符)
int x = 1,y;
y = (x>1)?55:100;
System.out.println("y="+y);
}
}
6个练习题:
1、通过键盘输入声明初始化一个圆柱体的高和底面半径,π的值是3.14,求圆柱体的体积,并显示输出圆柱体的体积?
import java.util.Scanner; //接收键盘输入的工具类
public class Test7{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
System.out.println("请输入圆柱体的高");
double h = input.nextDouble(); //从键盘接受一个整数
System.out.println("请输入圆柱体的底面半径");
double r = input.nextDouble(); //从键盘接受一个整数
double S = 3.14*h*r*r;
System.out.println(S);
}
}
2、定义一个5位数,求各个位上的数字之和?
public class Test8{
public static void main(String[] args){
int num = 12654;
int w = num/10000;
int q = num/1000%10;
int b = num/100%10;
int s = num/10%10;
int g = num%10;
int Sum = g+s+b+q+w;
System.out.println(w);
System.out.println(q);
System.out.println(b);
System.out.println(s);
System.out.println(g);
System.out.println(Sum);
}
}
3、根据天数(46)计算周数和剩余的天数,天数是通过键盘输入的
import java.util.Scanner;
public class Test9{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
System.out.println("请输入一个天数:");
int day = input.nextInt();
System.out.println("周数是:"+(day/7));
System.out.println("剩余天数是:"+(day%7));
}
}
4、&和 &&的区别?
&:在逻辑运算时分别计算表达式两边的结果,再做&运算;在位运算时,&表示按位与。
&&:短路与运算,先算左边的表达式,若结果是false,则不用计算右面表达式,结果直接返回false;若结果是true,再计算右面表达式,如右边的表达式为true,结果为true,否则返回false。
& 和 &&的区别?
&:在逻辑运算时分别计算表达式两边的结果,再做&运算;
在位运算时,&表示按位与。
&&:短路与运算,先算左边的表达式,若结果是false,则不用计算右面表达式,结果直接返回false;
若结果是true,再计算右面表达式,如右边的表达式为true,结果为true,否则返回false。
| 和 ||的原理同上。
所以短路与和短路或的计算效率更高,建议使用。
5、以最快的速度计算8*4的结果?
使用位移的方法是最快的
int result = 8 <<2;
左移算法:位移数作为2的次幂与操作数相乘
8*4 ==> 8<<2
10*4 ==> 10<<2 = 40
右移算法:操作数除以位移数的2次幂
10/2 ==> 10>>1 = 5
6、通过键盘输入,初始化两个数,将这两个数交换位置后,输出显示交换后的数据
import java.util.Scanner;
public class Test10{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
System.out.println("请输入第一个数:");
int a = input.nextInt();
System.out.println("请输入第二个数:");
int b = input.nextInt();
//方法一:通过第三个变量来交换
int c = a;
a = b;
b = c;
System.out.println("a="+a+",b="+b);
//方法二:通过表达式来交换两个数【如果a,b的值比较大,容易超出int范围】
a = a + b - (b=a)
System.out.println("a="+a+",b="+b);
//方法三:通过 +、- 来交换两个数
a = a+b;
b = a-b;
a = a-b;
System.out.println("a="+a+",b="+b);
//方法四:通过异或来交换两个数是最快的方式(注意:a不能等于b)
a = a^b;
b = a^b;
a = a^b;
System.out.println("a="+a+",b="+b);
}
}
5-2 优先级
优先级 | 运算符 | 综合性 |
1 | ()、[ ] | 从左到右 |
2 | ! 、+(正)、 - (负)、~、 ++、 -- | 从右到左 |
3 | ^、/、% | 从左到右 |
4 | +(加)、-(减) | 从左到右 |
5 | <<、>>、>>> | 从左到右 |
6 | < 、<=、 >、 >= | 从左到右 |
7 | ==、!= | 从左到右 |
8 | &(按位与) | 从左到右 |
9 | * | 从左到右 |
10 | | | 从左到右 |
11 | && | 从左到右 |
12 | || | 从左到右 |
13 | ? | 从左到右 |
14 | =、+=、-=、*=、/=、%=、&=、|=、^=、~=、<<=、>>=、>>>= | 从右到左 |
public class Test11{
public static void main(String[] args){
int a=1;
int b=2;
a = ++a + (b--) + (a-b) + b;
// 2 + 2 - 0 + 2 = 6
System.out.println(a);
}
}