进制
世界上有 10 种人,认识和不认识二进制的。
- 二进制(binary):0,1 ,满2进1。以
0b
或0B
开头。 - 十进制(decimal):0-9 ,满10进1。
- 八进制(octal):0-7 ,满8进1。以
0
开头。 - 十六进制(hex):0-9 及 A-F(不区分大小写),满16进1。 以
0x
或0X
开头表示。
直接 print
出来的都是十进制。
int num1 = 0b100;
int num2 = 100;
int num3 = 0100;
int num4 = 0x100;
System.out.println(num1);
System.out.println(num2);
System.out.println(num3);
System.out.println(num4);
运算符
分类:
- 算术运算符:
+
-
*
/
%
++
--
- 赋值运算符:
=
+=
-=
*=
/=
%=
- 比较运算符(关系运算符):
==
!=
<
>
<=
>=
instanceof
- 逻辑运算符:
&
—逻辑与|
—逻辑或!
—逻辑非&&
—短路与||
—短路或^
—逻辑异或 - 位运算符:
<<
>>
>>>
&
|
^
~
- 三元运算符:
(条件表达式) ?表达式1 :表达式2 ;
挑一些要点介绍一下。
取余运算
int m1 = 12;
int n1 = 5;
System.out.println("m1 % n1 = " + m1 % n1);
int m2 = -12;
int n2 = 5;
System.out.println("m2 % n2 = " + m2 % n2);
int m3 = 12;
int n3 = -5;
System.out.println("m3 % n3 = " + m3 % n3);
int m4 = -12;
int n4 = -5;
System.out.println("m4 % n4 = " + m4 % n4);
取余结果的符号与被模数一致。
自增自减
int a1 = 10;
int b1 = ++a1;
System.out.println("a1 = " + a1 + ",b1 = " + b1);
int a2 = 10;
int b2 = a2++;
System.out.println("a2 = " + a2 + ",b2 = " + b2);
自增不会改变数据类型,而 + 1
会。
short a = 1;
short b = a + 1; //×
short b = a++; //√
赋值
1.+=
不会改变数据类型。
short a = 1;
a = a + 1; //×
a += 1; //√
int i = 1;
i *= 0.1;
System.out.println(i);
i++;
System.out.println(i);
2.
int num = 0;
(num++)++; //×
3.n *= m++;
→ n = n * m++
→ n = n * m; m++;
逻辑运算符
&
—逻辑与(单与)&&
—短路与(双与)|
—逻辑或(单或)||
—短路或(双或)!
—逻辑非^
—逻辑异或
boolean b1 = false;
int num1 = 10;
boolean result1 = (b1 & (num1++ > 0));
System.out.println(result1);
System.out.println(num1);
boolean b2 = false;
int num2 = 10;
boolean result2 = (b2 && (num2++ > 0));
System.out.println(result2);
System.out.println(num2);
结论:短路——出结果则停,不继续运算。
位运算符
<<
>>
>>>
~
&
|
^
运算符 | 含义 | 例 | 细节 |
---|---|---|---|
<< | 左移 | 3<<2 → 3*2*2 → 12 | 被移除的高位丢弃,右边补0。 |
>> | 右移 | 3>>2 → 3\2 → 1 | 最高位是0(正数),左边补0; 最高位是1(负数),左边补1。 |
>>> | 无符号右移 | 3>>>2 → 3\2 → 1 | 无论最高位是0或者是1,左边都补0。 |
& | 按位与 | 6&3 → 110&011 → 010 → 2 | |
| | 按位或 | 6|3 → 110|011 → 111 → 7 | |
^ | 按位异或 | 6^3 → 110^011 → 101 → 5 | |
~ | 取反 | ~6 → ~00000110 → 11111001 → -7 ~(-6) → ~11111010 → 00000101 → 5 |
按补码取反 |
- 左移是在右补0(正负数都是)。正数左移太多位会出现负数
- 右移是在左补1(负数)、补0(正数)。
- 无符号右移,在左补0,
对于 &
^
和 |
,判断其是逻辑运算符还是位运算符,取决于其左右两边是布尔型还是整型。
练习:交换两个变量的值
int n1 = 10;
int n2 = 20;
/*
法1
弊端:
1)n1 + n2 可能会超出 int 范围
2)只能交换数值
*/
n1 = n1 + n2;
n2 = n1 - n2;
n1 = n1 - n2;
/*
法2
弊端:难理解
不过也不怎么用,不用在意
*/
num1 = num1 ^ num2;
num2 = num1 ^ num2;
num1 = num1 ^ num2;
真实开发的时候,除非操作数非常非常非常大,否则用正常的临时变量交换法就行。
三元运算符
String str = (m > n)? "m大" : ((m == n)? "m和n相等" : "n大");
int max = ((n1 > n2)? n1 : n2) > n3)? ((n1 > n2)? n1 : n2) : n3;
看上去很 NB,但是可读性很差,效率上也没提升,所以没卵用。
另外三元运算可以转换成 if else
,但 if else
未必能转换成三元运算。
运算符优先级
没必要记,有优先级需求用括号。
程序流程控制
- 顺序结构
- 分支结构
- 循环结构
顺序结构没什么说的。
分支结构
if-else
if(条件表达式1){
执行代码块1;
}else if (条件表达式2){
执行代码块2;
}
...
else{
执行代码块n;
}
- 当多个条件是“互斥”关系时,条件判断语句及执行语句间顺序无所谓。
- 当多个条件是有交集的关系,需要根据实际情况考虑。
- 当多个条件是“包含”关系时,条件范围小的在上,范围大的在下,否则范围小的就没机会执行了。
switch
switch(表达式){
case 常量1:
语句1;
break;
case 常量2:
语句2;
break;
...
case 常量N:
语句N;
break;
default:
语句;
break;
}
default
语句是可选的,位置也是灵活的。- switch( ) 中的表达式,只能是
byte
、short
、char
、int
、枚举、String
之一
例题:输入 year
、month
和 day
,输出这一天是今年的第几天 sum
。
switch(month){
case 12:
sum += 30;
case 11:
sum += 31;
//...
case 2:
if((year%4 == 0 && year%100 != 0) || year%400 == 0){
sum += 29;
}else{
sum += 28;
}
case 1:
sum += day;
}
凡是可以使用 switch-case 结构的,都可以转换为 if-else 。反之不成立。
条件不多时,优先使用 if-else。
循环结构
- for
for(int i = 0; i < n; i++){ ... }
结果:int n = 1; for(System.out.print('a'); n <= 3; System.out.print('c'), n++){ System.out.print('b'); }
abcbcbc
- while
- do-while
for 和 while 对比
for(int i = 0; i < n; i++){
...
}
相当于
int i = 0;
while(i < n){
...
i++;
}
- for 定义的 i 是局部的,while 定义的 i 是全局的(当然 for 也可以定义全局的 i)
- 已知循环次数用 for,不确定循环次数用 while
return
的作用是结束方法,不是结束循环。之所以结束循环是因为方法结束。
带标签的break和continue
label:for(int i = 1; i < 999; i++){
for(int j = 1; j < 10; j++){
if(j % 4 == 0){
break label;
}
System.out.print(j);
}
}
Scanner
步骤:
- 导入包
import java.util.Scanner;
- Scanner 的实例化
Scanner scan = new Scanner(System.in);
- 调用 Scanner 类的相关方法,获取指定类型的变量
System.out.println("请输入姓名:"); String name = scan.next(); System.out.println("请输入年龄:"); int age = scan.nextInt(); System.out.println("请输入体重:"); double weight = scan.nextDouble(); System.out.println("请输入性别(true男false女):"); boolean gender = scan.nextBoolean(); System.out.println("您好," + name + "。您今年" + age + "岁。体重为" + weight + "kg。性别" + gender + "。");
Scanner 没有提供获取char
型的获取。所以非要获取char
的话,只能这么做:String srt = scan.next(); char c = str.charAt(0); //获取索引为 0 的字符