java ——程序流程控制
✍作者:电子科大不知名程序员
🌲专栏:java学习指导
各位读者如果觉得博主写的不错,请诸位多多支持;如果有错误的地方,欢迎在评论区指出
目录
- java ——程序流程控制
- 分支结构
- if-else
- switch-case
- scanner
- 循环
- for 循环
- while 循环
- do-while 循环
- 嵌套循环
- break和continue
- break和continue
三种基本流程结构:顺序结构、分支结构、循环结构
分支结构
if-else
三种结构:
if(条件表达式){
执行代码块;
}
//二选一
if(条件表达式){
执行代码块1;
}
else{
执行代码块2;
}
//多选一
if(条件表达式1){
执行代码块1;
}
else if(条件表达式2){
执行代码块2;
}
......
else{
执行代码块n;
}
switch-case
1.格式
switch(表达式){
case 常量1:
语句1;
//break;
case 常量2:
语句2;
//break;
......
case 常量N:
语句N;
break;
default:
语句;
//break;
}
//break的意思是不一定要用break
public class SwitchCaseTest {
public static void main(String[] args) {
int number=2;
switch(number) {
case 0:
System.out.println("zero");
case 1:
System.out.println("one");
case 2:
System.out.println("two");
case 3:
System.out.println("three");
default:
System.out.println("other");
}
}
}
运行结果如下:
【说明】:
1.根据switch表达式中的值,一次匹配各个case中的常量,一旦匹配成功,进入相应case结构中,调用其执行语句,当调用完执行语句后,则仍然继续向下执行其它case结构中的执行语句,直到遇到break关键字或者switch-case末尾结束为止;
2.要想像if-else那样的多选一:需要在每一个case后加break;
break:可以使用在switch-case结构中,表示一旦执行到此关键字,就跳出switch-case结构;
3.switch结构中的表达式,只能是如下的6种数据类型之一:byte、short、char、int、枚举类型、String类型
boolean isRight=ture;
switch(isRight){ //wrong
......
}
4.case后放的是常量,不能作范围判断(相当于判断==)
5.break关键字在switch结构中是可选的(绝大多数情况要加)
6.default相当于if-else结构中的else中类型,当前面情况(case)都不满足时执行
default也是可选的,且位置是灵活的(用不到)
实例1:
import java.util.Scanner;
public class SwitchCase3 {
//对于学生成绩大于60分的,输出“合格”。低于60分的,输出不合格
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
int score_1=scan.nextInt();
int score_2=score_1/10;
switch(score_2) {
case 1:
case 2:
case 3:
case 4:
case 5:
System.out.println("Failed");
break;
case 6:
case 7:
case 8:
case 9:
case 10:
System.out.println("pass");
break;
}
}
}
优化:switch(score_1/60)——这样就分成了及格和不及格的两种情况了
实例2:
package my_first_java_code;
import java.util.Scanner;
public class SwitchCase4 {
public static void main(String [] args){
//编写程序:从键盘上输入2022年的月份和日期,通过程序求得这是2022的第几天
Scanner scan=new Scanner(System.in);
System.out.println("Please enter a month:");
int month=scan.nextInt();
System.out.println("Please enter a day:");
int day=scan.nextInt();
//定义一个变量来保存总天数
int sumDays=0;
/*方法1:过于的冗余
* switch(month) {
case 1:
sumDays=day;
case 2:
sumDays=31+day;
case 3:
...
}
*/
//方法2:我们不妨思考,因为我们到下个月的时候正好要将前面所有月的天数相加,因此不妨将前几个月的天数写在下面,那么没有break的情况下就会自动执行
switch(month) {
case 12:
sumDays+=30;
case 11:
sumDays+=31;
case 10:
sumDays+=30;
case 9:
sumDays+=31;
case 8:
sumDays+=31;
case 7:
sumDays+=30;
case 6:
sumDays+=31;
case 5:
sumDays+=30;
case 4:
sumDays+=31;
case 3:
sumDays+=28;
case 2:
sumDays+=31;
case 1:
sumDays=day;
}
System.out.println("2022年的第"+month+"月第"+day+"日是第"+sumDays+"天");
//注意用连接符连接
}
}
通过实例2:我们再次强调,break是可选的马,根据实际要求来
实例3:不仅仅考虑2022年,我们加入对年的思考——需要判断是否是闰年
import java.util.Scanner;
public class SwitchCaseTest5 {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
System.out.println("Please enter a year:");
int year=scan.nextInt();
System.out.println("Please enter a month:");
int month=scan.nextInt();
System.out.println("Please enter a day:");
int day=scan.nextInt();
//定义一个变量来保存总天数
int sumDays=0;
switch(month) {
case 12:
sumDays+=30;
case 11:
sumDays+=31;
case 10:
sumDays+=30;
case 9:
sumDays+=31;
case 8:
sumDays+=31;
case 7:
sumDays+=30;
case 6:
sumDays+=31;
case 5:
sumDays+=30;
case 4:
sumDays+=31;
case 3:
//根据是否是闰年来决定
//sumDays+=28;
if(year%4==0&&year%100!=0||year/400==0) {
sumDays+=29; //是闰年
}
else {
sumDays+=28; //不是闰年
}
case 2:
sumDays+=31;
case 1:
sumDays=day;
}
System.out.println(year+"年的第"+month+"月第"+day+"日是第"+sumDays+"天");
}
}
scanner
如何从键盘获取不同类型的变量:需要使用scanner类
具体实现步骤:
1.导包:import java.util.Scanner;
2.Scanner的实例化:Scanner scan=new Scanner(System.in);
3.调用Scanner类的相关方法:next()/nextXxx(),来获取指定类型的变量
对于String类,字符串型采用next();其它的采用/nextXxx()(注意首字母大写)
import java.util.Scanner;
public class ScannerTest {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
int num=scan.nextInt(); //int型
System.out.println(num);
}
}
import java.util.Scanner;
public class ScannnerTest02 {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
System.out.println("Please enter your name");
String name=scan.next();
System.out.println(name);
System.out.println("Please enter your age");
int age=scan.nextInt();
System.out.println(age);
System.out.println("Please enter your weight");
double weight=scan.nextDouble();
System.out.println(weight);
System.out.println("Whether you join us (true/false)");
boolean isjoin=scan.nextBoolean();
System.out.println(isjoin);
}
}
注意:我们需要根据相应的方法,来输入指定类型的值。如果输入的数据类型与要求的类型不匹配时,会报异常:InputMisMatchExce导致程序终止
循环
循环的四个组成部分:
1.初始化部分------>2.循环条件部分(boolean类型)------->3.循环体部分------>4.迭代部分
for 循环
for(1初始化部分;2循环条件部分;4迭代部分){
3循环体部分;
}
实例:输入两个数正整数m和n,求其最大公约数和最小公倍数
最大公约数:首先要确定范围:1-两数间的较小数;若要满足最大,那么从两数间的较小数开始循环,找到第一个满足条件的数即可(然后退出循环:break)
最小公倍数:范围:两数中的较大数-两数的乘积;后续同理
package my_first_java_code;
import java.util.Scanner;
public class ForTest {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
System.out.println("请输入第一个正整数");
int first_num=scan.nextInt();
System.out.println("请输入第二个正整数");
int second_num=scan.nextInt();
//求最大公约数
//先求出两数的较小数——三目运算符
int min=(first_num<second_num)?first_num:second_num;
for(int i=min;i>=1;i--) {
if(first_num%i==0&&second_num%i==0) {
System.out.println("最大公约数为"+i);
break;
}
}
int max=(first_num>second_num)?first_num:second_num;
for(int j=max;j<first_num*second_num;j++) {
if(j%first_num==0&&j%second_num==0) {
System.out.println("最小公倍数为"+j);
break;
}
}
}
}
while 循环
1初始化条件
while(2循环条件){
3循环体;
4迭代条件;
}
do-while 循环
1初始化条件
do{
3循环体;
4迭代条件;
}while(2循环条件)
说明:
1.do-while循环至少会执行一次循环体
2.当循环会执行多次时,do-while循环和while循环没有区别
实例:从键盘读入个数不确定的整数,并判断读入数的个数,输入0时为结束条件
import java.util.Scanner;
public class CirculateEG {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
int count=0;
while(true) {
int import_num=scan.nextInt();
if(import_num!=0) {
count++;
System.out.println("输入的个数为:"+count);
}
else
break;
}
}
}
对于该类无法确定循环次数的问题:while(true)/for( ; ; ),然后再用break来控制
【总结】:结束循环的方式:循环条件返回false;循环体中,执行break
嵌套循环
外层控制行数;内层控制列数
常见模型:
/*
*
**
***
****
*****
*/
规律:i=j(行=列)
for(int i=1;i<=5;i++){
for(int j=1;j<=i;j++){
System.out.print("*");
}
System.out.println(); //换行
}
/*
*****
****
***
**
*
*/
规律:i+j=5(行=列)
for(int i=1;i<=5;i++){
for(int j=1;j<=5-i;j++){
System.out.print("*");
}
System.out.println(); //换行
}
实例1:九九乘法表
public class Nine_nine_multiplication_table {
public static void main(String[] args){
for(int i=1;i<=9;i++) {
for(int j=1;j<=i;j++) {
System.out.print(i+"*"+j+"="+i*j+" ");
}
System.out.println();
}
}
}
实例2:输出质数
1:
public class Output_prime_numbers {
public static void main(String[] args){
for(int i=2;i<=100;i++) {
boolean isFlag=true;
for(int j=2;j<i;j++) { //判断i是否是质数
if(i%j==0) {
isFlag=false;
}
}
if(isFlag==true) {
System.out.println(i);
}
}
}
}
这里使用到一个标志:是否除尽;需要特别注意的是:每次在判断完后需要重置isflag的值
2.优化
判断质数时若已经被整除了,那么就不用再循环下去了:break(对非质数有效)
为了判断优化是否有效,我们通过记录运行时间来直观的看是否优化(单位:毫秒)
public class Output_prime_number_optimized_V1 {
public static void main(String[] args){
//获取当前时间距离1970-01-01 00:00:00的时间差
long start_time=System.currentTimeMillis();
for(int i=2;i<=100000;i++) {
boolean isFlag=true;
for(int j=2;j<i;j++) { //判断i是否是质数
if(i%j==0) {
isFlag=false;
break;
}
}
if(isFlag==true) {
System.out.println(i);
}
}
//获取当前时间距离1970-01-01 00:00:00的时间差
long end_time=System.currentTimeMillis();
System.out.println("该程序运行时间为:"+(end_time-start_time));
}
}
优化前程序运行时间与优化后程序运行时间如下:
很明显,时间相差10倍!
这里使用到了:
long start_time=System.currentTimeMillis();
System.currentTimeMillis();的返回值为整型,
3.再优化
方法:数学上有个规律,对于一个小于n的整数x,若n不能整除x,则n必定不能整数n/x,那么带来一个明显的优化就是循环控制语句从2到根号n即可。
修改为:
for(int j=2;j<Math.sqrt(i);j++)
这里对i求根号用到了数学方法:
Math.sqrt(); //括号内放开根数
再次优化后程序运行时间如下:
break和continue
1.break:switch-case/循环结构中 作用:结束当前循环
2.continue:循环结构中 作用:结束当次循环
相同点:在break和continue之后是不能声明执行语句
3.对于嵌套循环内:break默认跳出包裹此关键字最近的一层循环
------>若要结束某一特定的for循环:使用标签(continue同理)
label:for( ; ;){
for( ; ;){
break label; //结束指定标识的一层循环结构
}
}
实例:输出质数的另一种写法
label:for(int i=2;i<=100;i++) {
for(int j=2;j<=Math.sqrt(i);j++) { //判断i是否是质数
if(i%j==0) { //如果出现了整除
continue label;
}
}
//能执行到此步骤的,都是质数
System.out.println(i);
}
7591011354)]
break和continue
1.break:switch-case/循环结构中 作用:结束当前循环
2.continue:循环结构中 作用:结束当次循环
相同点:在break和continue之后是不能声明执行语句
3.对于嵌套循环内:break默认跳出包裹此关键字最近的一层循环
------>若要结束某一特定的for循环:使用标签(continue同理)
label:for( ; ;){
for( ; ;){
break label; //结束指定标识的一层循环结构
}
}
实例:输出质数的另一种写法
label:for(int i=2;i<=100;i++) {
for(int j=2;j<=Math.sqrt(i);j++) { //判断i是否是质数
if(i%j==0) { //如果出现了整除
continue label;
}
}
//能执行到此步骤的,都是质数
System.out.println(i);
}