流程控制
1.1 概述
在一个程序的执行过程中,各条语句的执行顺序对程序的结果是有直接影响的,也就是说,程序的流程对运行结果有直接的影响,所以很多时候我们要通过控制语句的执行顺序来实现我们要实现的功能。
1.2 顺序结构
1.2.1 概述
根据语句顺序,从上到下依次执行。
1.2.3 案例
源代码:
public class ProcessControlTest {
public static void main(String[] args) {
/**
* 顺序结构,从上往下依次执行
* 练习:求两个整数的和
*
* System.out.printf:格式化输出,%d代表整型占位符
*/
int num1 = 1320;
int num2 = 519;
System.out.printf("%d + %d = %d",num1,num2,num1 + num2);
}
}
输出结果:
1.3 选择结构
1.3.1 if判断语句
格式:
if (关系表达式){
语句块;
}
说明:
1.当关系表达式为 真 时,才执行语句块,否则跳过语句块;
2.语句块可以是一条或者多条,一条时可以省略花括号,但是为了代码结构美观以及写多条时忘加而导致程序超出预期,建议平时写代码时都加上,养成良好的代码编写习惯。
1.3.1.1 案例
源代码:
public class ProcessControlTest {
public static void main(String[] args) {
/**
* 选择结构:if判断语句
* 练习:判断一个整数是否在0到100之间,如果是则打印输出
*/
int num1 = 99;
int num2 = 989;
//num1满足表达式条件,所以会打印输出
if (num1 >= 0 && num1 <= 100)
System.out.println("num1 = " + num1);
/**
* num2不满足表达式条件,本不应该输出,但是if后面有一个分号; 而分号也是一个完整的表达式
* 如果 条件表达式 为true,会执行这个分号,然后打印num2
* 如果 条件表达式 为false,不会执行这个分号,然后打印num2
* 这样,看上去无论如何都会打印num2,那这个条件就没有意义了,
* 这是初学者比较容易踩的坑,if语句后是不需要加分号的,但是加了也不会报错,所以要格外注意。
*/
if (num2 >= 0 && num2 <= 100);
System.out.println("num2 = " + num2);
}
}
输出结果:
1.3.2 if…else判断语句
格式:
if (关系表达式){
语句块1;
}else{
语句块2;
}
说明:
1.当 关系表达式 的结果为 真时,执行 语句块1, 否则,执行 语句块2,二者必选其一。
1.3.2.1 案例
源代码:
public class ProcessControlTest {
public static void main(String[] args) {
/**
* 选择结构:if…else判断语句
* 练习:定义一个整数(年份),判断这一年是否为闰年,满足下列条件之一都是闰年:
* 1. 如果能够被4整除,但是不能被100整除
* 2. 能够被400整除
*/
int year = 1999;
if((year % 4 == 0 && year % 100 != 0)
|| (year % 400 == 0)) {
System.out.println(year + "是闰年!");
}else {
System.out.println(year + "不是闰年!");
}
}
}
输出结果:
1.3.3 if…else if…else判断语句
格式:
if (关系表达式1){
语句块1;
}else if (关系表达式2){
语句块2;
}else if (关系表达式3){
语句块3;
}else{
语句块4;
}
说明:
1.当 关系表达式1 为真时,执行 语句块1 后跳出该语句,否则继续判断;
当 关系表达式2 为真时,执行 语句块2 后跳出该语句,否则继续判断;
当 关系表达式3 为真时,执行 语句块3 后跳出该语句,否则继续执行;
当 所有表达式 都不为真时,执行 语句块4后跳出该语句。
2.从上往下判断,执行满足条件的语句块,多者选其一,比起单独写多个if语句,这种写法性能更优。
1.3.3.1 案例
源代码:
public class ProcessControlTest {
public static void main(String[] args) {
/**
* 选择结构:if…else if…else判断语句
* 练习:定义两个double类型的变量,赋值你的身高体重,并计算出你的BMI值是多少,BMI的计算公式是 体重(kg) / (身高*身高)m
* 1. 体重过轻:BMI < 18.5
* 2. 正常范围:18.5 <= BMI < 24
* 3. 体重过重:24 <= BMI < 27
* 4. 轻度肥胖:27 <= BMI < 30
* 5. 中度肥胖:30 <= BMI < 35
* 6. 重度肥胖:35 <= BMI
*/
double weight = 52.4;
double height = 1.68;
double bmi = weight / (height * height);
if(bmi < 18.5) {
System.out.println("你的BMI = " + bmi + ",体重过轻!");
}else if(bmi < 24 && bmi >= 18.5) {
System.out.println("你的BMI = " + bmi + ",正常范围!");
}else if(bmi < 27 && bmi >= 24) {
System.out.println("你的BMI = " + bmi + ",体重过重!");
}else if(bmi < 30 && bmi >= 27) {
System.out.println("你的BMI = " + bmi + ",轻度肥胖!");
}else if(bmi < 35 && bmi >= 30) {
System.out.println("你的BMI = " + bmi + ",中度肥胖!");
}else {
System.out.println("你的BMI = " + bmi + ",重度肥胖!");
}
}
}
输出结果:
1.3.4 switch选择语句
格式:
switch (表达式){
case 常量值1:语句体1;break;
case 常量值2:语句体2;break;
……
case 常量值n:语句体n;break;
default:语句体n+1:break;
}
说明:
1.当 表达式的值 和 case后的常量值 相等时,执行后面对应的语句体;
如果没有符合条件的常量值,则执行default后的语句体。
注意事项:
1.switch后面的小括号当中只能是基本数据类型(byte、short、char、int)和引用数据类型(String、enum);
2.switch语句格式可以很灵活,前后顺序可以颠倒,而且break语句还可以省略;
3.但是还是建议每个case后面都应该加一个break;,表明退出switch语句;如果没有加,那会从满足条件的case开始,从上往下执行直到遇到break或者整体结束为止,这就违背了写switch语句的初衷,直接采用顺序结构即可。
1.3.4.1 案例
源代码:
import java.util.Scanner;
public class ProcessControlTest {
public static void main(String[] args) {
/**
* 选择结构:switch选择语句
* 练习:从键盘输入一个整数(月份),判断是哪个季节。
*/
Scanner scanner = new Scanner(System.in);
System.out.println("请输入月份:");
int season = scanner.nextInt();
switch (season) {
case 3:
case 4:
case 5:
System.out.println("春季!");break;
case 6:
case 7:
case 8:
System.out.println("夏季!");break;
case 9:
case 10:
case 11:
System.out.println("秋季!");break;
case 12:
case 1:
case 2:
System.out.println("冬季!");break;
default:
System.out.println("输入的季节有误!");
break;
}
}
}
输出结果:
1.3.5 Scanner类
在前面的学习中,知道使用System.out.println()输出数据到控制台,但是在上面的1.3.4.1 案例中,需要从控制台输入数据,所以需要用到Scanner类,后续也会频繁使用,所以在这里简单介绍下如何使用该类读取控制台输入的数据。
注意:使用该类时,要在类上面的导包处,写上:import java.util.Scanner;具体看1.3.4.1 案例,表示导入该类,才不会编译报错。
1.3.5.1 使用Scanner读取整数
Scanner s = new
Scanner(System.in);
int
a = s.nextInt();//读整数
1.3.5.2 使用Scanner读取浮点数
Scanner s = new
Scanner(System.in);
float
a = s.nextFloat();//读浮点数
1.3.5.3 使用Scanner读取字符串
Scanner s = new
Scanner(System.in);
String a = s.nextLine();//读字符串
注意:如果在读实际字符串之前,输入过回车换行符,也会被当做字符串来接收,所以这时候要接收两次才行,第二次才是实际输入的字符串。
1.4 循环结构
1.4.1 概述
循环结构的基本组成部分,一般可以分为四个部分:
- 初始化语句:在循环开始最初执行,而且只做唯一一次;
- 条件判断:如果成立,则循环继续,如果不成立,则循环退出;
- 循环体:重复要做的事情内容,若干条语句;
- 步进语句:每次循环之后都要进行的扫尾工作,每次循环结束之后都要执行一次。
1.4.2 while循环
格式:
初始化语句;
while(条件表达式){
循环体;
步进语句;
}
说明:
1.当 条件表达式 为真时,执行 循环体+步进语句,接着循环判断 条件表达式和执行循环体+步进语句,直到 条件表达式 为假时,退出循环。
注意事项:
1.条件表达式 一定要有结束循环的条件,否则就会造成死循环,导致程序崩溃。
1.4.2.1 案例
源代码:
import java.util.Scanner;
public class ProcessControlTest {
public static void main(String[] args) {
/**
* 循环结构,while循环
* 练习:通过Scanner 获取一个整数,然后使用while计算这个整数的阶乘:5! = 5 * 4 * 3 * 2 * 1
*/
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个整数:");
int n = sc.nextInt();//接收控制台输入的整数
int sum = 1;
while(n >= 1) {
sum *= n--;
}
System.out.println(sum);
}
}
输出结果:
1.4.3 do…while循环
格式:
初始化语句;
do{
循环体;
步进语句;
} while(条件表达式)
说明:
1.不做任何判断,先执行一次,然后就和while循环类似了,循环判断条件表达式,执行循环体+步进语句,直到条件表达式为假时退出循环。
1.4.3.1 案例
源代码:
public class ProcessControlTest {
public static void main(String[] args) {
/**
* 循环结构,do-while循环
* 练习:打印0到9
*/
int i = 0;
do{
System.out.println(i);
i++;
} while(i < 10);
}
}
输出结果:
1.4.4 for循环
格式:
for(初始化语句;条件判断;步进语句){
循环体;
}
说明:
1.先执行 初始化语句,整个循环过程中只会执行一次;
2.然后执行条件判断,如果成立,执行 循环体,最后执行 步进语句,这三步会循环执行,直到条件判断不成立后退回循环。
1.4.4.1 案例
源代码:
public class ProcessControlTest {
public static void main(String[] args) {
/**
* 循环结构,for循环
* 练习:寻找所有的水仙花数,水仙花数定义:
* 1. 一定是3位数
* 2. 每一位的立方,加起来恰好是这个数本身,比如153=1*1*1+5*5*5+3*3*3
*/
for(int i = 100; i < 1000; i++) {
int a = i / 100; //百位
int b = i / 10 % 10; //十位
int c = i % 10; //个位
if((a*a*a + b*b*b + c*c*c) == i) {
System.out.println("水仙花数:" + i);
}
}
}
}
输出结果:
1.4.5 三种循环的区别
- 不管条件判断是否成立,do…while循环至少执行一次,但是条件判断如果不成立,则while循环和for循环一次都不会执行;
- for循环的变量在小括号当中定义,只有循环内部才可以使用,while循环和do…while循环的初始化语句定义在循环外面,所以退出循环之后还继续使用。
1.4.6 条件控制语句:break
- 可以在switch语句当中使用,一旦执行,整个switch语句立即结束;
- 可以在循环语句当中使用,一旦执行,最内层的整个循环语句立即结束,打断循环。
1.4.6.1 案例
源代码:
public class ProcessControlTest {
public static void main(String[] args) {
/**
* 循环控制语句:continue
* 练习:打印单数,如果是双数,直接结束循环
*/
for (int j = 1; j < 10; j++) {
if(j % 2 == 0)
break;
System.out.println(j);
}
}
}
输出结果:
1.4.7 循环控制语句:continue
- 此语句一旦执行,立即跳过当前次循环剩下内容,马上开始下一次循环。
1.4.7.1 案例
源代码:
public class ProcessControlTest {
public static void main(String[] args) {
/**
* 循环控制语句:continue
* 练习:打印 1-100 之间的数,如果这个数,要么是3,要么5的倍数,就忽略掉
*/
for (int i = 1; i < 21; i++) {
if(i % 3 == 0 || i % 5 == 0){
continue;
}
System.out.println(i);
}
}
}
输出结果:
1.4.8 死循环
格式:
while(true){
循环体;
}
说明:
1.因为条件表达式一直为true,所以程序永远无法自动停止,造成死循环;
2.在控制台手动执行死循环,使用快捷键:Ctrl+C。
1.4.9 循环嵌套
指一个循环的循环体是另一个循环,总共循环次数=外循环次数*内循环次数。
格式:
for(初始化语句①;条件判断②:步进语句⑧){
for(初始化语句③;条件判断④:步进语句⑦){
循环体⑥;
}
}
说明:
1.执行顺序分别是①到⑧,步骤①和③只在每次循环开始前执行一次;
2.外循环一次,内循环一轮。
1.4.9.1 案例
源代码:
public class ProcessControlTest {
public static void main(String[] args) {
/**
* 循环嵌套
* 练习-小学算术题,同时满足下列条件:
* a + b == 8
* a + c == 14
* b + d == 10
* c - d == 6
*/
for(int a = 0 ;a <= 14; a++) {
for(int b = 0; b <= 14; b++) {
for(int c = 0; c <= 14; c++) {
for(int d = 0; d <= 14; d++) {
if(a + b == 8 && a + c == 14 && b + d == 10 && c - d == 6) {
System.out.println("a = " + a + ", b = " + b + ", c = " + c + ", d = " + d);
}
}
}
}
}
}
}
输出结果:
题外话:
如果文章中存在错误的地方,欢迎大家指正出来,共同学习进步,后续会陆续就JAVA这门课程展开进行分享。