运算符
一、什么是运算符?
计算机的基本用途之一就是处理数学运算,比如:
int a=10;
int b=20;
a+b;
a<b;
上面的代码中,+和<就是运算符。
运算符就是对操作数进行操作时的符号,不同操作符操作的含义不同。
二、算术运算符
1.基本四则运算符:加减乘除模
public class operator {
public static void main(String[] args) {
int a=20;
int b=10;
System.out.println(a+b);//30
System.out.println(a-b);//10
System.out.println(a*b);//200
System.out.println(a/b);//2
System.out.println(a%b);//0
}
}
注意:
- 都是二元运算符,使用时必须有两个操作数
- int/int结果还是int类型,而且会向下取整
int a=3;
int b=2;
System.out.println(a/b);
//数学中结果应该是1.5,在这里输出结果是1,向下取整,小数点后舍弃
//得到1.5,这么写:
double c1=(double)a1/b1;
System.out.println(c1);
- 除法和模运算时,右操作数不能为0
- 不仅可以对整数取模,也可以对double类型取模,但没有意义,一般都是对整型取模
- 左右两边操作数类型不一样时,向类型大的提升
System.out.println(1+0.2);
//+的左侧是int,右侧是double,做加法运算之前,int被提升为double
//输出结果为1.2
2.增量运算符
增量运算符操作完成后,会将操作的结果赋值给左操作数
int a=1;
a+=2;//相当于a=a+2
System.out.println(a);//输出3
a-=1;//相当于a=a-1
System.out.println(a);//输出2
a*=3;相当于a=a*3
System.out.println(a);//输出6
a/=3;//相当于a=a/3
System.out.println(a);//输出2
a%=3;相当于a=a%3
System.out.println(a);//输出2
3.自增/自减运算符
int a=1;
a++;//后置++,表示给a的值+1
System.out.println(a++);//表达式结束才给变量+1,输出2
System.out.println(a);//输出3
++a;//前置++, 先给a+1,再执行表达式,a的值变为4
System.out.println(++a);//先给a+1,输出5
System.out.println(a);//输出5
注意:
- 如果单独使用,前置++和后置++没有任何区别
- 如果混合使用,前置++先+1,然后使用+1后的值,后置++是使用原来的值,表达式结束后给变量+1
- 只有变量才能使用自增/自减运算符,常量不能使用,因为常量不允许被修改
三、关系运算符
关系运算符主要有六个:== != < > <= >=,计算结果为true或者false。
int a=10;
int b=20;
//在Java中,=表示赋值,==表示相等
System.out.println(a==b);//false
System.out.println(a!=b);//true
System.out.println(a>b);//false
System.out.println(a<b);//true
System.out.println(a>=b);//false
System.out.println(a<=b);//true
注意: 当需要多次判断时不能连着写,比如1<a<11
int a=10;
System.out.println(1<a<11);
//二元运算符 '<' 的操作数类型错误
第一个类型: boolean
第二个类型: int
//1<a为boolean类型,后面的11为int类型
四、逻辑运算符*
逻辑运算符主要有三个:&&、||、!,运算结果都是boolean类型
1.逻辑与 &&
语法规则:表达式1&&表达式2,左右表达式都必须是boolean类型的结果。
表达式1 | 表达式2 | 表达式1&&表达式2 |
---|---|---|
真 | 真 | 真 |
真 | 假 | 假 |
假 | 真 | 假 |
假 | 假 | 真 |
int a=1;
int b=2;
System.out.println(a==1&&b==2);//true,左右都为真
System.out.println(a==1&&b>100);//false,左真右假
System.out.println(a>100&&b==2);//false,左假右真
System.out.println(a>100&&b>100);//false,左右都为假
2.逻辑或||
语法规则:表达式1||表达式2,左右表达式必须是boolean类型的结果。
表达式1 | 表达式2 | 表达式1&&表达式2 |
---|---|---|
真 | 真 | 真 |
真 | 假 | 真 |
假 | 真 | 真 |
假 | 假 | 真 |
int a=1;
int b=2;
System.out.println(a==1&&b==2);//true,左右都为真
System.out.println(a==1&&b>100);//true,左真右假
System.out.println(a>100&&b==2);//true,左假右真
System.out.println(a>100&&b>100);//false,左右都为假
左右表达式中至少有一个为真,则结果为真。
3.逻辑非 !
语法规则:! 表达式
表达式 | !表达式 |
---|---|
真 | 假 |
假 | 真 |
int a=1;
System.out.println(!(a==1));//false
System.out.println(!(a!=1));//true
4.短路求值
&&和||遵守短路求值的规则。
System.out.println(10>20&&10/0==0);//输出false
System.out.println(10<20||10/0==0);//输出true
上面已经说过 / 的右操作数不能为0,但上述代码没有报错,为什么呢?
解释:
- 对于&&,如果左侧表达式值为false,则表达式结果一定是false,无需计算右侧表达式。
- 对于||,如果左侧表达式值为true,则表达式结果一定是true,无需计算右侧表达式。
- &和|这两个运算符,如果表达式结果为boolean类型时,也表示逻辑运算,但是它们不支持短路求值。
System.out.println(10>20&10/0==0);
System.out.println(10<20|10/0==0);
//编译失败
五、位运算符
Java中数据存储的最小单位是字节,而数据操作的最小单位是比特位。字节是最小的存储单位,每个字节由八个二进制的比特位组成,多个字节组合在一起可以表示各种不同的数据。
位运算符主要有四个:& | ~ ^,其中:
一元运算符:~
二元运算符:& | ^
位操作表示:按二进制位运算。
1.按位与 &:
计算规则:如果两个二进制位都是1,则结果为1,否则结果为0.
举例:
0000 1010 -------- 10的二进制
&
0001 0100 -------- 20的二进制
结果为
0000 0000-------- 0的二进制
2.按位或 |:
计算规则:如果两个二进制位都是0,则结果为0,否则结果为1.
0000 1010 -------- 10的二进制
|
0001 0100 -------- 20的二进制
结果为
0001 1110-------- 30的二进制
3.按位取反~:
计算规则:如果该位为0,则变为1;如果该位为1,则变为0.
int a = 0xf;
System.out.printf("%x\n",~a);
注意:
- 0x前缀的数字为十六进制数字,一个十六进制对应4个二进制位.
- 0xf表示十进制的15,也就是二进制的1111.
- printf能够格式化输出内容,%x表示按照十六进制输出.
- \n表示换行符.
4.按位异或^:
计算规则:如果两个数字的二进制位相同,则结果为0,相异则结果为1.
int a=0x1;
int b=0x2;
System.out.printf("%x\n",a^b);//输出3
六、移位运算符
移位运算符有三个:<< >> >>>
特点:
- 都是二元运算符
- 都是按照二进制比特位来运算的
1.左移<<
最左侧位不要了,最右侧位补0.
int a = 0x10;
System.out.printf("%x\n",a<<1);
//输出20;是按十六进制打印的
2.右移>>
最右侧位不要了,最左侧位补符号位(正数补0,负数补1).
int a = 0x10;
System.out.printf("%x\n",a>>1);
//输出8;是按十六进制打印的
3.无符号右移>>>
最右侧位不要了,最左侧位补0.
int a = 0xffffffff;
System.out.printf("%x\n",a>>>1);
//输出7fffffff;是按十六进制打印的
总结:
- 左移1位,相当于原数字*2,左移n位,相当于原数字 * 2 n 2^n 2n .
- 右移1位,相当于原数字/2,右移n位,相当于原数字/ 2 n 2^n 2n .
- 计算机移位效率高于计算机的乘除,当某个代码乘除2的多少次方时,可以用移位运算代替.
- 移动负数位或者位数过大都没有意义。
七、条件运算符
条件运算符只有一个:
表达式1?表达式2:表达式3
当表达式1为true时,输出表达式2的值;
当表达式1为false时,输出表达式3的值;
条件运算符也是Java中唯一的一个三目运算符,是条件判断语句的简化写法。
举例:
//求两个整数的最大值
int a=10;
int b=20;
int max=a>b?a:b;
注意:
- 表达式2和表达式3的结果得是同类型的,除非能发生隐式类型转换
- 表达式不能单独存在,其产生的结果必须要被使用
八、运算符的优先级
运算符之间是有优先级的,具体规则不用记忆。在可能产生歧义的代码中加上括号即可。
一些知识点:
- 整数:在内存中都是以补码方式存在;
- 正数的原码、反码、补码都是相同的;
- 负数的原码、反码、补码不同;
- 原码:数据的二进制格式
反码:对原码取反,注意:符号位不变;
补码:反码+1