运算符
1.算术运算符
概述:
- 运算:对常量和变量进行操作的过程称为运算
- 运算符: 对常量和变量进行操作的符号称为运算符
- 操作数: 参与运算的数据
- 表达式:用运算符把常量或者变量连接起来符号并且符合java语法的式子就可以称为表达式。
- 不同运算符连接的式子体现的是不同类型的表达式。
- 算术运算符:
+,-,*,/,%,++,–
注意:想要输出小数的话 System.out.println((5乘1.0)/2); // 2.5如果不乘以1.0的话输出结果为:2。
******举例 :
int a = 4;
int b = (a++)+(++a)+(a*10);
4 6 60
a=5 a=6 a=6
System.out.println(a);//6
System.out.println(b);//70
}
a=6,b=70;***
2.赋值运算符
(1)赋值运算符: = , +=, -=, *=, /=, %=
- 其中我们一直在使用的也是最常用的:=。
举例:a+=20
这里实际上可以看作为a的值加上了一个20再赋值给a,但是不能完全等于 a = a + 20;其他以此类推。
(2)例题: short s=1, s = s+1; short s=1, s += 1; 上面两个代码有没有问题, 如果有,那里有问题?
答:short s=1,s=s+1会报错
因为short型的数据类型在参与数据运算时,首先会提升数据类型,所以s=s+1,s会提升数据类型为int型在做加法运算。结果是int型拿s为short型去接收数据一定会报错,要想赋值成功就要进行强制类型转换。
即:s=(short)(s+1);
而第二个没有问题,short s=1,s+=1,本身就带强制类型转换,===>s=(强制类型转换)(s+1)。
总结:所以说s=s+1与s+=1不是完全等同。后者本身就包含强制类型转换
3.关系运算符
(1)关系运算符有: ==,!=,>,<,>=,<=
(2)注意事项:
- 关系运算符的表达式的结果是一个boolean类型,要么是true,要么是false
- ==不能少写,一个=是赋值运算符,==才是关系运算符
- 赋值的时候要注意类型问题,关系运算符表达式的结果是boolean类型,所以接收的时候只能是boolean类型的变量接收。
4.逻辑运算符
(1)逻辑运算符有: &(与), |(或), ^(异或),!(非), &&(短路与), ||(短路或)。
逻辑运算符的两边放的是boolean类型的值,计算的结果也是一个boolean类型的值
(2)运算规则:
两边都要算的:
- &: 参与运算的时候,两边只要有false,则false,两边都做运算
- |: 参与运算的时候,两边只要有true,则true,两边都做运算
- ^: 参与运算的时候,两边结果相同为false,不同为true,两边都做运算
- !: 将true变成false,false变成true
-举一个例子:
int a=3,int b=4;
System.out.println((a++ == 3) | (b++ == 4)); //左边true,右边也是true,结果是true,两边都做运算//
System.out.println((a++ == 4) | (b++ == 4)); //左边是false,右边是true,结果是true,两边都做运算//
System.out.println((a++ == 3) | (b++ == 5)); //左边是true,右边是false,结果是true,两边都做运算//
System.out.println((a++ == 4) | (b++ == 5)); //左边是false,右边是false,结果是false,两边都做运算//
不一定两边都要算:
-
&&: 短路与,结果和单个与结果一样,有false则false,但是执行的东西不一样,当&&左边的表达式结果为false的时候,结果是false,右边不执行
-
||: 短路或,结果和单个或结果一样,有true则true,但是执行的东西不一样, 当||左边是true的时候,右边不执行,结果是true.
-
举个例子:
int a=3;int b=4; System.out.println((a++ == 4) && (b++ == 4));
//左边是false,右边是true,结果是false,左边做运算,右边不做运算。//
System.out.println("a:" + a + ",b:" + b);
输出结果为:a:4,b:4; -
第二个例子
System.out.println((a++ == 3) || (b++ == 5));//左边是true,右边是false,结果是false,左边进行运算,右边不进行运算。//
System.out.println("a:" + a + ",b:" + b); //a:4,b:4
结果为a:4,b:4
(3)“&”和“&&”的区别:
单&时,左边无论真假,右边都进行运算;
&&时,如果左边为真,右边参与运算,如果左边为假,那么右边不参与运算。
“|”和“||”的区别同理,双或时,左边为真,右边不参与运算。
5.位运算符
(1)位运算符有: <<(左移),>>(右移),>>>(无符号右移),&(与),|(或),^(异或,~(非)。
(2)运算规则:,&(与),|(或),^(异或,~(非)。
举例:如下代码:
public class OptWeiDemo1 {
public static void main(String[] args) {
byte a = 3;
byte b = 4;
System.out.println(a&b);
System.out.println(a|b);
System.out.println(a^b);
System.out.println(~a); //-4
}
}
过程: 由于数据在计算机中参与运算的都是补码,而想要知道补码,就得知道反码,原码,就得求出二进制
3的二进制:00000011
4的二进制:00000100
又由于3和4都是正数,如果是负数的话先去求补码再去运算。
3的补码:00000011
4的补码:00000100
-
System.out.println(a&b); 结果为0;
-& 运算:有0则0
00000011
&
00000100
---------------
00000000结果是 : 0
-
System.out.println(a|b);
| 运算:有1则1
00000011
|
00000100
--------------
00000111结果是:7
-
System.out.println(a^b);
^ 运算:相同则0,不同则1
00000011
^
00000100
--------------
00000111结果是:7
-
System.out.println(~a);
~ 运算:1变成0,0变成1
00000011
~
-------------
补码: 11111100
反码: 11111011
原码: 10000100结果是:-4
(3)运算规则:<<(左移),>>(右移),>>>(无符号右移)
-
位运算符:
<<: 左移,二进制左移,右边用0补齐,多出来的丢弃
>>: 右移,最左边最高位是0用0补齐,最高位是1就用1补齐,多出来的丢弃。
>>>: 无符号右移,无论左边最高是0还是1,都用0补齐,多出来的丢弃。 -
举例:如下代码:
public class OptWeiDemo2 {
public static void main(String[] args) {
System.out.println(3<<2); //12 = 3*4 = 3*2^2
System.out.println(24>>2); //6 = 24/(2*2)
System.out.println(-24>>2);// -6
System.out.println(-24>>>2);//1073741818
System.out.println(3<<3); // 3*2^3
//请用最有效率的方式写出计算2乘以8的结果
// System.out.println(2*8);
System.out.println(2<<3);
}
}
运算过程:
-
System.out.println(3<<2); //结果为:12 = 3乘4 = 3乘2^2
过程:<<: 左移,二进制左移2位,右边用0补齐。
3为int型有4个字节一共有32位。
3的二进制:00000000 00000000 00000000 00000011
由于3是正数,所以原码,反码,补码都一样
3的补码:00000000 00000000 00000000 00000011
左移:
00000000 00000000 00000000 00000011
(00)00000000 00000000 00000000 00001100 (补码)
由于最高位是0,既是补码也是原码,所以结果是: 12 -
System.out.println(24>>2); 结果为:6 = 24/(2*2)
右移,最左边最高位是0用0补齐,最高位是1就用1补齐,多出来的丢弃。
24的二进制:00000000 00000000 00000000 00011000
由于24是正数,所以原码,反码,补码都一样
24的补码:00000000 00000000 00000000 00011000
右移:
00000000 00000000 00000000 00011000
0000000000 00000000 00000000 000110(00) (补码)
由于最高位是0,既是补码也是原码,所以结果是:6 -
System.out.println(-24>>2);结果: -6。由于是负数所以要先求补码进行运算,运算之后再去求其原码
过程: -24的二进制:10000000 00000000 00000000 00011000
已知原码求补码:
原码:10000000 00000000 00000000 00011000
反码:11111111 11111111 11111111 11100111
补码:11111111 11111111 11111111 11101000
右移:由于最高位是一,则空位用一来补。
11111111 11111111 11111111 11101000
1111111111 11111111 11111111 111010(00) (补码)
已知补码求原码:
补码:11111111 11111111 11111111 11111010
反码:11111111 11111111 11111111 11111001
原码:10000000 00000000 00000000 00000110
最终结果是:-6 -
System.out.println(-24>>>2);//结果为:1073741818
无符号右移,无论左边最高是0还是1,都用0补齐,多出来的丢弃。
-24的二进制:10000000 00000000 00000000 00011000
已知原码求补码:
原码:10000000 00000000 00000000 00011000
反码:11111111 11111111 11111111 11100111
补码:11111111 11111111 11111111 11101000
无符号右移2位:由于无符号右移所以用0来补空位
11111111 11111111 11111111 11101000
***00***11111111 11111111 11111111 111010(00) (补码)
由于最高位是0,所以它的原码,反码,补码都是一样的。
最终结果位:0011111111 11111111 11111111 111010 = 1073741818 -
也可用一个简便方法:左移a>>b的话:结果为:a乘2^b
右移a<<b的话:结果为:a/2^b
6.三目运算符
(1).三目运算符:又称之为三元运算符
格式:(关系表达式)?表达式1:表达式2;
果关系表达式的结果为true,运算后的结果是表达式1;
如果关系表达式的结果为false,运算后的结果是表达式2;
(2).注意事项
注意事项:
- 三目运算符表达式的结果数据类型由三目运算符表达式1和表达式2中最大的数据类型决定的。
- 关系表达式一定只能是boolean类型
- 举例:面试题:int a = 20;double b = 30.0;(a>b)?a:b
int a1 = 20;
double b1 = 30.0;
double c1 = (a1>b1)?a1:b1;
System.out.println(c1);
结果为:30.0