个人主页:Ice_Sugar_7
所属专栏:快来卷Java啦
所谓运算符,就是对操作数进行操作的符号,不同运算符操作的含义不同。
这块和C语言一样,基本四则运算符有:加减乘除模(+、-、*、/、%)
需要注意的点在于:
①除法运算中,int / int 结果还是int类型,而且会向下取整
,比如2 / 3,本来是0.66666…,但是向下取整后就变为0了。那这样的话我该如何得到小数结果
呢?很简单,只要分子or分母有一个是分数
,就可以转换为浮点数运算,可以直接给分子乘个0.1,即2 * 0.1 / 3。
②做除法和取模时,右操作数不能为0,不然会报错
③%不仅可以对整型取模,也可以对double类型取模,但是没有意义,一般都是对整型取模的
System.out.println(11.5 % 2.0);
// 运行结果
1.5 //也是一个double类型的数
④两侧操作数类型不一致时,向类型大的提升,比如:
System.out.println(1+0.2); // +的左侧是int,右侧是double,在加之前int被提升为double(范围小的提升为范围大的),所以输出1.2
这个指的是+=、-=、*=、%=,和C语言一样。唯一需要注意的点在于:注意:只有变量才能使用该运算符,常量不能使用。
这两个都分为前置和后置,以++为例,前后置区别在于:前置是先++,然后再去使用变量值;而后置++则是先使用当前变量值,使用后再++。比如:
int a = 1;
System.out.println(a++); // 注意:后置++是先使用变量原来值,表示式结束时给变量+1,因此输出1
System.out.println(a); // 输出2
注意:与增量运算符一样,只有变量才能使用自增/自减运算符,常量不能使用,因为常量不允许被修改。
关系运算符主要有六个: ==、!=、<、>、<=、>= ,其计算结果是 true 或者 false。
int a = 10;
int b = 20;
System.out.println(a == b); // false
System.out.println(a != b); // true
System.out.println(a < b); // true
注意:当需要多次判断时,不能连着写,比如:3 < a < 5,Java程序与数学中是有区别的,别把数学的毛病带到这里(doge)。
逻辑运算符主要有三个:&&、||、! ,运算结果都是 boolean类型。
这两位的功能在学习C语言的时候已经接触过了,在此不多赘述,这次讲点不一样的。
&& 和 || 遵守短路求值的规则。
System.out.println(10 > 20 && 10 / 0 == 0); // 打印 false
System.out.println(10 < 20 || 10 / 0 == 0); //打印 true
我们都知道,计算 10 / 0 会导致程序抛出异常。但是上面的代码却能正常运行,说明10 / 0 这条语句压根就没有运行。
对于&&,如果左侧表达式值为 false,则表达式结果一定是 false,无需计算右侧表达式。
对于||,如果左侧表达式值为 true,则表达式结果一定是 true,无需计算右侧表达式。
简而言之就是:只要通过第一条表达式就可以得到true或者false的话,那就不会继续执行第二条表达式。
拓展:& 和 | 的作用也类似 && 和 || ,但与 &&、|| 相比, 它们不支持短路求值,如果把它们放到上面的代码的话,那就会报错。
它的功能很简单,就是“真变假,假变真。” 看个例子就明白了:
int a = 1;
System.out.println(!(a == 1)); // a == 1 为true,取个非就是false
System.out.println(!(a != 1)); // a != 1 为false,取个非就是true
数据存储的最小单位是字节,而数据操作的最小单位是比特位
。字节是最小的存储单位,每个字节是由8个二进制比特位组成的,多个字节组合在一起可以表示各种不同的数据。
位运算符主要有四个:&、|、~、^,除了 ~ 是一元运算符外,其余都是二元运算符。位操作表示按二进制位
运算,所以位操作符是在二进制层面上对操作数进行操作。
①按位与: 如果两个二进制位都是1,则结果为1,否则结果为0。
②按位或: 如果两个二进制位都是0, 则结果为 0, 否则结果为 1。
③按位取反: 如果该位为 0 则转为 1, 如果该位为 1 则转为 0
④按位异或: 如果两个数字的二进制位相同,则结果为 0,相异则结果为 1
(ps.一个数异或自己结果为0)
移位运算符有三个:<<、>>、>>>,都是二元运算符,且都是按照二进制比特位来运算的。
注意:打印移位运算的结果,是按十六进制打印的。
左移 <<: 最左侧位不要了, 最右侧补 0
int a = 0x10;
System.out.printf("%x\n", a << 1);
// 运行结果
20 //这个20是十六进制下的20,转换为十进制就是32
还有一件事儿:向左移位时,丢弃的是符号位,因此正数左移可能会得到负数
右移 >>: 最右侧位不要了, 最左侧补符号位(正数补0, 负数补1)
无符号右移 >>>: 最右侧位不要了, 最左侧补 0
int a = 0xffffffff;
System.out.printf("%x\n", a >>> 1);
// 运行结果
7fffffff
如果你数学还不错的话,那我觉得你在运用这三个的时候,应该也有发现一些数学规律了。
- 左移 1 位, 相当于原数字 * 2。左移 N 位,相当于原数字 * 2 的N次方
- 右移 1 位, 相当于原数字 / 2。右移 N 位,相当于原数字 / 2 的N次方
来点小拓展:
①由于计算机计算移位效率高于计算乘除, 当某个代码正好乘除 2 的N次方的时候可以用移位运算代替。
②移动负数位或者移位位数过大都没有意义。
条件运算符只有一个:表达式1 ? 表达式2 : 表达式3
当表达式1的值为 true 时,整个表达式的值为 表达式2 的值;
当表达式1的值为 false 时,整个表达式的值为 表达式3 的值。
也是 Java 中唯一的一个三目运算符,相当于 if 语句的简化写法,是真的很实用,强烈建议学习。
然后按照惯例,来提一下注意事项:
①表达式2和表达式3的结果要是同类型的,除非能发生类型隐式类型转换。
int a = 10; int b = 20; int c = a > b? 1 : 2.0; //会报错,因为double是大类型,赋给int类型的话数据可能丢失(尽管小数点后是0,但是它也是数据) //就算把 > 改为 < 也仍然会报错,因为这个表达式本身就是错的。
②表达式不能单独存在,其产生的结果必须要被使用。就是你这个表达式一定要把它的结果赋给某个变量,不然就不完整。
来道阿里的笔试题练练手:问下面表达式的结果
boolean flg2 = true == true ? false ? true : false : true;
这道题是一个嵌套的条件运算符,解题的关键是我们得把?
和:
对应起来,那第一个?
对应哪一个:
呢?显然是对应最右边的那个,因为如果是对应第一个:
的话,那第二个?
就对应最右边的:
,那么对于第二个?
,是找不到“表达式2”的(因为表达式2不可能是“true : false”)。找出对应关系后那就简单了。首先 true == true 为真,那就执行?
后面的表达式一一false ? true : false 这个表达式为假,结果为false,所以最终flg2就为false。
在一条表达式中,各个运算符可以混合起来进行运算,但是运算符的优先级不同,比如:* 和 / 的优先级要高于 +和 - ,有些情况下稍不注意,可能就会造成很大的麻烦。
而运算符的优先级遵循一定的规则,你也不必刻意去记(除非你记忆力超群),而且你记了但别人没记的话,那他们也看不懂你的代码。其实你只要在你想优先运算的运算符及操作数加上括号
就ok了。
如果你觉得本文写得还不错,不妨点赞收藏关注三连呗!
如果发现本文有不足或不妥之处,欢迎指出,我将第一时间改正。