二、流程控制
1.流程控制简介
程序在运行是,执行某一代码块,会有三种执行结构,分别为:顺序结构、分支结构、循环结构。
顺序结构:
代码从上到下,依次执行,这种执行结构是程序运行的基本结构。
分支结构:
代码执行到了某一个节点,遇到了多种继续执行的可能性,选择其中的一种继续向下执行。
循环结构:
某一段代码因为某种条件,需要重复执行多次。
程序的三大基本结构:顺序、分支(选择)、循环
2. 分支结构
2.1 if
基本语法:
if(boolean表达式){
code1: 表达式返回true,执行code1
}else{
code2: 表达式返回false,执行code2
}
if单分支语法:
if分支语句中,可以没有else语句块。
//....前置代码
if (boolean表达式){
//code1
}
//....后续代码
总结:
- 带有else语句块的分支结构,一定会执行某一条分支。
- 不带else语句块的分支结构,可能一条分支都不执行。
- if分支结构不可能执行多条分支。
if多分支结构:
if(表达式1){
code1
}else if(表达式2){
code2
}else if(表达式3){
code3
}
......
else{code4
}
练习代码:
package com.basic.day03.branch;
import java.util.Scanner;
/**
* 使用Scanner从控制台上扫描一个整数num
* 逻辑:
* 如果num<0 或者 num>100 提示: 输入有误
* 如果 >=90 输出: 优秀
* 如果 >= 80 输出: 良好
* 如果 >= 60 输出: 及格
* 如果 < 60 输出: 不及格
*/
public class _03IfDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个整数");
int num=sc.nextInt();
if (num<0||num>100){
System.out.println("输入错误");
} else if (num>=90) {
System.out.println("优秀");
} else if (num>=80) {
System.out.println("良好");
} else if (num>=60) {
System.out.println("及格");
}else{
System.out.println("不及格");
}
sc.close();
}
}
2.2 switch和case
语法:
switch(变量|具有返回值的表达式){
case 值1: code1;
case 值2: code2;
......
default: codeN;
}
解析:
1. 变量|具有返回值的表达式: 只能是byte,short,char,int,String,枚举这些类型的表达式或者变量。
2. 执行逻辑:会使用变量或表达式的值,与每一个case后的值,一一做比较。如果碰到完全相等的值,就执行对应的case后的代码块,
3. 上述语法,具有分支穿透效果。如果选择了一个case分支,那么除了该分支执行完后,还要继续向下执行其他的所有分支。
4. 如果带有default这个分支,那么如果其他case都没有对比上,则执行default分支。
5. 如果不想要穿透效果,那就在case分支后,添加break关键字。
代码应用:
public class _06SwitchCaseDemo {
public static void main(String[] args) {
// 随机一个整数:[0,4]
int num= (int)(Math.random()*5);
switch (num){
case 0:
System.out.println("随机的是0");break;
case 1:
System.out.println("随机的是1");
case 2:
System.out.println("随机的是2");break;
case 3:
System.out.println("随机的是3");break;
default:
System.out.println("随机的是4");
}
System.out.println("---main方法结束---");
}
}
代码解析:如果进入了case1,那么case2的输出流也会执行,然后遇到break停止。如果前面case都没有适合的,就会执行default,default不需要添加break。因为已经结束了,添加多余了。
2.3if和switch的比较
如果分支的条件,是一个范围,使用if。
如果分支的条件,是一个值,可以使用if,也可以使用switch。
2.4分支结构练习题
题目:输入年月,输出所输入的年的月份有多少天。
推荐写法:
package com.basic.day04.branch;
import java.util.Scanner;
public class Exercise02 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入年份:");
int y = sc.nextInt();
System.out.println("请输入月份:");
int m = sc.nextInt();
String str = "";
boolean flag = false;
int days=-1;
if(y%4==0&&y%100!=0||y%400==0) {
str = "是闰年";
flag = true;
}
else{
str="不是闰年";
}
switch (m){
case 1:case 3:case 5:case 7:case 8:case 10:case 12:
days=31;break;
case 4:case 6:case 9: case 11:
days=30;break;
case 2:
if (flag){
days=29;
}else {
days=28;
}
}
System.out.println(y+str+y+"月份有"+days+"天");
}
}
运行结果截图:
整体思想,尽可能的合并语句,使代码简介,减少输出语句,将多条输出语句合并成一句。
3.循环结构
循环(Loop)是一种控制结构,它允许程序重复执行某段代码块多次,直到满足某个条件为止。循环是编程中非常基础且强大的概念,用于处理重复任务,如遍历数组或列表、重复执行直到满足特定条件等。
循环三要素:
循环三要素:
- 循环因子的声明和初始化
- 循环条件
- 循环步长: 循环因子向着循环结束的方向而改变。
3.1 for循环
循环结构之for循环:通常用于在知道需要重复执行代码块的确切次数时使用。它包含了初始化、条件判断和循环步长三个步骤,但这些都包含在循环的声明中。
1 2 3
for(循环因子的声明和初始化;循环条件;循环步长){
4
//循环体
}
执行逻辑:
成立 成立 不成立
1-->2-->4-->3-->2-->4-->3-->2-->结束
练习1:
public class _01ForDemo {
public static void main(String[] args) {
//使用for循环打印十次hello world。
for (int i = 1; i <= 10; i++) {
System.out.println("hello world" );
}
// //使用for循环打印1~10
for (int i=1;i<=10;i++) {
System.out.println(i);
}
//使用for循环打印20以内的偶数,2~20
for (int i=1;i<=10;i++) {
System.out.print(i*2+" ");
}
}
}
结果就不贴图啦。就是输出题干要求的。注意print输出不换行,println输出换行。
练:2:
public class _02ForDemo {
public static void main(String[] args) {
// System.out.println("hello");
//使用for循环计算1~100的和
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum+=i;
}
System.out.println(sum);
}
}
结果:
for循环的特殊写法:
- for循环的小括号里,除了分号,其他都可以省略
- 循环因子的声明和初始化,可以写在for循环之前。
- 循环步长,可以写在循环体中
- 循环条件可以不写,默认是true。(就是会发生死循环)
具体看下面练习代码:
public class _03ForDemo {
public static void main(String[] args) {
// //下面的写法,三部分都省略了,中间的循环条件也省略了,相当于true.即死循环,程序要尽量避死循环。
// for (;;){
// System.out.println("Hello World");
// }
//循环因子的声明和初始化写在了for循环之前
int i = 1;
for(;i<=10;i++) {
System.out.println(i);
}
//循环步长,写在循环体内
for (int m = 1;m<=10;) {
System.out.println(m);
m+=3;
}
//循环体中只有一层代码时,可以省略花括号。
for (int n = 1;n<=10;)
System.out.println(n);
int x=1;
int y=2;
//if分支里只有一行代码时,可以省略花括号。
if(x==y)
System.out.println("相等");
else
System.out.println("不相等");
}
}
3.2 while循环
循环结构之while循环
当需要在满足某个条件时重复执行代码块,但不知道需要执行多少次时使用。循环开始前进行条件判断,如果条件为真,则执行循环体,并在循环体执行完毕后进行迭代,然后再次进行条件判断。
语法结构:
while(循环条件){
//循环体
}
代码用例
import java.util.Scanner;
public class _04WhileDemo {
public static void main(String[] args) {
//使用while循环打印五次hello world。
int i = 1;
while(i <= 5){
System.out.println("hello world");
i++; //循环要素之循环步长,写在了循环体中。
}
//需求二 使用while循环打印一百以内的内被5整除的数字
int n=1;
while(n<101){
if(n%5==0)
System.out.println(n);
n++;
}
//需求三:使用while循环,计算1~100以内的能被3整除的数字之和
n=1;
int sum=0;
while(n<101){
if(n%3==0)
sum=sum+n;
n++;
}
System.out.println("一百以内能被三整除的数字之和:"+sum);
//需求4: 使用while循环,判断一个整数,是几位数.
sum=0;
Scanner sc = new Scanner(System.in);
System.out.println("输入一个数字");
long s=sc.nextLong();
long s1=s;
while(s>0){
s/=10;
sum++;
}
System.out.println(s1+"是"+sum+"位数");
}
}
需求4结果:
3.3 do-while循环
循环结构之do-while循环:类似于while循环,但至少会执行一次循环体,因为条件判断是在循环体执行之后进行的。
语法结构:
do{
}while(循环条件);
特点:先执行一次循环体,然后再判断循环条件是否成立循环条件成立,再执行循环体。
代码演示(for循环演示ATM机输入密码操作):
import java.util.Scanner;
public class _05DoWhileDemo {
public static void main(String[] args) {
// 使用for/while 来完成模拟ATM机输入密码操作,5次不正确,就结束循环
String ealPWD="123456";
boolean flag=false;
Scanner sc = new Scanner(System.in);
for (int i=0;i<5;i++){
System.out.print("Enter password: ");
String password = sc.nextLine();
if (password.equals(ealPWD)){
System.out.println("Password Match");
flag =true;
break;
}
}
if (!flag){
System.out.println("Password Do Not Match");
}
}
}
结果:输入正确密码结束,输入错误五次密码会提示不匹配,然后运行结束。
代码演示(do-while结构演示输入密码操作,但没有次数限制)
import java.util.Scanner;
public class _06DoWhileDemo {
public static void main(String[] args) {
String realPWD="123456";
Scanner sc = new Scanner(System.in);
String PWD="";
do{
System.out.println("请输入密码");
PWD = sc.nextLine();
}while (!PWD.equals(realPWD));
}
}
结果:输入正确密码后结束,不然会一直重复输入密码操作。
总结:
for,while,do-while的应用场景或者区别
- for 循环适合需要循环次数的场景
- while 循环适合不知道循环次数的场景
- do-while适合先执行循环体,在判断条件的场景。比如做一件事,直到什么时候结束。
3.4 break关键字
循环结构之关键字break:break
关键字是一个非常重要的控制流语句,它用于立即退出当前所在的循环体(无论是 for
循环、while
循环还是 do-while
循环),并且继续执行循环之后的下一条语句。break
通常与条件语句(如 if
)一起使用,以在满足特定条件时跳出循环。
break:打断,毁坏的含义
再循环结构中,表示打断,结束循环,继续向下执行后续代码
break只能结束他所在的循环,离他最近的循环。
代码练习(猜数字游戏):
public class _07BreakDemo {
public static void main(String[] args) {
// 从1开始打印到一百,如果遇到到10,就结束循环。
for (int i = 1; i <= 100; i++) {
if (i==10)
break;
System.out.println(i);
}
//猜数字游戏的模拟
Scanner sc = new Scanner(System.in);
int answer = (int) (Math.random()*10);
while(true) {
System.out.println("猜测的数字:");
int input = sc.nextInt();
if (input==answer)
break;
else if (input>answer)
System.out.println("猜大了");
else
System.out.println("猜小了");
}
System.out.println("you win!");
}
}
结果展示:
3.5 continue关键字
continue关键字用于跳过当前循环迭代中的剩余代码,并强制循环进入下一次迭代(对于for循环,就是下一个元素的迭代;对于while循环,就是回到循环条件的判断)。
这意味着,如果在循环体中遇到continue语句,那么从continue语句之后到循环体末尾的所有代码都将被忽略,循环会立即进行下一次迭代(如果条件允许的话)。
测试用例:
public class _08ContinueDemo {
public static void main(String[] args) {
//需求1:计算100以内的偶数之和,排除50。
int sum = 0;
for (int i = 2; i <=100; i+=2) {
if(i==50)
continue;
sum += i;
}
System.out.println(sum);
}
}
结果说明:当循环到五十的时候,会直接跳过这一次的加和,然后进行下一次循环加51。所以最终结果为2500。
3.6综合应用(循环嵌套)
循环的嵌套:
1.循环结构是可以进行多层次嵌套的
2.生产环境中(做开发时),尽量不要使用循环的嵌套,因为非常消耗性能
执行逻辑
外层循环执行一次,内层循环执行一遍。(从开始到结束)
public class _09NextOfLoop {
public static void main(String[] args) {
//案例,启动!
/* for (int i = 0; i <10 ; i++) {
System.out.println("i"+i);
for (int j = 0; j <10 ; j++) {
System.out.println("j"+j);
}
}*/
// System.out.println("----循环结束----");
//使用输出语句打印一个*,打出图形如下
// *****
// *****
// *****
// *****
// *****
for (int i = 0; i < 5; i++) {
for(int j = 0; j < 5; j++){
System.out.print("*");
}
System.out.println();
}
// for (int i = 0; i < 5; i++) {
// for(int j = 4-i; j>0; j--){
// System.out.print(" ");
// }
// for(int j = 0; j <=i; j++){
// System.out.print("*");
// }
// System.out.println();
// }
//案例3 判断57是不是质数 质数:只能被1和它本身整除的数
boolean flag = true;
for (int i = 2; i <Math.sqrt(57) ; i++) {
if(57%i==0){
flag = false;
System.out.println("不是质数");
break;
}
}
if(flag){
System.out.println("是质数");
}
//输出一百以内所有的素数。
for (int i = 2; i <=100 ; i++) {
flag=true;
for(int j = 2; j<=Math.sqrt(i); j++){
if(i%j==0){
flag=false;
break;
}
}
if(flag){
System.out.println(i);
}
}
}
}
结果就不展示了,注意最后判断素数时的范围是sqrt(那个数),因为求素数到他的开方就够了。