整理自 韩顺平零基础30天学Java
运算符
算术运算符
/
10 / 4 = 2 ,10.0 / 4 = 2.5
那么double ( 10 / 4 ) = 2.0
% 取模,取余
在Java中 % 的本质,a % b = a - a / b *b
当a是小数时,公式 a % b = a - (int)a / b * b 有小数的运算得到的结果是近似值。
System.out.println( 10 % 3 ); //1
//-10 % 3 = -10 - (-10) / 3 * 3 = -10 + 9 = -1
System.out.println( -10 % 3 ); //-1
//10 % -3 = 10 - 10 / (-3) * (-3) = 10 - 9 = 1
System.out.println( 10 % -3 ); //1
System.out.println( -10 % -3 ); //-1
System.out.println( -10.5 % -3 ); //-10.5 - (-10) / 3 * 3 = -10.5 + 9 = -1.5
++
前:先自增后赋值,后:先赋值后自增
int i = 66;
System.out.println(++i + i); //67 + 67 =134
面试题
int i = 1;
i = i++;
System.out.println(i);
结果是多少?为什么?
使用临时变量:(1)temp = i;(2)i = i + 1;(3)i = temp;
我自己的理解是:后++是先赋值再自增,所以i = i++赋值完后就直接输出了。(不一定对,因为我理解不了上面的temp为什么还会有第三步。结合下面这道题,感觉我这个思路也可以。)
不确定我表达的是否清楚。梳理一下,i = 1先赋值给 i ,然后直接输出,在我们看不见的地方,i++进行了自增。如果这时是int j = 1 , i;i = j++;的话,那么i = 1,j = 2。
int i = 1;
i = ++i;
System.out.println(i);
结果是多少?为什么?
使用临时变量:(1)i = i + 1;(2)temp = i;(3)i = temp;
关系运算符(比较运算符)
结果为boolean型,一般用于if或循环体的判断。
逻辑运算符
这个知识点,离散数学、数字电路都有涉及。有兴趣的可以去看看,个人感觉离散数学的会比较有挑战性,很好玩。
逻辑与&和短路与&&
只有同时正确,结果才正确。类似于1 * 1 = 1,0 * 0 = 0、0 * 1 = 0、1 * 0 = 0。
短路与:左边为错误时,计算机就不再判断右边,结果一定是错误。
逻辑与:左右都需要判断。
逻辑或|和短路或||
只有同时错误,结果才错误。类似于0 + 0 = 0,1 + 1 = 1、0 + 1 = 1、1 + 0 = 1。
短路或:左边为正确时,计算机就不会判断右边了,因为一定是正确的。
逻辑或:左右都需要判断。
逻辑异或^
不同才正确。类似于1 ⊕ 1 = 0、0 ⊕ 0 = 0,1 ⊕ 0 = 1、0 ⊕ 1 = 0
逻辑非!:取反
赋值运算符
赋值运算符,如 a += b; 等价于 a = a + b;
复合取值运算符会进行类型转换。
byte b = 3;
b += 2; //等价于 b = (byte)(b + 2); 强制转换---b = b + 2;直接写会报错
三元运算符:条件表达式?表达式1:表达式2;
如果为true,取表达式1;为false,取表达式2。(本质是一个if-else)
表达式1和表达式1要为可以赋给变量的类型(或可以自动转换)。
运算符的优先级
1)( ) , { }等
2)单目运算:++ --
3)算术运算符
4)位移运算符
5)比较运算符
6)逻辑运算符
7)三元运算符
8)赋值运算符
如果不确定,就加括号。类似于小学数学的先算括号里面的,对应()也排在第一。
标识符的命名规则和规范
规则
- 字母、数字、_、$,但数字不可以开头。
- 不可以使用关键字和保留字,但可以包含。
- 严格区分大小写。
- 不能包含空格。
规范
- 包名:com.douruimi.demo
- 类名、接口名:DouRuiMi(大驼峰)
- 变量名、方法名:douRuiMi(小驼峰,简称驼峰法)
- 常量名:DOU_RUI_MI
键盘输入语句
- 导包:java.util
- 创建该类对象(声明变量)
- 调用功能
import java.util.Scanner; //把java.util下的Scanner类导入
//Scanner类 简单的文本扫描器
public class input{
public static void main(String[] args){
//创建Scanner对象
Scanner scanner = new Scanner(System.in);
System.out.println("请输入名字:");
//接收用户输入
String name = scanner.next();
System.out.println("请输入年龄:");
int age = scanner.nextInt();
System.out.println("请输入薪水:");
double sal = scanner.nextDouble();
System.out.println("名字:" + name + "年龄:" + age + "薪水:" + sal);
}
}
//char类型
char c1 = scanner.next().charAt(0);
进制
二进制、十进制、八进制 0开头、十六进制 0x或0X开头,A-F不区分大小写。
进制转换
n进制转十进制
从右边开始看,第一位是 当前位数的数字×n^0 ,以此类推。
如二进制转十进制:1001→1 × 2^0 + 0 × 2^1 + 0 × 2^2 + 1 × 2^3 = 9
一般,二进制的算法直接用8421。
十进制转n进制:除法取余法
将数字不断除以n,直到商为0,然后把每步得到的余数倒过来,就是对应的n进制。
如十进制转二进制:34→010001→0b100010。
或者用n进制转十进制的方法:直到每个位置对应的大小,直接放进去减一减就出来了。
还是34转二进制:32 16 8 4 2 1 = 1 0 0 0 1 0
二进制转八进制和十六进制
八进制:低位开始每3位为一组,转成对应的八进制。
十六进制:每4位一组。
八进制/十六进制转二进制,就是1位转3位/4位,高危位数不够补零即可。
原码、反码、补码
- 二进制最高位是符号位:0 正数,1 负数。
- 正数的原码、反码、补码都一样。
- 负数的反码 = 它的原码符号位不变,其他位取反。
- 负数的补码 = 它的反码 + 1,即负数的反码 = 负数的补码 - 1。
- 0的反码、补码都是0。
- Java没有无符号数,即Java中的数都是有符号的。
- 在计算机运算时,都是以补码的方式来运算的。
- 当我们看运算结果时,要看它的原码。
这个详细的在《计算机组成原理》,有提到原码、反码的局限性,具体有点忘了。后续复习到机组时,我再回来补吧,或者写一篇maybe。
位运算符
&、|、^、~、>>、<< 和 >>>
按位与& 按位或| 按位异或^ 按位取反~
先得到补码,再进行运算,运算结束后转换成反码,最后转换成原码。记住符号位
该知识点在100p,可以去看看老师的讲解。
位移运算符>> << >>>
- 算术右移>>:低位溢出,符号位不变,并用符号位补溢出的高位。
- 算术左移<<:符号位不变,低位补0。
- >>>逻辑右移:也叫无符号右移,低位溢出,高位补0。
int a = 1 >> 2; //把1向右位移2位 00000001→00000000 本质 1 / 2 / 2 = 0
int c = 1 << 2; //00000001→00000100 本质 1 * 2 * 2
程序控制结构
顺序控制:默认,从上到下
分支控制
if-else
if(条件){
语句;
}else if(条件){
语句;
}else{
语句;
}
单分支:if
双分支:if - else
多分支:if - else if - ... - else
嵌套分支:尽量不要超过三层,可读性不好
switch分支结构
switch(表达式){
case 常量1:
语句块1;
break;//退出switch分支
.....
default: //以上都不匹配,执行这个
default语句块;
break;
}
进行算法设计时,可以利用穿透减少代码量,如相同输出。
细节
- 表达式数据类型,应和case后的常量类型一致,或者是可以自动转成可以相互比较的类型,比如输入的是字符,而常量是int。
- switch(表达式)中表达式的返回值必须是:byte、short、int、char、enum[枚举]、String。
- case子句中的值必须是常量,而不能是变量。
- default子句是可选的,当没有匹配的case时,执行default。
- break语句用来在执行完一个case分支后使程序跳出switch语句块;如果没有写break,程序会顺序执行到switch结尾。
习题
//对学生成绩大于60分的,输出”合格“。低于60分的,输出“不合格”。
Scanner scanner1 = new Scanner(System.in);
System.out.println("请输入成绩:");
Double score = scanner1.nextDouble();
if(score >=0 && score <=100){
switch((int)(score/60)){ //强转,成绩在60-100为1,在0-60为0
case 1:
System.out.println("合格");
break;
case 0:
System.out.println("不合格");
break;
}
}
switch和if的比较
- 如果判断的具体数值不多,而且符合byte、short、int、char、enum、String这六种类型,两种语句都可以使用,但建议使用switch。
- 其他情况:对区间判断,对结果为boolean类型判断,使用if。if的使用范围更广。
循环控制
for循环
for(循环变量初始化;循环条件;循环变量迭代){
循环操作;
}
循环变量在括号内定义,则只存在于for循环中。
循环变量可以定义在外面,循环变量迭代可以写在里面,此时for( ;循环条件; )
while循环
循环变量初始化;
while(循环条件){
循环体;
循环变量迭代;
}
细节
- 循环条件是返回一个布尔值的表达式。
- while循环是先判断再执行语句。