文章目录
1. 运算符
1.1 算术运算符(理解)
1.1.1 运算符和表达式
-
运算符:对常量或者变量进行操作的**符号**
-
表达式:用**运算符把常量或者变量链接起来的符合java语法的式子**。
不同运算符连接的表达式体现的是不同类型的表达式。
-
举例说明:
int a = 10; int b = 20; int c = a + b;
+:是运算符,并且是算术运算符
a + b :是表达式,由于 + 是算数运算符,所以这个表达式是算术表达式。
1.1.2 算术运算符
符号 | 作用 | 说明 |
---|---|---|
+ | 加 | |
- | 减 | |
* | 乘 | 与“×”相同 |
/ | 除 | 与“÷”相同 |
% | 取余 | 获取的是两个数据做除法的余数 |
注意事项:
/和%的区别:两个数据做除法,/取结果的商,%取结果的余数。
整数操作只能得到整数,要想得到小数。必须有浮点数参与运算。
1.1.3 字符的“+”操作
char类型参与算术运算,使用的是计算机底层对应的十进制数值。需要我们记住三个字符对应的数值:
- ‘a’ --> 97 ,a-z是连续的,所以’b’对应的数值是98,’c’是99,依次递加。
- ‘A’ --> 65 ,A-Z是连续的,所以’B’对应的数值是66,’C’是67,依次递加。
- ‘0’ --> 48 ,0-9是连续的,所以’1’对应的数值是49,’2’是50,依次递加。
public class Test {
public static void main(String[] args) {
// 可以通过使用字符与整数做算术运算,得出字符对应的数值是多少
char ch1 = 'a';
System.out.println(ch1 + 1); //输出:98,97 + 1 = 98
char ch2 = 'A';
System.out.println(ch2 + 1); //输出:66,65 + 1 = 66
char ch3 = '0';
System.out.println(ch3 + 1); //输出:49,48 + 1 = 49
}
}
算术表达式中**包含不同的基本数据类型的值的时候,整个算术表达式的类型会自动进行提升**。
提升规则:
byte类型,short类型和char类型将被提升到int类型,不管是否有其他类型参与运算。
整个表达式的类型自动提升到与表达式中最高等级的操作数相同的类型
等级顺序:
byte,short,char --> int --> long -->float --> double
例如:
public class Test {
public static void main(String[] args) {
byte b1 = 10;
byte b2 = 20;
//byte b3 = b1 + b2; // 错误: 不兼容的类型: 从int转换到byte可能会有损失
int i3 = b1 + b2; //应该使用int接收
byte b3 = (byte)(b1 + b2); //或者将结果强制转换为byte类型
int num1 = 10;
double num2 = 20.0;
double num3 = num1 + num2; //使用double接收,因为num1会自动提升为double类型
}
}
备注:
正是由于上述原因,所以在程序开发中我们很少使用byte或者short类型定义整数。也很少会使用char类型定义字符,而使用字符串类型,更不会使用char类型做算术运算。
1.1.4 字符串的“+”操作
在“+”操作中,如果出现了字符串,这个“+”是字符串连接符,而不是运算符。
当连续进行“+”操作时,从左到右逐个进行。
public class Test {
public static void main(String[] args) {
System.out.println("heruo" + 666); //输出:heruo666
System.out.println(10 + 10 + "heruo"); //输出:20heruo
System.out.println("heruo" + 10 + 10); //输出:heruo1010
// 可以使用小括号改变运算的优先级
System.out.println("heruo" + (10 + 10)); //输出:heruo20
}
}
1.2 赋值运算符(应用)
赋值运算符的作用是将一个表达式的值赋给左边,左边必须是可修改的,不能是常量。
符号 | 作用 | 说明 |
---|---|---|
= | 赋值 | a=10,将10赋值给a |
+= | 加后赋值 | a+=b,将a+b的值赋给a |
-= | 减后赋值 | a-=b,将a-b的值赋给a |
*= | 乘后赋值 | a* =b,将a* b的值赋给a |
/= | 除后赋值 | a/=b,将a/b的值赋给a |
%= | 取余后赋值 | a%=b,将a%b的值赋给a |
注意:
扩展的赋值运算符隐含了强制类型转换。
public class Test {
public static void main(String[] args) {
short s = 10;
//s = s + 10; // 此行代码报错,因为运算中s提升为int类型,运算结果int赋值给short可能损失精度
s += 10; // 此行代码没有问题,隐含了强制类型转换,相当于 s = (short)(s + 10);
}
}
1.3 自增资减运算符(理解)
符号 | 作用 | 说明 |
---|---|---|
++ | 自增 | 变量的值加1 |
– | 自减 | 变量的值减1 |
注意:
++ 和 – 既可以放在变量的后边,也可以放在变量的前边。
单独使用的时候, ++ 和 – 无论是放在变量的前边还是后边,结果是一样的。
参与操作的时候,如果放在变量的后边,先拿变量参与操作,后拿变量做 ++ 或者 --。
参与操作的时候,如果放在变量的前边,先拿变量做 ++ 或者 --,后拿变量参与操作。
最常见的用法:单独使用
public class Test {
public static void main(String[] args) {
int i = 10;
i++; //单独使用
System.out.println("i: "+ i); //输出:i: 11
int j = 10;
++j;
System.out.println("j: " + j); //输出:j: 11
int x = 10;
int y = x++; //赋值运算,++在后面,所以x先把原来的值赋给y,x再自增1
System.out.println("x: " + x +" , y: " + y); //输出:x: 11 , y: 10
int m = 10;
int n = ++m; //赋值运算,++在前面,所以x先自增1,再把自增后的值赋给y
System.out.println("m: " + m + " , n: " + n); //输出:m: 11 , n: 11
}
}
练习
public class Test {
public static void main(String[] args) {
int x = 10;
int y = x++ + x++ + x++;
System.out.println(y); //求y的值
/*
解析:
三个表达式都是++在后,所以每次使用的都是自增前的值。
但是程序自左至右执行,
第1次运算,x自增前是10,自增后是11;
第2次运算,x自增前是11,自增后是12;
第3次运算,x自增前是12,自增后是13。
所以整个式子转换为:int y = 10 + 11 + 12;
输出结果为33
*/
}
}
//注意:实际开发中不建议写这样的代码
1.4 关系运算符(应用)
关系运算符一共有6种关系,分别为小于、小于等于、等于、大于、大于等于、不等于。
符号 | 说明 |
---|---|
== | a==b,判断a和b的值是否相等,成立为true,不成立为false |
!= | a!=b,判断a和b的值是否不相等,成立为true,不成立为false |
> | a>b,判断a是否大于b,成立为true,不成立为false |
> = | a>=b,判断a是否大于等于b,成立为true,不成立为false |
< | a<b,判断a是否小于b,成立为true,不成立为false |
<= | a<=b,判断a是否小于等于b,成立为true,不成立为false |
注意:
关系运算符的结果都是boolean类型,要么是true,要么是false。
千万不要把“==
”误写成“=
”,“==
”是判断是否相等的关系,”=
“是赋值。
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(a == b); // false
System.out.println(a != b); // true
System.out.println(a > b); // false
System.out.println(a >= b); // false
System.out.println(a < b); // true
System.out.println(a <= b); // true
// 关系运算的结果肯定是boolean类型,所以也可以将运输结果赋值给boolean类型的变量
boolean flag = a > b;
System.out.println(flag); // 输出false
}
}
1.5 逻辑运算符(应用)
逻辑运算符把各个运算的关系表达式连接起来组成一个复杂的逻辑表达式,以判断程序中的表达式是否成立,判断的结果是 true 或 false。
符号 | 作用 | 说明 |
---|---|---|
& | 逻辑与 | a&b,a和b都是true,结果为true,否则为false |
| | 逻辑或 | a|b,a和b都是false,结果为true,否则为false |
^ | 逻辑异或 | a^b,a和b结果不同为true,相同为false |
! | 逻辑非 | !a,结果和a的结果正好相反 |
public class Test {
public static void main(String[] args) {
//定义变量
int i = 10;
int j = 20;
int k = 30;
//&“与”,并且的关系,只要表达式中有一个值为false,结果即为false
System.out.println((i > j) & (i > k)); //false & false , 输出为false
System.out.println((i < j) & (i > k)); // true & false , 输出为false
System.out.println((i > j) & (i < k)); //false & true , 输出为false
System.out.println((i < j) & (i < k)); //true & true , 输出为true
System.out.println("--------"); //输出一条分割线
//|“或”,或者的关系,只要表达式中有一个值为true,结果即为true
System.out.println((i > j) | (i > k)); //false | false , 输出为false
System.out.println((i < j) | (i > k)); // true | false , 输出为true
System.out.println((i > j) | (i < k)); //false | true , 输出为true
System.out.println((i < j) | (i < k)); //true | true , 输出为true
System.out.println("--------"); //输出一条分割线
//^“异或”,相同为false,不同为true
System.out.println((i > j) ^ (i > k)); //false ^ false , 输出为false
System.out.println((i < j) ^ (i > k)); // true ^ false , 输出为true
System.out.println((i > j) ^ (i < k)); //false ^ true , 输出为true
System.out.println((i < j) ^ (i < k)); //true ^ true , 输出为false
System.out.println("--------"); //输出一条分割线
//!“非”,取反
System.out.println(i > j); //false
System.out.println(!(i > j)); //true
}
}
短路逻辑运算符
符号 | 作用 | 说明 |
---|---|---|
&& | 短路与 | 作用与&相同,但是有短路效果 |
|| | 短路或 | 作用与|相同,但是有短路效果 |
在逻辑与运算中,只要有一个表达式的值为false,那么结果就可以判定为false了,没有必要将所有表达式的值都计算出来。短路与操作就有这样的效果,可以提高效率。同理在逻辑或运算中,一旦发现值为true,右边的表达式将不再参与运算。
- 逻辑与&,无论左边真假,右边都要执行。
- 短路与&&,如果左边为假,右边不执行;如果左边为真,右边执行。
- 逻辑或|,无论左边真假,右边都要执行。
- 短路或||,如果左边为真,右边不执行;如果左边为假,右边执行。
public class Test {
public static void main(String[] args) {
int x = 3;
int y = 4;
System.out.println((x++ > 4) & (y++ > 5)); // 两个表达式都会运算
System.out.println(x); // 4
System.out.println(y); // 5
System.out.println("--------");// 打印一条华丽的分割线
System.out.println((x++ > 4) && (y++ > 5)); // 左边已经可以确定结果为false,所以右边不会运算
System.out.println(x); // 5
System.out.println(y); // 5
}
}
1.6 三元运算符(理解)
语法格式:
关系表达式 ? 表达式1 : 表达式2;
解释:
问号前面的位置是判断的条件,判断结果为boolean型,为true时调用表达式1,为false时调用表达式2。其逻辑为:如果条件表达式成立或者满足则执行表达式1,否则执行第二个。
举例:
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
int c = a > b ? a : b; // 判断 a>b 是否为真,如果为真取a的值,如果为假取b的值
System.out.println(c); //输出:20
}
}
习题1:
动物园里有两只老虎,已知两只老虎的体重分别为180kg、200kg,请用程序实现判断两只老虎的体重是否相同。
public class Test {
public static void main(String[] args) {
//1. 定义两个变量用于保存两只老虎的体重,单位为kg。
int weight1 = 180;
int weight2 = 200;
//2. 用三元运算符实现两只老虎体重的判断,体重相同返回true,否则返回false。
boolean b = weight1 == weight2 ? true : false;
//3. 输出结果
System.out.println("b: " + b);
}
}·
习题2
一座寺庙里住着三个和尚,已知他们的身高分别为150cm、210cm、165cm,请用程序实现获取这三个和尚的最高身高。
public class Test {
public static void main(String[] args) {
// 1. 定义3个变量用于保存和尚的身高,单位为cm。
int height1 = 150;
int height2 = 210;
int height3 = 165;
// 2. 用三元运算符获取前两个和尚的较高身高值,并赋值给临时身高值。
int tempHeight = height1 > height2 ? height1 : height2;
// 3. 用三元运算符比较临时身高值和第三个和尚的身高值,赋值给最高身高变量。
int maxHeight = tempHeight > height3 ? tempHeight : height3;
// 4. 输出结果
System.out.println("maxHeight: " + maxHeight);
}
}
2. 数据输入(应用)
我们可以通过**Scanner**类来获取用户的输入,使用步骤如下:
-
导包。Scanner类在java.util包下,所以需要将该类导入。导包的语句需要定义在类的上面。
import java.util.Scanner;
-
创建Scanner对象。
Scanner sc = new Scanner(System.in); // 创建Scanner对象,sc表示变量名,其他均不可变
-
接收数据
int i = sc.nextInt(); // 表示将键盘录入的值作为int数返回。
示例:
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
// 创建对象
Scanner sc = new Scanner(System.in);
// 接收数据
int x = sc.nextInt();
// 输出数据
System.out.println("x: " + x);
}
}
改写三个和尚案例,数据使用键盘录入。
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
// 身高未知,采用键盘录入实现,首先导包,然后创建对象
Scanner sc = new Scanner(System.in);
// 键盘录入三个身高分别赋值给三个变量
System.out.println("请输入第一个和尚的身高:");
int height1 = sc.nextInt();
System.out.println("请输入第二个和尚的身高:");
int height2 = sc.nextInt();
System.out.println("请输入第三个和尚的身高:");
int height3 = sc.nextInt();
// 用三元运算符获取前两个和尚的身高较高值,并保存到临时身高变量
int tempHeight = height1 > height2 ? height1 : height2;
// 用三元运算符获取临时身高和第三个和尚身高较高值,并保存到最高身高变量
int maxHeight = tempHeight > height3 ? tempHeight : height3;
// 输出结果
System.out.println("这三个和尚身高最高值为:" + maxHeight + "cm");
}
}
3. 流程控制语句(应用)
在一个程序执行的过程中,各条语句的执行顺序对程序的结果是有直接影响的。所以,我们必须清楚每条语句的执行流程。而且,很多时候要通过控制语句的执行顺序来实现我们想要的功能。
3.1 流程控制语句分类
- 顺序结构
- 分支结构(if, switch)
- 循环结构(for, while, do…while)
3.2 顺序结构
顺序结构是程序中最简单最基本的流程控制,没有特定的语法结构,按照代码的先后顺序,依次执行,程序中大多数的代码都是这样执行的。
顺序结构流程图:
开始 --> 语句A --> 语句B --> 语句C --> 结束
3.3 分支结构之if语句
3.3.1 if语句格式1
格式:
if (关系表达式) {
语句体;
}
执行流程:
- 首先计算关系表达式的值
- 如果关系表达式的值为true,就执行语句体
- 如果关系表达式的值为false,就不执行语句体
- 继续执行后面的语句内容
示例:
public class Test {
public static void main(String[] args) {
System.out.println("开始");
// 定义两个变量
int a = 10;
int b = 20;
// 需求:判断a和b的值是否相等,如果相等,在控制台输出:a等于b
if (a == b) {
System.out.print("a等于b");
}
int c = 10;
// 需求:判断a和c的值是否相等,如果相等,在控制台输出:a等于c
if (a == c) {
System.out.println("a等于c");
}
System.out.println("结束");
}
}
3.3.2 if语句格式2
格式:
if (关系表达式) {
语句体1;
} else {
语句体2;
}
执行流程:
- 首先计算关系表达式的值
- 如果关系表达式的值为true,执行语句体1
- 如果关系表达式的值为false,执行语句体2
- 继续执行后面的语句内容
示例:
public class Test {
public static void main(String[] args) {
System.out.println("开始");
// 定义两个变量
int a = 10;
int b = 20;
// 需求:判断a的值是否大于b。如果是,则输出:a的值大于b;否则,输出:a的值不大于b
if (a > b) {
System.out.println("a的值大于b");
} else {
System.out.println("a的值不大于b");
}
System.out.println("结束");
}
}
if语句案例:奇偶数
需求:任意给出一个整数,请用程序实现判断该整数是奇数还是偶数,并在控制台输出该整数是奇数还是偶数。
分析:
- 为了体现任意一个整数,采用键盘录入数据
- 判断一个整数为奇数还是偶数份两种情况,使用if…else结构
- 偶数的判断标准为:整数除2取余,结果为0
- 根据结果,输出对应的内容
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
// 使用键盘录入一个整数
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个整数:");
int num = sc.nextInt();
// 用if...else语句判断该整数是奇数还是偶数,并在控制台输出结果
if (num % 2 == 0 ) {
System.out.println(num + "是偶数");
} else {
System.out.println(num + "是奇数");
}
}
}
3.3.3 if语句格式3
格式:
if (关系表达式1) {
语句体1;
} else if (关系表达式2) {
语句体2;
}
...
else {
语句体n+1;
}
执行流程:
-
首先计算关系表达式1的值
-
如果值为true就执行语句体1;如果值为false就判断关系表达式2的值
-
如果值为true就执行语句体2;如果值为false就判断关系表达式3的值
-
…
-
如果没有任何关系表达式值为true,就执行语句体n+1
示例:
键盘录入一个星期数(1,2,…7),输出对应的星期一,星期二,…星期日
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
// 使用键盘录入一个星期数
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个星期数(1至7的整数):");
int week = sc.nextInt();
// 判断星期几,并在控制台输出结果
if (week== 1 ) {
System.out.println("星期一");
} else if (week== 2 ) {
System.out.println("星期二");
} else if (week == 3) {
System.out.println("星期三");
} else if (week == 4) {
System.out.println("星期四");
} else if (week == 5) {
System.out.println("星期五");
} else if (week == 6) {
System.out.println("星期六");
} else if (week == 7) {
System.out.println("星期日");
}
}
}
案例:
需求:小明快要期末考试了,小明爸爸对他说,会根据他不同的考试成绩,送他不同的礼物,假如你可以控制小明的得分,请用程序实现小明到底该获得什么样的礼物,并在控制台输出。
分析:
- 小明的成绩未知,可以键盘录入
- 由于奖励种类较多,属于多种判断,采用if…else…if格式实现
- 为每种判断设置对应的条件
- 为每种判断设置对应的奖励
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
// 小明的成绩未知,可以键盘录入
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个分数:");
int score = sc.nextInt();
// 由于奖励种类较多,属于多种判断,采用if...else...if格式实现
// 为每种判断设置对应的条件
// 为每种判断设置对应的奖励
// 数据测试:正确数据,边界数据,错误数据
if (score>100 || score<0) {
System.out.println("你输入的分数有误");
} else if (score>=96 && score<=100) {
System.out.println("换台电脑");
} else if (score>=91 && score<=95) {
System.out.println("换个手机");
} else if (score>=81 && score<=90) {
System.out.println("换个平板");
} else {
System.out.println("一顿毒打");
}
}
}