今日内容
- 运算符
- 分支语句
教学目标
- 能够知道哪些运算中发生了隐式转换
- 能够知道如何对数据进行强转
- 能够使用自增自减运算符并知道在前在后的区别
- 能够使用关系运算符完成数据的比较
- 能够掌握不同逻辑运算符的运算规则
- 能够掌握三元运算符的格式和执行流程
- 能够运用小扩号提升算数优先级
- 能够掌握 if 语句的三种格式使用
第五章 运算符
5.1 package管理类文件
包的作用
包就是文件夹,通过 Package 来管理不同功能的类文件。
在test-operator这个模块中,Demo1Operator1和Demo2Operator1是讲解知识点的类。Test1Operator1是写练习的类。我想把他们分开进行管理,放在一起太乱了。此时就可以在src下新建包进行管理。
使用包的步骤
- 右键点击src,再点击Package。
- 输入包名。
包名一般写成公司域名反写。黑马程序员的域名为:www.itheima.com。那么就去掉com,剩下来的反写。
输入:com.itheima 回车
- 在src下成功新建包
- 点击小齿轮,把Compact Middle Packages前面的勾去掉
- 此时包就会产生一个层级关系。
包就是文件夹,其实就是在src文件夹里面新建了一个com文件夹。
在com文件夹里面新建了一个itheima文件夹
- 在itheima文件夹包,再新建两个不同功能的包,来管理这三个类。
- 输入包名
其实就是在itheima文件夹下,再新建一个demo1文件夹用来存放课堂讲解知识点的类文件。
- 新建完毕之后出现demo1文件夹
- 把Demo1Operator和Demo2Operator拖到demo1文件夹中
- 在弹出的界面中点击Refactor表示确定。
- 展开demo1文件夹,就看到了文件夹中的两个类。
- 同样的操作,在itheima里面再新建一个test文件夹,用来存放讲解练习的类文件。
- 当这三个类分别存放完毕时,就会发现代码中第一行package后面已经不一样了。
这个表示所在的包名。
5.2 自增自减运算符
符号 | 作用 | 说明 |
++ | 自增 | 变量的值加1 |
-- | 自减 | 变量的值减1 |
注意事项:
- ++和-- 既可以放在变量的后边,也可以放在变量的前边。
- ++ 、-- 只能操作变量,不能操作常量
- 单独使用的时候, ++和-- 无论是放在变量的前边还是后边,结果是一样的。
- 参与操作的时候,如果放在变量的后边,先拿变量参与操作,后拿变量做++或者--。
- 参与操作的时候,如果放在变量的前边,先拿变量做++或者--,后拿变量参与操作。
- 最常见的用法:单独使用。
代码示例:
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; // 赋值运算,++在前边,所以是使用m自增后的值赋值给n,m本身自增1
System.out.println("m:" + m + ", m:" + m); // m:11,m:11
5.3 类型转换
在Java中,不同的基本数据类型之间是不能直接参与运算的。在底层需要先进行类型转换,变成一样的类型,再进行运算。
类型转换分为两种:
- 自动类型转换
- 强制类型转换。
5.3.1 隐式转换
把一个表示数据范围小的数值或者变量赋值给另一个表示数据范围大的变量。这种转换方式是自动的,直接书写即可。例如:
int a = 10;
double num = a; // 将int类型变量a里面的值,直接赋值给double类型
System.out.println(num); // 输出10.0
取值范围从小到大关系图:
说明:
- 取值范围小的数据,和取值范围大的数据进行运算,小的会先提升为大的之后,再进行运算
- 整数默认是int类型,byte、short和char类型数据参与运算均会自动转换为int类型。
- boolean类型不能与其他基本数据类型相互转换。
练习1:
//问变量c是什么数据类型?
int a = 10;
double b = 12.3;
??? c = a + b;
//double的取值范围比int大,所以在计算的时候,变量a会自动提升为double。
//最终是两个double相加,结果就是double类型的。
练习2:
byte a = 10;
byte b = 20;
byte c = a + b;
// 第三行代码会报错,a和b会自动转换为int类型,计算结果为int,int赋值给byte需要强制类型转换。
// 修改为:
int num = b1 + b2;
练习3:
int a = 1;
char b = 'a';
int c = a + b;
System.out.println(c);
//最终输出结果:98
//b会自动转换为int类型,字符变成int类型会查询码表,变成97
//第三行代码97 + 1 最终结果为98.
5.3.2 强制转换
把一个表示数据范围大的数值或者变量赋值给另一个表示数据范围小的变量。
强制类型转换格式:
目标数据类型 变量名 = (目标数据类型)值或者变量;
举例:
double num1 = 5.5;
int num2 = (int) num1; // 将double类型的num1强制转换为int类型
System.out.println(num2); // 输出5(小数位直接舍弃)
5.3.3 强转细节解释
- 强制转换有可能导致精度丢失
- 如果超出范围的数字进行强转会导致数据错误
举例:
double num1 = 5.5;
int num2 = (int) num1; // 将double类型的num1强制转换为int类型
System.out.println(num2); // 输出5(小数位直接舍弃)
//在上面的代码中,小数5.5强转成整数,后面的小数部分就舍弃了,这就是精度的丢失。
5.4 赋值运算符
赋值运算符的作用是将一个表达式的值赋给左边,左边必须是可修改的,不能是常量。
符号 | 作用 | 说明 |
= | 赋值 | 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 |
注意事项:
扩展的赋值运算符隐含了强制类型转换。
short s = 10;
s = s + 10; // 此行代码报出,因为运算中s提升为int类型,运算结果int赋值给short可能损失精度
s += 10; // 此行代码没有问题,隐含了强制类型转换,相当于 s = (short) (s + 10);
5.5 关系运算符
关系运算符有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。
千万不要把“”误写成“=”,""是判断是否相等的关系,"="是赋值。
代码示例:
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
5.6 逻辑运算符
- 理解层面:逻辑运算符,可以用来整合多个条件, 为一段整体的逻辑
- 代码层面:连接布尔类型的表达式, 或者是值
分类:
符号 | 作用 | 说明 |
& | 逻辑与 | a&b,a和b都是true,结果为true,否则为false |
| | 逻辑或 | a|b,a和b都是false,结果为false,否则为true |
^ | 逻辑异或 | a^b,a和b结果不同为true,相同为false |
! | 逻辑非 | !a,结果和a的结果正好相反 |
5.7 短路逻辑运算符
符号 | 作用 | 说明 |
&& | 短路与 | 作用和&相同,但是有短路效果 |
|| | 短路或 | 作用和|相同,但是有短路效果 |
在逻辑与运算中,只要有一个表达式的值为false,那么结果就可以判定为false了,没有必要将所有表达式的值都计算出来,短路与操作就有这样的效果,可以提高效率。同理在逻辑或运算中,一旦发现值为true,右边的表达式将不再参与运算。
计算规则:
- 逻辑与&,无论左边真假,右边都要执行。
- 短路与&&,如果左边为真,右边执行;如果左边为假,右边不执行。
- 逻辑或|,无论左边真假,右边都要执行。
- 短路或||,如果左边为假,右边执行;如果左边为真,右边不执行。
代码示例:
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((x++ > 4) && (y++ > 5)); // 左边已经可以确定结果为false,右边不参与运算
System.out.println(x); // 4
System.out.println(y); // 4
最为常用的逻辑运算符:
&& || !
5.8 三元运算符
格式
关系表达式 ? 表达式1 : 表达式2;
执行流程
问号前面的位置是判断的条件,判断结果为boolean型。
为true时调用表达式1,为false时调用表达式2。
其逻辑为:如果条件表达式成立或者满足则执行表达式1,否则执行第二个。
举例:
int a = 10;
int b = 20;
int c = a > b ? a : b; // 判断 a>b 是否为真,如果为真取a的值,如果为假,取b的值
5.8.2 练习-求三个数的最大值
需求:
键盘录入三个整数,找出最大值并打印在控制台。
import java.util.Scanner;
public class Test2Operator {
public static void main(String[] args) {
//1.使用Scanner键盘录入三个整数
Scanner sc = new Scanner(System.in);
System.out.println("请输入三个整数:");
int num1 = sc.nextInt();
int num2 = sc.nextInt();
int num3 = sc.nextInt();
//2:用三元运算符获取前两个整数的最大值,并用临时变量保存起来。
int temp = num1 > num2 ? num1 : num2;
//3:用三元运算符,让获取临时最大值和第三个数比较,得到结果。
int max = temp > num3 ? temp : num3;
//4:输出结果
System.out.println("最大值是:" + max);
}
}
思考:
如果我要求三个数的最小值呢?
只要把里面的大于号变成小于号就可以了。
5.9 运算符优先级(了解)
运算符的优先级就是在运算的过程中,如果出现了很多运算符,那么到底先算哪一个?在小学的时候,我们知道先乘除后加减,小括号优先于所有等等。
在Java中,运算符优先级如下图所示:
有没有觉得很麻烦,很头疼?所以,这些优先级我们不需要记忆。
只要知道一点即可:小括号优先于所有!
在计算的时候必定是先计算小括号里面的,再计算小括号外面的。
代码示例:
int a = 10;
int b = 20;
System.out.println(a > b || a < b && a > b);//代码阅读性很差
-----------改写如下--------------
int a = 10;
int b = 20;
System.out.println((a > b) || (a < b && a > b));//代码阅读性很好
第六章 流程控制语句
程序执行的过程中,各条语句的执行顺序对程序的结果是有直接影响的。
所以,我们必须清楚每条语句的执行流程。
而且,很多时候要通过控制语句的执行顺序来实现我们想要的功能。
6.1流程控制语句分类
- 顺序结构
- 分支结构(if, switch)
- 循环结构(for, while, do…while)
6.2 顺序结构
结构说明:
顺序结构是 Java 程序默认的执行流程,没有特定的语法结构,按照代码的先后顺序,依次执行
程序中大多数的代码都是这样执行的。
执行流程图:
代码示例:
System.out.println("开始");
System.out.println("执行代码1");
System.out.println("执行代码2");
System.out.println("执行代码3");
System.out.println("结束");
//从上往下依次执行
6.3 if语句
6.3.1 if语句格式1
格式:
if (关系表达式) {
语句体;
}
执行流程:
①首先计算关系表达式的值
②如果关系表达式的值为true就执行语句体
③如果关系表达式的值为false就不执行语句体
④继续执行后面的语句内容
案例:满足年龄才能上网
System.out.println("开始");
int age = 17;
if(age >= 18){
System.out.println("可以上网吧");
}
System.out.println("结束");
注意事项
- if 语句中,如果大括号控制的是一条语句,大括号可以省略不写
- if 语句的 ( ) 和 { } 之间不要写分号
6.2.2 if语句格式2
格式:
if (关系表达式) {
语句体1;
} else {
语句体2;
}
执行流程:
①首先计算关系表达式的值
②如果关系表达式的值为true就执行语句体1
③如果关系表达式的值为false就执行语句体2
④继续执行后面的语句内容
案例:满足年龄才能上网
System.out.println("开始");
int age = 17;
if(age >= 18){
System.out.println("可以上网吧");
}else{
System.out.println("再等等");
}
System.out.println("结束");
6.2.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。
案例:会员身份
// 键盘录入会员身份
Scanner sc = new Scanner(System.in);
System.out.println("请输入:");
int num = sc.nextInt();
// 使用if语句区分出不同身份, 程序打印不同结果.
if (num == 1) {
System.out.println("会员身份");
} else if (num == 2) {
System.out.println("非会员身份");
} else {
System.out.println("您的输入有误");
}
6.2.4 练习:考试奖励
需求:
小明快要期末考试了,小明爸爸对他说,会根据他不同的考试成绩,送他不同的礼物。
假如你可以控制小明的得分,请用程序实现小明到底该获得什么样的礼物,并在控制台输出。
分析:
①小明的考试成绩未知,可以使用键盘录入的方式获取值
②由于奖励种类较多,属于多种判断,采用if...else...if格式实现
③为每种判断设置对应的条件
④为每种判断设置对应的奖励
代码示例:
// 1. 键盘录入考试成绩
Scanner sc = new Scanner(System.in);
System.out.println("请输入您的成绩:");
int score = sc.nextInt();
// 2. 由于奖励种类较多,属于多种判断,采用if...else...if格式实现
// 3. 为每种判断设置对应的条件
if(score >= 95 && score <= 100){
// 4. 为每种判断设置对应的奖励
System.out.println("山地自行车一辆");
}else if(score >= 90 && score <= 94){
System.out.println("游乐场玩一次");
}else if(score >= 80 && score <= 89){
System.out.println("变形金刚玩具一个");
}else{
System.out.println("挨顿揍");
}
问题分析:
如果分数是小于0或者大于100的都是挨顿揍,这个不合理。
所以我们要过滤非法数据。
第一种改写方式:
// 1. 键盘录入考试成绩
Scanner sc = new Scanner(System.in);
System.out.println("请输入您的成绩:");
int score = sc.nextInt();
// 2. 由于奖励种类较多,属于多种判断,采用if...else...if格式实现
// 3. 为每种判断设置对应的条件
if(score < 0 || score > 100){
System.out.println("您的成绩输入有误");
}else if(score >= 95 && score <= 100){
// 4. 为每种判断设置对应的奖励
System.out.println("山地自行车一辆");
}else if(score >= 90 && score <= 94){
System.out.println("游乐场玩一次");
}else if(score >= 80 && score <= 89){
System.out.println("变形金刚玩具一个");
}else{
System.out.println("挨顿揍");
}
第二种改写方式:
Scanner sc = new Scanner(System.in);
System.out.println("请输入您的成绩:");
int score = sc.nextInt();
if (score >= 0 && score <= 100) {
// 正确的成绩
if (score >= 95 && score <= 100) {
System.out.println("山地自行车一辆");
} else if (score >= 90 && score <= 94) {
System.out.println("游乐场玩一次");
} else if (score >= 80 && score <= 89) {
System.out.println("变形金刚玩具一个");
} else {
System.out.println("挨顿揍");
}
} else {
// 错误的成绩
System.out.println("您的成绩输入有误");
}
6.4 Switch语法:
没有break具有穿透现象
switch(表达式) {
case n:
代码块
break;
case n:
代码块
break;
default:
默认代码块
}
复制代码
实例:
switch (new Date().getDay()) {
case 0:
day = "星期天";
break;
case 1:
day = "星期一";
break;
case 2:
day = "星期二";
break;
case 3:
day = "星期三";
break;
case 4:
day = "星期四";
break;
case 5:
day = "星期五";
break;
case 6:
day = "星期六";
}
复制代码
但是如果case判断的不是一个值,而是一个范围值呢?
其实也简单,语法就得变化一下,参数不能写在switch里面,而是定义在外面,如下
// 判断方位
var direction = 45;
switch (true) {
case angle==0:
direction = '正北'; break;
case angle==90:
direction = '正东'; break;
case angle==180:
direction = '正南'; break;
case angle==270:
direction = '正西'; break;
case angle==360:
direction = '正北'; break;
case (angle>0 && angle<90):
direction = '东北'; break;
case (angle>90 && angle<180):
direction = '东南'; break;
case (angle>180 && angle<270):
direction = '西南'; break;
case (angle>270 && angle<360):
direction = '西北'; break;
}
标签:语句,day03,System,运算符,int,println,out
From: https://blog.csdn.net/Darling912/article/details/143634764