持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第18天,点击查看活动详情
1 运算符:算术运算符
算术运算符的注意问题
-
如果对负数取模,可以把模数负号忽略不记,如:5%-2=1。 但被模数是
负数则不可忽略。此外,取模运算的结果不一定总是整数。
%:求余运算符。
求余运算的结果不一定总是整数,它的计算结果是使用第一个操作数除以第二个操作数,得到一个整除的结果后剩下的值就是余数。由于求余运算也需要进行除法运算,因此如果求余运算的两个操作数都是整数类型,则求余运算的第二个运算数不能是0,否则将引发除以零异常。如果求余运算的两个操作数中有1个或者2个都是浮点数,则允许第二个操作数是0或0.0,只是求余运算的结果是非数:NaN。0或0.0对零以外的任何数求余都将得到0或0.0。
当计算两边都是正数,如果左边小于右边,那么结果就是左边;如果左边等于右边,那么结果就是为0。
System.out.println(-10%-3);//-1
System.out.println(-2%5);//-2
System.out.println(2%-5);//2
System.out.println(-2%-5);//-2
如果运算时出现负数,先忽略负号,计算出结果之后,左边的数是正数,那么结果就为正,反之为负。
应用:开关算法:任何数模以2结果0或 1
/:除法运算符。
除法运算符有些特殊,如果除法运算符的两个操作数都是整数类型,则计算结果也是整数,就是将自然除法的结果截断取整,例如19/4的结果是4,而不是5。如果除法运算符的两个运算数都是整数类型,则除数不可以是0,否则将引发除以零异常。但如果除法运算符的两个操作数有1个是浮点数,或者2个都是浮点数,则计算结果也是浮点数,这个结果就是自然除法的结果。而且此时允许除数是0,或者0.0,得到结果是正无穷大或负无穷大。
-
对于除号“/”,它的整数除和小数除是有区别的:整数之间做除法时,只 保留整数部分而舍弃小数部分。 例如:int x=3510;x=x/1000*1000; x的 结果是?
-
“+”除字符串相加功能外,还能把非字符串转换成字符串.例如: System.out.println(“5+5=”+5+5); //打印结果是? 5+5=55 ?
思考1:
short s = 3;
s = s+2; ①
s += 2; ②
①和②有什么区别?
从结果中个看出,当指令为s=s+2进行编译时,会报错.
原因是数字2是int型
的常量,s+2会自动转换成int型
,将一个int型赋给一个short型的s,自然编译会出错。
如果一定要使用s+2的话,可以将s+2改为(short)(s+2),这时(short)将(s+2)的值强转为short型,这时便可以将(s+2)的值赋给s.
为什么s+=2不会报错呢?
因为编译器自动将+=运算符
后面的操作数强制转换为前面变量的类型
,所以s+=2不会报错.
同时类似的还有: -= *= /= %=
++自增运算符
i++和++i
int i = 0;
i = i++;
System.out.println(i)
//结果为 0
原因:
i++
:先取值后运算(先取局部变量 i
的值放入操作数栈
计算,后将局部变量的 i 自增)
++i
: 先运算后取值(先将局部变量的 i
自增,再将 i 放入操作数栈
计算)
package pers.mobian.questions01;
public class test01 {
public static void main(String[] args) {
int i = 1;
i = i++;
int j = i++;
int k = i + ++i * i++;
System.out.println("i="+i);
System.out.println("j="+j);
System.out.println("k="+k);
}
}
结果:i = 4;j = 1; k = 11 底层原理
三目运算符 (条件表达式)?表达式1:表达式2;
- 代码案例1
public static void main(String[] args) {
int a = 1;
int b = 1;
// int类型(9)转换为double类型(9.0D)
System.out.println(a == b ? 9.9 : 9);
// (98)在char取值范围内,转换为对应ASCII码
System.out.println(a == b ? 'a' : 98);
// 超出char取值范围,统一转为int类型
System.out.println(a == b ? 'a' : Integer.MAX_VALUE);
// 触发二元数字提升,统一转为变量int类型
System.out.println(a == b ? 'a' : b);
System.out.println(a != b ? 'a' : b);
}
// 输出结果
9.9
a
97
97
1
练习题
- 考查运算符的优先级
class Demo{
public static void main(String[] args){
int x=0,y=1;
if(++x==y-- & x++==1||--y==0)
System.out.println("x="+x+",y="+y); //x = 2,y = 0;
else
System.out.println("y="+y+",x="+x);
}
}
- 编写代码实现两个变量值交换,int m = 3, n =5;
答案一:
int temp = m;
m = n;
n = temp;
答案二:
m = m + n;
n = m - n;
m = m - n;
答案三:
m = m ^ n;
n = m ^ n;
m = m ^ n;
- 如何求一个0~255范围内的整数的十六进制值,例如60的十六进制表示形式3C
位运算符
- &:按位与。
- |:按位或。
- ~:按位非。
- ^:按位异或。
- <<:左移运算符。
- >>: 右移运算符
- >>>:无符号右移运算符
按位非只需要一个操作数,这个运算符将把操作数在计算机底层的二进制码
按位取反
。如下代码测试了按位与和按位或运算的运行结果。
//将输出1
System.out.println(5 & 9);
//将输出13
System.out.println(5 | 9);
左移运算符是将运算数的二进制码整体左移指定位数,左移后右边空出来的位以0填充。例如如下代码
//输出20
System.out.println(5 << 2);
//输出-20
System.out.println(-5 << 2);
上面的32位数是-5的补码,左移两位后得到一个二进制补码,这个二进制补码的最高位是1,表明是一个负数,换算成十进制数就是-20。
Java的右移运算符有两个:>>和>>>,对于>>运算符而言,把第一个操作数的二进制码右移指定位数后,左边空出来的位以原来的符号位填充,即如果第一个操作数原来是正数,则左边补0;如果第一个操作数是负数,则左边补1。>>>是无符号右移运算符,它把第一个操作数的二进制码右移指定位数后,左边空出来的位总是以0填充。
2 程序流程控制
2.1 if-else结构
分支结构:if-else
使用说明
条件表达式必须是布尔表达式(关系表达式或逻辑表达式)、布尔变量
语句块只有一条执行语句时,一对{}可以省略,但建议保留
if-else语句结构,根据需要可以嵌套使用
当if-else结构是“多选一”时,最后的else是可选的,根据需要可以省略
当多个条件是“互斥”关系时,条件判断语句及执行语句间顺序无所谓
当多个条件是“包含”关系时,“小上大下 / 子上父下”
练习题
- 实现对三个整数进行排序,输出时按照从小到大的顺序输出。
if(num1 >= num2){ //num1 >= num2的所有情况
if(num2 >= num3){
System.out.println(num3 + "," + num2 + "," + num1);
}else if(num3 >= num1){
System.out.println(num2 + "," + num1 + "," + num3);
}else{
System.out.println(num2 + "," + num3 + "," + num1);
}
}else{ //num1 >= num2的所有情况
if(num2 <= num3){
System.out.println(num1 + "," + num2 + "," + num3);
}else if(num3 <= num1){
System.out.println(num3 + "," + num1 + "," + num2);
}else{
System.out.println(num1 + "," + num3 + "," + num2);
}
}
2.2 switch-case结构
switch语句有关规则
switch(表达式)中表达式的值必须
是下述几种类型之一:byte,short, char,int,枚举 (jdk 5.0),String (jdk 7.0)
;
case子句中的值必须是常量
,不能是变量名或不确定的表达式值;
同一个switch语句,所有case子句中的常量值互不相同;
break语句用来在执行完一个case分支后使程序跳出switch语句块;如
果没有break,程序会顺序执行到switch结尾
default子句是可任选
的。同时,位置也是灵活的。当没有匹配的case时,
执行default
switch和if语句的对比
if和switch语句很像,具体什么场景下,应用哪个语句呢?
如果判断的具体数值不多,而且符合byte、short 、char、int、String、枚举等几种类型。虽然两个语句都可以使用,建议使用swtich语句。因为效率稍高
。
其他情况:对区间判断,对结果为boolean类型判断,使用if,if的使用范围更广。
也就是说,使用switch-case的,都可以改写为if-else
。反之不成立。
2.3 循环结构之for循环
- 语法格式
for (①初始化部分; ②循环条件部分; ④迭代部分){ ③循环体部分; }
- 执行过程:
①-②-③-④-②-③-④-②-③-④-.....-②
- 说明:
②循环条件部分为boolean类型表达式,当值为false时,退出循环 ①初始化部分可以声明多个变量,但必须是同一个类型,用逗号分隔 ④可以有多个变量更新,用逗号分隔
2.4 循环结构之while循环
语法格式
①初始化部分
while(②循环条件部分){ ③循环体部分; ④迭代部分; }
执行过程:
①-②-③-④-②-③-④-②-③-④-...-②
说明:
注意不要忘记声明④迭代部分。否则,循环将不能结束,变成死循环。
for循环和while循环可以相互转换
2.5 循环结构之do-while循环
语法格式 ①初始化部分; do{ ③循环体部分 ④迭代部分 }while(②循环条件部分); 执行过程: ①-③-④-②-③-④-②-③-④-...② 说明: do-while循环至少执行一次循环体。
特殊关键字的使用:break、continue
break 语句 break语句用于终止某个语句块的执行 { …… break; …… } break语句出现在多层嵌套的语句块中时,可以通过标签指明要终止的是 哪一层语句块 label1: { …… label2: { …… label3: { …… break label2; …… } } }
特殊流程控制语句2 continue 语句 continue只能使用在循环结构中 continue语句用于跳过其所在循环语句块的一次执行,继续下一次循环 continue语句出现在多层嵌套的循环语句体中时,可以通过标签指明要跳过的是哪一层循环
附加:特殊流程控制语句3 return:并非专门用于结束循环的,它的功能是结束一个方法。 当一个方法执行到一个return语句时,这个方法将被结束。 与break和continue不同的是,return直接结束整个方法,不管 这个return处于多少层循环之内
特殊流程控制语句说明
break只能用于switch语句
和循环语句
中。
continue 只能用于循环语句
中。
二者功能类似,但continue是终止本次
循环,break是终止本层
循环。
break、continue之后不能有其他的语句,因为程序永远不会执行其后的语句。
标号语句必须紧接在循环的头部。标号语句不能用在非循环语句的前面。 很多语言都有goto语句,goto语句可以随意将控制转移到程序中的任意一条
语句上,然后执行它。但使程序容易出错。Java中的break和continue是不同
于goto的。