java - 基础 - 运算符
运算符分类:
按操作数数目
单目 a++
双目 a+b
三目 (a>b) ? x : y
if a>b 如果为true 执行x,否则执行y
按运算符分类
算术运算
加+ 减- 乘* 除/ 取余% 自增++ 自减--
int x = 1; int y = x++;
结果x = 2; y = 1;
计算时先算术运算后赋值运算,x++先备份后计算,把自身的值存入临时空间,然后自身+1,之后临时空间的值会存入y。
int x = 1; int y = ++x;
结果x = 2; y = 2;
计算时先算术运算后赋值运算,++x先计算后备份,把自身的值+1,然后存入临时空间,之后临时空间的值会存入y。
因此:
int x = 1; x = x++;
结果 x = 1;
x++先备份后计算,把自身的值存入临时空间,然后自身+1 (x=2),之后临时空间的值会存入x(x=1)。
int m = 1; int n = 2; int sum = m++ + ++n - n-- - --m + n-- - --m;
sum = 1 + 2 - 3 - 1 + 2 - 0 = 2;
m = 2, n = 2, sum = 1;
m 、= 2, n = 3, sum = 1 + 3 = 4;
m = 2, n = 2, sum = 4 - 3 = 1;
m = 1, n = 2, sum = 1 - 1 = 0;
m = 1, n = 1, sum = 0 + 2 = 2;
m = 0, n = 1, sum = 2 - 0 = 2;
赋值运算
等号=, 加等于+=, 减等于-=, 乘等于*=, 除等于/=, 模等于%=
int x += 10;
相当于 x = x + 10;但是这个是复制运算,没有算术运算。所以
byte x = 1; x += 1; x = x + 1;
x += 1 不会报错,赋值运算自动转化了;
x= x +1 会报错,因为x是byte,1是int,计算会有问题。
关系(比较)运算
大于>,大于等于>=, 小于<, 小于等于<=, 不等于!=, 等于==, 包含于instanceof
结果为true 或者 false;
3 > 2 true
3 < 2 false
逻辑运算
逻辑与&,逻辑或|,逻辑异或^, 逻辑非!,短路与&&,短路或||;
连接 boolean 结果;
&:前后都为true,结果为true
|:前后至少有一个为true,结果为true
^:前后一个为true,一个为false,结果为true
!:true 和 false 转换。结果取反
&&:前后都为true,结果为true, 如果前面的为false,则直接输出false,不再计算后面的。 在前面为true时可以提高效率
||:前后至少有一个为true,结果为true, 如果前面的为true,则直接输出true,不再计算后面的。 在后面为true时可以提高效率
位运算(bit)
& 按位与, |按位或, ^按位异或,~按位取反
<<按位左位移, >>按位右位移, >>>按位右位移(无符号)
用于计算二进制。
10进制转换为2进制
除2取余数,倒序排列取有效位
60
30 0
15 0
7 1
3 1
1 1
0 1
倒叙可以得到 111100
则60 --> 111100;
3&5
把3和5变为2进制,然后对每位进行与运算
00000000 00000000 00000000 00000011
00000000 00000000 00000000 00000101
--------------------------------------------------------与运算
00000000 00000000 00000000 00000001
再转化为10进制,
3&5 = 1
同理可得
3|5 = 111 = 7
3^5 = 110 = 6
~ 转化为2进制补码然后取反
~6 = -7; 补码取反 00000000 00000000 00000000 00000110 --> 11111111 11111111 11111111 11111001 符号位为1说明为负号,则减1取反加负号 00000000 00000000 00000000 00000111 = 7 所以 ~6 = -7;
~-6 = 5;补码取反 11111111 11111111 11111111 11111010 --> 00000000 00000000 00000000 00000101 = 5;
取反是一种计算,把源码全部取反即可。反码是一种编码,两者不同。
源码,反码,补码:
正数反码,补码和源码一致,负数反码为保持符号位不变的情况下其他位取反,补码为反码+1;补码转化为源码需要-1,然后取反,或者取反然后+1
计算机中数字以补码形式存储。
6 -6
源码 00000000 00000000 00000000 00000110 10000000 00000000 00000000 00000110
反码 00000000 00000000 00000000 00000110 11111111 11111111 11111111 11111001
补码 00000000 00000000 00000000 00000110 11111111 11111111 11111111 11111010
6 << x = 00000000 00000000 00000000 00000110 值的补码向左移动x位, 相当于乘以2的x次幂
6 << 2 = 00000000 00000000 00000000 00011000 = 16 + 8 = 24
同理
6 >> 1 = 00000000 00000000 00000000 00000011 = 3; 值的补码向右移动x位, 相当于除以2的x次幂,符号位与源码一致,正数为0,负数为1
6 >> 2 = 1;
-6 >> 1
-6 补码: 11111111 11111111 11111111 11111010
右移后: 11111111 11111111 11111111 11111101
变为源码:10000000 00000000 00000000 00000011 = -3
-6 >> 1 = -3
>>>为无符号右移,移动后符号位为0
-6 >>> 1
-6 补码: 11111111 11111111 11111111 11111010
右移后: 01111111 11111111 11111111 11111101
变为源码(变成正数了所以源码和补码一样):01111111 11111111 11111111 11111101
8进制用0开头
16进制用0X开头。
优先级
大部分时候:括号 > ! , 算术运算> 位运算 > 关系运算 > 逻辑运算 > 赋值运算