1.1. 运算符(一天课时)
Java语言中定义了若干运算符号,完成某种特殊的运算
按照参与运算的数据的数量分为三种类型
一元/单目运算符
二元/双目运算符
三元/多(三)目运算符
按照运算符的功能分为六种
算术运算符 关系运算符 逻辑运算符
位运算符 移位运算符 条件运算符
1.1.1. 算数运算符
数据类型转换的规则同样适用了算数运算符
加法运算符 +
int a =1;
a=a+1;
关注内存中的变化
int a =1;
a=a+1;
a=a+1;
a=a+1;
S.o.p(a);
等号右边的a内存中都不是同一个a,导致a改变的是“=”号,而不是+法。但是a+1和a+1000对应的都是内存中同一块区域(暂且取名叫temp)
减法运算符 -
规则同加法
乘法运算符 *
PC内,只有加法,乘法→加法再计算。
S.o.p(3*4.0);//结果12.0 低转高
除法运算符 /
有点特殊,整数在使用除号操作时,得到的结果仍为整数(小数部分忽略);浮点数做除法,保留小数。
int a =10;
int b =3;
S.o.p(a/b);//结果3,int
double d=10.0;
int b=3;
S.o.p(d/b);//结果3.3333335,不用去考虑结尾为什么是5,只要记住,除法就是除法。低转高
模运算符 %
取余运算,模数(%右边的数)的符号忽略不计,结果的正负取决于被模数(%左边的数)。
例:
-10%4 结果 -2
10%-4 结果 2
10.0%2→0.0 低转高
10&2.0→0.0 低转高
10%2.1→1.6 取余数,结果是1.5999999999999996约等于1.6。不必深究为什么是1.5999999999999996。
发现:10%0,编译能够通过,但是运行报错——ArithmeticException:/by zero
Ø 加号
两个字符相加得到的是码表值,两个字符串相加是将字符串连接在一起。
例:
char c = ‘a’;
S.o.p(c);// a
S.o.p(c+0);// 97
S.o.p(c+‘b’);//195 参与算数运算时,取其unicode码值(有点不足int自动类型提升的意味)
S.o.p(c+‘b’+“c”);//195c 注意这个例子!
S.o.p(c+“b”+‘c’);//abc 注意这个例子!
面试题一:
S.o.p(1+2+3+”a”+3+2+1)
打印:6a321
准则:碰到字符串,后面的全是字符串
面试题二:
S.o.p(2+4+’中’+4+2);
打印:面试官你在开玩笑吧,我怎么会知道’中的’Unicode码值
改成S.o.p(2+4+’a’+4+2)或者S.o.p(2+4+”中”+4+2)还能搞。
面试题三:
S.o.p(‘a’+”b”+’c’);
结果:abc
只有当字符(char)参与算数运算时,运算结果才是数值。
Ø 自增自减运算符
只能是变量自增、自减
例:
2++; 错
int a=1;a++; 对
a++:先运算后自加
++a:先自加后运算
a++与++a是一个表达式
例:
int a =1;
a++;
a++;
a++:
S.o.p(a);//结果4
int a =1;
a++;
System.out.println(a);//2
int b =1;
System.out.println(b++);//1
int c=1;
System.out.println(++c);//2
int a =1;
int b =2;
System.out.println(1+a++);//2
System.out.println(a++ + b++)//3
面试题:
求a++ + a++ a++ 面试题
System.out.println(a++ + a++ a++);
//连加的运算过程(1+2+3)
自增自减使用错误的情况:
+ +符号拆开;
int a =1;++a++;编译报错,需要变量,找到值。++a的值是1,JVM找到1++,++需要变量,所以报错。
发现:
int a =1;
//当你整体打印时
System.out.println(a++ + a++ + a++);//6
System.out.println(a++ + ++a + a++);//16
System.out.println(a++ + ++a + ++a);//26
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
赋值运算符
1.1.2. 关系运算符(比较运算符)
结果一定是一个布尔值,关系运算符只能比较数字。
大于 >
大于等于 >=
小于 <
小于等于 <=
等于(特殊) == 3==3 true==true
不等于(特殊) != false!=false 2.7!=3
3<=3.0 →true。比较的是数学值,先做类型转换。int→double再比较
3f<=3d →true
3L>=3d →true
3>2>1 //编译报错
关系运算符两边可以是表达式。例:1+2>3+4 →false 说明+的优先级大于>
·JAVA中=号用于做赋值运算,而且要求等号左边必须是一个变量,右边必须是一个值。
例: int a,b=2;
a=a=b;
int a =0;
System.out.println(a=1);//打印1
·JAVA中使用==符号来判定两边的值是否相等
例: 3+2 ==5→true
3>2 ==5>4→true
·JAVA中用!=符号来判定两边是否不同
例: System.out.println(3+2!=5);//false,5=5,相同,所以为false!
“==”只要兼容,就可以比较,“=”只能比较数字,而且==中间不能出现空格。
例: ‘a’==97;
true==false;
1.1.3. 逻辑运算符
逻辑运算符操作的都是布尔值,运行结束之后返回的也是boolean值
& 同真则真,描述一种使条件成立的情况的组合,限制多。
| 同假则假,描述的范围太广,用的很少。
^ 判断两边是否不同,不同则为true,相同则为false
! 取反,!true结果是false,!false结果是true
&& 前半是false短路,不运行后一半。比&多进行一次对前面式子的判定。&&的运算级别大于||。
System.out.println(false && true || true);//true
|| 前半是true短路,不运行后一半。
System.out.println(true || true && false);//true
有一种很骚的面试题:false&&.......一大串,问你运算结果?
你可能会答false,结果......一大串里有一个语法错误。
Ø 位运算符(作了解)
任何信息在计算机中都是以二进制的形式保存的,&、|、^除了可以作为逻辑运算符,也可以做为位算符。
它们对两个操作数中的每一个二进制位都进行运算,0当做false,1当做true。
&将两个二进制数每一位进行与运算,两边都为1结果才为1,只要有一边是0,结果就为0。
|将两个二进制数每一位进行或运算,两边都为0结果才为0,只要有一边是1,结果就为1。
^将两个二进制数每一位进行异或运算,只要两边不同结果就为1,相同则为0。
1.1.4. 移位运算符
我们可以对数据按二进制位进行移位操作,java的移位运算符有三种:
<< 左移 将二进制的每一位向左移,低位补0。左移几位就相当于乘以2的几次方。
>> 右移 将二进制的每一位向右移,原来高位是0就补0,原来高位是1就补1。右移几位就相当于除以2的几次方。
>>> 无无符号右移 将二进制的每一位向右移,高位补0。正数移动没区别,负数移动后变为正数。
例题:
byte b=1;
b<<8;
结果256。还是类型转换的知识。→低转高
有两个int型变量a和b,在不使用第三个变量的情况下交换两个变量中的值。
解答:有三种方法(未整理)
移位运算符在面试中的考点:左移*2,右移/2,做快速运算3*8→3<<3
1.1.5. 运算符优先级
思考一下代码运行结果:
System.out.println(1 + 2 * 3);//7
System.out.println(false && true || true);//true
System.out.println(true || true && false); //true
int a = 2;
int b = a + 3 * a++;
System.out.println(b); //8
int a = 2;
int b = a++ + 3 * a;
System.out.println(b); //11
int a = 1;
int b = 2;
System.out.println(a+++b); //3
1.1.6. 条件运算符
条件运算符是目前唯一的三目运算符
格式:
条件表达式?表达式1:表达式2 3>2?4:5
true/false?值1:值2;
当条件为真时,该运算符的结果是表达式1,不运行表达式2
当条件为假时,该运算符的结果是表达式2,不运行表达式1
三目运算符是最爱出题的地方之一
面试题:
int a =10;
double b=9.9;//最贱的是这里写9!
System.out.println(a>b?a:b);
结果:10.0
int a = 10;
int b = 20;
System.out.println( b-a > a-b ? a-b : b-a);//-10
面试题2:
System.out.println( true ? false : true ? false : true );
//true ? false : (true ? false : true)false
面试题3:
??? a = 3 > 2 ? 1 : true;
System.out.println( a );// 打印结果1
面试题4:
int a = 1;
int b = 2;
int c = a++ > b-- ? ++a : --b
问,a、b、c的值
答:a= 2,b= 0,c= 0
1.1.7. 复合赋值运算符
复合赋值运算符
+= -= *= /= %=
<<= >>= >>>= &= |=
a+=b 计算形式等同于 a = a + b
a+=b+5 计算形式等同于 a = a + (b+5)
虽然+=运算结果上等同于 + ,但是看一个例子
byte b=1;
b=b+1;//报错
byte b=1;
b+=1;//不报错
思考一下,+=和+的内存结构图是怎样的?
一些例子:
int a =1;
int b=c=d=e=a;//报错,变量未声明不能使用。
int a=2;
a += a++;//4
int a =2;
a+=(a=++a);
System.out.println(a);//5
难点:以+=为例,复合赋值运算符的关键点在于“先提取”!
两道面试题:
int a =1;
a+=(a=a++);
System.out.println(a);//2
第一道题的难点在“先提取”
int a =1;
a+=a+++(a=1);
System.out.println(a);//3
其中,第二道面试题考查点非常多:复合赋值、算数运算、赋值表达式
1.1.8. 运算符总结(一天课时):
运算符这部分考点,主要是考你能否跟JVM一个思维,用JVM的思维去处理基本问题。
算数(重点,但不是难点)
关系(运算结果boolean,注意==与= 的差别)
逻辑(重点,不是难点,注意&&和||,而且&&的运算优先级大于||,System.out.println(false && true || true);//true)
移位(考察点:左移*2、右移/2、3*8快速运算)
条件(重点,把握住true表达式1运行,表达式2不运行;false表达式2运行,表达式1不运行)
复合赋值表达式(难点,综合前面部分知识,也是难点)