Java学习笔记_第一阶段_1.6 控制结构
1.6 控制结构
在程序中,程序运行的流程控制决定程序是如何执行的,是我们必须掌握的,主要有三大流程控制语句。
- 顺序控制
- 分支控制
- 循环控制
顺序
-
顺序控制介绍
程序从上到下逐行地执行,中间没有任何判断和跳转
graph TD A(执行语句1)-->B(执行语句2) B-->C(......) C-->执行语句n -
顺序控制举例和注意事项
Java中定义变量时采用合法的前向引用。如
public class Test { int num1 = 12; int num2 = num1 + 2; }
错误形式:
public class Test { int num2 = num1 + 2;//错误 int num1 = 12; }
分支(if-else, switch)
if-else
-
分支控制if-else介绍
让程序有选择的执行,分支控制有三种
- 单分支
- 双分支
- 多分支
-
单分支
基本语法:
if(条件表达式){ 执行代码块;//可以有多条语句 }
说明:
- 当条件表达式为true时,就会执行{}的代码,如果为false,就不执行
- 如果{}中只有一条语句,则可以不用{},建议写上{}
例:编写一个程序,可以输入人的年龄,如果该同志的年龄大于18岁,则输出“你的年龄大于18,要对自己的行为负责,送入监狱”
import java.util.Scanner; public class If01 { public static void main(String[] args) { Scanner myScanner = new Scanner(System.in); System.out.println("请输入年龄:"); int age = myScanner.nextInt(); if(age > 18) { System.out.println("你的年龄大于18,要对自己的行为负责,送入监狱"); } System.out.println("程序继续..."); } }
单分支对应的流程图(描述程序执行流程):
graph TD S[开始]-->A{条件表达式} A--T-->B[代码块] B-->C[继续] A--F-->C -
双分支
基本语法:
if(条件表达式){ 执行代码块1; } else { 执行代码块2; }
说明:
- 当条件表达式成立,即执行代码块1,否则执行代码块2
- 如果执行代码块只有一条语句,则{}可以省略,否则不能省略
例:编写一个程序,可以输入人的年龄,如果该同志的年龄大于18岁,则输出“你的年龄大于18,要对自己的行为负责,送入监狱”,否则,输入“你的年龄不大这次放过你了”
import java.util.Scanner; public class If02 { public static void main(String[] args) { Scanner myScanner = new Scanner(System.in); System.out.println("请输入年龄:"); int age = myScanner.nextInt(); if(age > 18) { System.out.println("你的年龄大于18,要对自己的行为负责,送入监狱"); } else { System.out.println("你的年龄不大这次放过你了"); } System.out.println("程序继续..."); } }
双分支对应的流程图:
graph TD S[开始]-->A{条件表达式} A--T-->B1[代码块1] B1-->C[继续] A--F-->B2[代码块2] B2-->C[继续] -
多分支
基本语法:
if(条件表达式1){ 执行代码块1; } else if(条件表达式2){ 执行代码块2; } ... else { 执行代码块n; }
说明:
- 当条件表达式1成立时,即执行代码块1
- 当条件表达式1不成立时,才去判断表达式2是否成立``
- 如果表达式2成立,就执行代码块2
- 以此类推,如果所有的表达式都不成立,则执行else的代码块,注意,只能有一个执行入口
- 多分支可以没有else
多分支对应的流程图
例:输入保国同志的芝麻信用分:如果
- 信用分为100分时,输出信用极好
- 信用分为(80,99]时,输出信用优秀
- 信用分为[60,80]时,输出信用一般
- 其他情况,输出信用不及格
- 请从键盘输入保国的芝麻信用分,并加以判断
import java.util.Scanner;
public class Ex01 {
public static void main(String[] args) {
Scanner myScanner = new Scanner(System.in);
//接收用户输入
System.out.println("请输入信用分(1-100):");
int grade = myScanner.nextInt();
//先对输入的信用分,进行一个范围的有效判断 1-100,否则提示输入错误
if(grade >= 1 && grade <= 100){
//因为有4中情况,所以使用多分支
if(grade == 100) {
System.out.println("信用极好");
} else if (grade > 80 && grade <= 99){
System.out.println("信用优秀");
} else if (grade >= 60 && grade <= 80){
System.out.println("信用一般");
} else {
System.out.println("信用不及格");
}
} else {
System.out.println("信用分需要在1-100,请重新输入:)");
}
}
}
-
嵌套分支
-
基本介绍
在一个分支结构中又完整的嵌套了另一个完整的分支结构,里面的分支的结构称为内层分支,外面的分支结构称为外层分支。规范:不要超过3层(可读性不好)
-
基本语法
if(){ if(){ //if-else... } else { //if-else... } }
例1:参加歌手比赛,如果初赛成绩大于8.0进入决赛,否则提示淘汰。并且根据性别提示进入男子组或女子组。输入成绩和性别,进行判断和输出信息。
import java.util.Scanner; public class Ex02 { public static void main(String[] args) { Scanner myScanner = new Scanner(System.in); //接收用户输入 System.out.println("请输入该歌手的成绩:"); double score = myScanner.nextDouble(); if(score > 8.0) { System.out.println("请输入该歌手的性别:"); char gender = myScanner.next().charAt(0); if(gender == '男') { System.out.println("进入男子组"); } else if(gender == '女') { System.out.println("进入女子组"); } else { System.out.println("你的性别有误,不能参加比赛~"); } } else { System.out.println("sorry,你被淘汰了~"); } } }
例2:出票系统:根据淡旺季的月份和年龄,打印票价。
- 4-10旺季:成人(18-60):60;儿童(<18):半价;老人(>60):1/3;
- 淡季:成人:40;其他:20;
import java.util.Scanner; public class Ex03 { public static void main(String[] args) { Scanner myScanner = new Scanner(System.in); System.out.println("请输入月份:"); int month = myScanner.nextInt(); System.out.println("请输入年龄:"); int age = myScanner.nextInt(); if(month >= 4 && month <= 10) { if(age >= 18 && age <= 60) { System.out.println("票价为60"); } else if(age < 18){ System.out.println("票价为30"); } else { System.out.println("票价为20"); } } else { if(age >= 18 && age <= 60) { System.out.println("票价为40"); } else{ System.out.println("票价为20"); } } } }
-
switch
-
switch分支结构
-
基本语法
switch(表达式){ case 常量1: 语句块1; break; case 常量2: 语句块2; break; ... case 常量n: 语句块n; break; default: default语句块; break; }
- switch关键字,表示switch分支
- 表达式对应一个值
- case常量1:当表达式的值等于常量1,就执行语句块1
- break:表示退出switch
- 如果和case常量1匹配,就执行语句块2,如果没有匹配,就继续匹配case常量2
- 如果一个都没有匹配上,执行default
-
switch流程图
graph TD A[计算表达式的值]-->B1{等于常量1} B1--True-->C1[执行语句块1] C1-->D1{是否有break} D1--有-->E(结束switch) B1--false-->B2{等于常量2} B2--True-->C2[执行语句块2] D1--没有-->C2 C2-->D2{是否有break} D2--有-->E B2--False-->B3{等于常量n} B3--True-->C3[执行语句块n] D2--没有-->C3 C3-->D3{是否有break} D3--有-->E B3--False-->C4[default语句块] D3--没有-->C4 C4-->E
例:编写一个程序,该程序可以接受一个字符,比如:a,b,c,d,e,f,g
- a表示星期一,b表示星期二...
- 根据用户的输入显示相应的信息,要求用switch语句完成
import java.util.Scanner; public class Ex04 { public static void main(String[] args) { Scanner myScanner = new Scanner(System.in); System.out.println("请输入一个字符(a-g):"); char c = myScanner.next().charAt(0); switch(c) { case 'a': System.out.println("今天星期一"); break; case 'b': System.out.println("今天星期二"); break; case 'c': System.out.println("今天星期三"); break; case 'd': System.out.println("今天星期四"); break; case 'e': System.out.println("今天星期五"); break; case 'f': System.out.println("今天星期六"); break; case 'g': System.out.println("今天星期日"); break; default: System.out.println("你输入的字符不正确,没有匹配的"); } System.out.println("推出了switch,继续执行程序"); } }
-
switch注意事项和细节讨论
-
表达式数据类型,应和case后的常量类型一致,或者是可以自动转成可以相互比较的类型,比如输入的是字符,而常量是int
char c = 'a'; switch(c){ case 'a': System.out.println("ok1"); break; case "hello"://错误 System.out.println("ok2"); break; case 20://ok System.out.println("ok3"); break; }
-
switch(表达式)中表达式的返回值必须是:(byte,short,int,char,enum[枚举],String)
double c = 1.1; switch(c){ case 1.1: System.out.println("ok3"); break; }
-
case子句中的值必须是常量或者是常量表达式,而不能是变量
-
default子句是可选的,当没有匹配的case时,执行default
-
break语句用来在执行完一个case分支后使程序跳出switch语句块;如果没有写break,程序会顺序执行到switch结尾,除非遇到break
-
-
switch和if的比较
- 如果判断的具体数值不多,而且符合byte,short,int,char,enum[枚举],String这6种类型。虽然两个语句都可以使用,建议使用switch语句。
- 其他情况:对区间判断,对结果为boolean类型判断,使用if,if的使用范围更广
循环(for, while, do while)
for循环控制
-
基本语法
for(循环变量初始化;循环条件;循环变量迭代){ 循环操作(可以多条语句); }
-
说明
- for关键字,表示循环控制
- for有四要素:(1)循环变量初始化;(2)循环条件;(3)循环操作;(4)循环变量迭代
- 循环操作,这里可以有多条语句,也就是我们要循环执行的代码
- 如果循环操作(语句)只有一条语句,可以省略{},建议不要省略
-
for循环流程图
graph TD 循环变量初始化-->B{循环条件} B--T-->C[循环操作语句] C-->D[循环变量迭代] D-->B B--F-->E[for循环结果] E-->继续 -
注意事项和细节说明
-
循环条件是返回一个布尔值的表达式
-
for(;循环判断条件;)中的初始值和变量迭代可以写到其他地方,但是两边的分号不能省略
int i = 1; for(;i <= 10;) { System.out.println("hello" + i); i++; }
for(;;)表示一个无限循环,死循环
-
循环初始值可以有多条初始化语句,但要求类型一样,并且中间用逗号隔开,循环变量迭代也可以有多条变量迭代语句,中间用逗号隔开
-
while循环控制
-
基本语法
循环变量初始化; while(循环条件){ 循环体(语句); 循环变量迭代; }
-
说明
- while循环也有四要素
- 只是四要素放的位置和for不一样
-
while循环流程图
graph TD 循环变量初始化-->B{循环条件} B--T-->C[循环体 循环变量迭代] C-->B B--F-->D(while结束) -
注意事项和细节说明
- 循环条件是返回一个布尔值的表达式
- while循环时先判断再执行语句
do while循环控制
-
基本语法
循环变量初始化; do{ 循环体(语句); 循环变量迭代; }while(循环条件);
-
说明
- do while是关键字
- 也有循环四要素,只是位置不一样
- 先执行,再判断,也就是说,一定会至少执行一次
- 最后有一个分号;
-
do while流程图
graph TD 循环结构初始化-->B[循环体语句...循环变量迭代] B-->C{循环判断} C--F-->D(退出do-while) C--T-->B -
注意事项和细节说明
- 循环条件是返回一个布尔值的表达式
- do...while循环是先执行,再判断,因此它至少执行一次
多重循环控制
- 介绍
- 将一个循环放在另一个循环体内,就形成了嵌套循环。其中,for,while,do...while均可以作为外层循环和内层循环。[建议一般使用两层,最多不要超过3层,否则,代码的可读性很差]
- 实质上,嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的循环条件为false时,才会完全跳出内层循环,才可结束外层的档次循环,开始下一次的循环
- 设外层循环次数为m次,内层为n次,则内层循环体实际上需要执行m*n次
break
例:随机生成1-100的一个数,直到生成了97这个数,看看一共用了多少次
提示:(int)(Math.random() * 100) + 1
Java生成随机数(random()和Random类) (biancheng.net)
public class Test {
public static void main(String[] args) {
for (int i = 1;i <= 100;i++) {
int num = (int)(Math.random() * 100) + 1;
if (num == 97) {
System.out.println(num);
break;
} else {
System.out.println(num);
System.out.println(i);
System.out.println("=========");
}
}
}
}
-
基本介绍
break语句用于终止某个语句块的执行,一般使用在switch或者循环[for,while,do-while]中
-
基本语法
{ ... break; ... }
-
注意事项和细节说明
-
break语句出现在多层嵌套的语句块中时,可以通过标签指明要终止的是哪一层语句块
-
标签的基本使用
lable1: for (int i = 1;i <= 4;i++){ label2: for(int j = 1;j <= 5;j++){ if(j == 3){ break label1; } System.out.println("i=" + i); } }
说明:
- break语句可以指定退出哪层
- label1是标签,名字由程序员指定
- break后指定到哪个label就退出到哪里
- 在实际的开发中,尽量不要使用标签
- 如果没有指定break,默认退出最近的循环体
-
continue
-
基本结束
- continue语句用于结束本次循环,继续执行下一次循环
- continue语句出现在多层嵌套的循环语句体中时,可以通过标签指明要跳过的是哪一层循环,这个和前面的标签的使用的规则一样
-
基本语法
{ ...; continue; ...; }
例1:
public class Continue01 {
public static void main(String[] args) {
int i = 1;
while(i <= 4) {
i++;
if(i == 2) {
continue;
}
System.out.println("i=" + i);
}//输出3 4 5
}
}
例2:
public class Continue02 {
public static void main(String[] args) {
label1:
for (int j = 0;j < 4;j++) {
label2:
for (int i = 0;i < 10;i++) {
if (i == 2) {
//continue;//输出四组0 1 3 4 5 6 7 8 9
//continue label2;//输出四组0 1 3 4 5 6 7 8 9
continue label1;//输出四组0 1
}
System.out.println("i=" + i);
}
}
}
}
return
-
介绍
return使用在方法,表示跳出所在的方法
注:如果return写在main方法,退出程序
例:
public class Return01 {
public static void main(String[] args) {
for (int i = 1;i <= 5;i++) {
if (i == 3) {
System.out.println("i=" + i);
return;
}
System.out.println("Hello.world");
}
System.out.println("go on...");
//输出Hello.world Hello.world i=3
}
}