流程控制语句

目录

1. 顺序结构

2. 分支语句

2.1 if-else条件判断结构

2.1.1 基本语法

2.1.3 if...else嵌套

2.1.4 其它说明

2.2 switch-case选择结构

2.2.1 基本语法

2.2.2 利用case的穿透性

3. 循环语句

3.1 for循环

3.1.1 基本语法

3.2 while循环

3.2.1 基本语法

3.3 do-while循环

3.3.1 基本语法

3.4 对比三种循环结构

3.5 "无限"循环

3.5.1 基本语法

3.5.2 应用举例

3.6 嵌套循环(或多重循环)

3.6.1 使用说明

3.6.2 应用举例

4. 关键字break和continue的使用

4.1 break和continue的说明

4.2 应用举例

4.3 带标签的使用

4.4 经典案例

4.5 练习

5. Scanner:键盘输入功能的实现

6. 如何获取一个随机数


  • 流程控制语句是用来控制程序中各语句执行顺序的语句,可以把语句组合成能完成一定功能的小逻辑模块。
  • 程序设计中规定的三种流程结构,即:

    • 顺序结构

      • 程序从上到下逐行地执行,中间没有任何判断和跳转。

    • 分支结构

      • 根据条件,选择性地执行某段代码。

      • if…elseswitch-case两种分支语句。

    • 循环结构

      • 根据循环条件,重复性的执行某段代码。

      • forwhiledo-while三种循环语句。

      • 补充:JDK5.0 提供了foreach循环,方便的遍历集合、数组元素。(

1. 顺序结构

顺序结构就是程序从上到下逐行地执行。表达式语句都是顺序执行的。并且上一行对某个变量的修改对下一行会产生影响。

 

Java中定义变量时采用合法的前向引用。如:

 public static void main(String[] args) {
     int num1 = 12;
     int num2 = num1 + 2;
 }

错误形式:

 public static void main(String[] args) {
     int num2 = num1 + 2;
     int num1 = 12;
 }

2. 分支语句

2.1 if-else条件判断结构

2.1.1 基本语法

结构1:单分支条件判断:if

格式:

if(条件表达式){  
     语句块;  

说明条件表达式必须是布尔表达式(关系表达式或逻辑表达式)或 布尔变量。

执行流程:

  1. 首先判断条件表达式看其结果是true还是false

  2. 如果是true就执行语句块

  3. 如果是false就不执行语句块

结构2:双分支条件判断:if...else

格式:

 if(条件表达式) { 
     语句块1;
 }else {
     语句块2;
 }

执行流程:

  1. 首先判断条件表达式看其结果是true还是false

  2. 如果是true就执行语句块1

  3. 如果是false就执行语句块2

结构3:多分支条件判断:if...else if...else

格式:

 if (条件表达式1) {
     语句块1;
 } else if (条件表达式2) {
     语句块2;
 }
 ...
 }else if (条件表达式n) {
     语句块n;
 } else {
     语句块n+1;
 }

说明:一旦条件表达式为true,则进入执行相应的语句块。执行完对应的语句块之后,就跳出当前结构。

执行流程:

  1. 首先判断关系表达式1看其结果是true还是false

  2. 如果是true就执行语句块1,然后结束当前多分支

  3. 如果是false就继续判断关系表达式2看其结果是true还是false

  4. 如果是true就执行语句块2,然后结束当前多分支

  5. 如果是false就继续判断关系表达式…看其结果是true还是false

n. 如果没有任何关系表达式为true,就执行语句块n+1,然后结束当前多分支。

当条件表达式之间是“互斥”关系时(即彼此没有交集),条件判断语句及执行语句间顺序无所谓。

当条件表达式之间是“包含”关系时,“小上大下 / 子上父下”,否则范围小的条件表达式将不可能被执行。

2.1.3 if...else嵌套

在 if 的语句块中,或者是在else语句块中,又包含了另外一个条件判断(可以是单分支、双分支、多分支),就构成了嵌套结构

执行的特点: (1)如果是嵌套在if语句块中的,只有当外部的if条件满足,才会去判断内部的条件 (2)如果是嵌套在else语句块中的,只有当外部的if条件不满足,进入else后,才会去判断内部的条件

2.1.4 其它说明
  • 语句块只有一条执行语句时,一对{}可以省略,但建议保留

  • 当if-else结构是“多选一”时,最后的else是可选的,根据需要可以省略

2.2 switch-case选择结构

2.2.1 基本语法

语法格式:

 switch(表达式){
     case 常量值1:
         语句块1;
         //break;
     case 常量值2:
         语句块2;
         //break; 
     // ...
    [default:
         语句块n+1;
         break;
    ]
 }

执行流程图:

执行过程:

第1步:根据switch中表达式的值,依次匹配各个case。如果表达式的值等于某个case中的常量值,则执行对应case中的执行语句。

第2步:执行完此case的执行语句以后, ​ 情况1:如果遇到break,则执行break并跳出当前的switch-case结构 ​ 情况2:如果没有遇到break,则会继续执行当前case之后的其它case中的执行语句。--->case穿透 ​ ... ​ 直到遇到break关键字或执行完所有的case及default的执行语句,跳出当前的switch-case结构

使用注意点:

  • switch(表达式)中表达式的值必须是下述几种类型之一:byte,short,char,int,枚举 (jdk 5.0),String (jdk 7.0);

  • case子句中的值必须是常量,不能是变量名或不确定的表达式值或范围;

  • 同一个switch语句,所有case子句中的常量值互不相同;

  • break语句用来在执行完一个case分支后使程序跳出switch语句块;

    如果没有break,程序会顺序执行到switch结尾;

  • default子句是可选的。同时,位置也是灵活的。当没有匹配的case时,执行default语句。

2.2.2 利用case的穿透性

在switch语句中,如果case的后面不写break,将出现穿透现象,也就是一旦匹配成功,不会在判断下一个case的值,直接向后运行,直到遇到break或者整个switch语句结束,执行终止。

3. 循环语句

  • 理解:循环语句具有在某些条件满足的情况下,反复执行特定代码的功能。

  • 循环结构分类:

    • for 循环

    • while 循环

    • do-while 循环

  • 循环结构四要素

    • 初始化部分

    • 循环条件部分

    • 循环体部分

    • 迭代部分

3.1 for循环

3.1.1 基本语法

语法格式:

 for (①初始化部分; ②循环条件部分; ④迭代部分){
             ③循环体部分;
 }

执行过程:①-②-③-④-②-③-④-②-③-④-.....-②

图示:

说明:

  • for(;;)中的两个;不能多也不能少

  • ①初始化部分可以声明多个变量,但必须是同一个类型,用逗号分隔

  • ②循环条件部分为boolean类型表达式,当值为false时,退出循环

  • ④可以有多个变量更新,用逗号分隔

说明:

1、我们可以在循环中使用break。一旦执行break,就跳出当前循环结构。

2、小结:如何结束一个循环结构?

结束情况1:循环结构中的循环条件部分返回false

结束情况2:循环结构中执行了break。

3、如果一个循环结构不能结束,那就是一个死循环!我们开发中要避免出现死循环。

3.2 while循环

3.2.1 基本语法

语法格式:

 ①初始化部分
 while(②循环条件部分){
     ③循环体部分;
     ④迭代部分;
 }

执行过程:①-②-③-④-②-③-④-②-③-④-...-②

图示:

说明:

  • while(循环条件)中循环条件必须是boolean类型。

  • 注意不要忘记声明④迭代部分。否则,循环将不能结束,变成死循环。

  • for循环和while循环可以相互转换。二者没有性能上的差别。实际开发中,根据具体结构的情况,选择哪个格式更合适、美观。

  • for循环与while循环的区别:初始化条件部分的作用域不同。

3.3 do-while循环

3.3.1 基本语法

语法格式:

 ①初始化部分;
 do{
     ③循环体部分
     ④迭代部分
 }while(②循环条件部分); 

执行过程:①-③-④-②-③-④-②-③-④-...-②

图示:

说明:

  • 结尾while(循环条件)中循环条件必须是boolean类型

  • do{}while();最后有一个分号

  • do-while结构的循环体语句是至少会执行一次,这个和for和while是不一样的

  • 循环的三个结构for、while、do-while三者是可以相互转换的。

3.4 对比三种循环结构

  • 三种循环结构都具有四个要素:

    • 循环变量的初始化条件

    • 循环条件

    • 循环体语句块

    • 循环变量的修改的迭代表达式

  • 从循环次数角度分析

    • do-while循环至少执行一次循环体语句。

    • for和while循环先判断循环条件语句是否成立,然后决定是否执行循环体。

  • 如何选择

    • 遍历有明显的循环次数(范围)的需求,选择for循环

    • 遍历没有明显的循环次数(范围)的需求,选择while循环

    • 如果循环体语句块至少执行一次,可以考虑使用do-while循环

    • 本质上:三种循环之间完全可以互相转换,都能实现循环的功能

3.5 "无限"循环

3.5.1 基本语法

语法格式:

  • 最简单"无限"循环格式:while(true) , for(;;)

适用场景:

  • 开发中,有时并不确定需要循环多少次,需要根据循环体内部某些条件,来控制循环的结束(使用break)。

  • 如果此循环结构不能终止,则构成了死循环!开发中要避免出现死循环。

3.5.2 应用举例

案例1:从键盘读入个数不确定的整数,并判断读入的正数和负数的个数,输入为0时结束程序。

import java.util.Scanner;
 ​
 class PositiveNegative {
     public static void main(String[] args) {
         Scanner scanner = new Scanner(System.in);
         
         int positiveNumber = 0;//统计正数的个数
         int negativeNumber = 0;//统计负数的个数
         for(;;){  //while(true){
             System.out.println("请输入一个整数:(输入为0时结束程序)");
             int num = scanner.nextInt();
             if(num > 0){
                  positiveNumber++;
             }else if(num < 0){
                  negativeNumber++;
             }else{
                 System.out.println("程序结束");
                 break; 
             }
          }
          System.out.println("正数的个数为:"+ positiveNumber);
          System.out.println("负数的个数为:"+ negativeNumber);  
         
          scanner.close();
     } 
 }
 

3.6 嵌套循环(或多重循环)

3.6.1 使用说明
  • 所谓嵌套循环,是指一个循环结构A的循环体是另一个循环结构B。比如,for循环里面还有一个for循环,就是嵌套循环。其中,for ,while ,do-while均可以作为外层循环或内层循环。

    • 外层循环:循环结构A

    • 内层循环:循环结构B

  • 实质上,嵌套循环就是把内层循环当成外层循环的循环体。只有当内层循环的循环条件为false时,才会完全跳出内层循环,才可结束外层的当次循环,开始下一次的外层循环。

  • 设外层循环次数为m次,内层为n次,则内层循环体实际上需要执行m*n次。

  • 技巧:从二维图形的角度看,外层循环控制行数,内层循环控制列数

  • 开发经验:实际开发中,我们最多见到的嵌套循环是两层。一般不会出现超过三层的嵌套循环。如果将要出现,一定要停下来重新梳理业务逻辑,重新思考算法的实现,控制在三层以内。否则,可读性会很差。

例如:两个for嵌套循环格式

 for(初始化语句①; 循环条件语句②; 迭代语句⑦) {
     for(初始化语句③; 循环条件语句④; 迭代语句⑥) {
         循环体语句⑤;
     }
 }
 //执行过程:① - ② - ③ - ④ - ⑤ - ⑥ - ④ - ⑤ - ⑥ - ... - ④ - ⑦ - ② - ③ - ④ - ⑤ - ⑥ - ④..

执行特点:外层循环执行一次,内层循环执行一轮。

3.6.2 应用举例

案例1:打印5行6个*

 class ForForTest1 {
     public static void main(String[] args) {
         /*
         
         ******
         ******
         ******
         ******
         ******
         
         */
         
         for(int j = 1;j <= 5;j++){
 ​
             for(int i = 1;i <= 6;i++){
                 System.out.print("*");
             }
             
             System.out.println();
         }
     }
 }

案例2:打印5行直角三角形

 *
 **
 ***
 ****
 *****
 public class ForForTest2 {
     public static void main(String[] args){
         for (int i = 1; i <= 5; i++) {
             for (int j = 1; j <= i; j++) {
                 System.out.print("*");
             }
             System.out.println();
         }
     }
 }  

案例3:打印5行倒直角三角形

 *****
 ****
 ***
 **
 *
 public class ForForTest3 {
     public static void main(String[] args){
         for(int i = 1;i <= 5;i++){
             for(int j = 1;j <= 6 - i;j++){
                 System.out.print("*");
             
             }
             System.out.println();
         
         }
     }
 }

案例4:打印"菱形"形状的图案

         * 
       * * * 
     * * * * * 
   * * * * * * * 
 * * * * * * * * * 
   * * * * * * * 
     * * * * * 
       * * * 
         *   
 public class ForForTest4 {
 ​
     public static void main(String[] args) {
     /*
         上半部分        i       m(表示-的个数)    n(表示*的个数)关系式:2*i + m = 10 --> m = 10 - 2*i
     --------*          1       8               1                            n = 2 * i - 1
     ------* * *        2       6               3
     ----* * * * *      3       4               5
     --* * * * * * *    4       2               7
     * * * * * * * * *  5       0               9
 ​
         下半部分         i      m                n              关系式: m = 2 * i
     --* * * * * * *    1       2                7                     n = 9 - 2 * i
     ----* * * * *      2       4                5
     ------* * *        3       6                3
     --------*          4       8                1
 ​
             */
         //上半部分
         for (int i = 1; i <= 5; i++) {
             //-
             for (int j = 1; j <= 10 - 2 * i; j++) {
                 System.out.print(" ");
             }
             //*
             for (int k = 1; k <= 2 * i - 1; k++) {
                 System.out.print("* ");
             }
             System.out.println();
         }
         //下半部分
         for (int i = 1; i <= 4; i++) {
             //-
             for (int j = 1; j <= 2 * i; j++) {
                 System.out.print(" ");
             }
 ​
             //*
             for (int k = 1; k <= 9 - 2 * i; k++) {
                 System.out.print("* ");
             }
             System.out.println();
         }
     }
 ​
 }

案例5:九九乘法表

 public class ForForTest5 {
     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) + "\t");
             }
             System.out.println();
         }
     }
 }

4. 关键字break和continue的使用

4.1 break和continue的说明

             适用范围            在循环结构中使用的作用                     相同点
 ​
 break       switch-case
             循环结构            一旦执行,就结束(或跳出)当前循环结构         此关键字的后面,不能声明语句
 ​
 continue    循环结构            一旦执行,就结束(或跳出)当次循环结构         此关键字的后面,不能声明语句

        此外,很多语言都有goto语句,goto语句可以随意将控制转移到程序中的任意一条语句上,然后执行它,但使程序容易出错。Java中的break和continue是不同于goto的。

4.2 应用举例

 class BreakContinueTest1 {
     public static void main(String[] args) {
     
         for(int i = 1;i <= 10;i++){
             
             if(i % 4 == 0){
                 //break;//123
                 continue;//123567910
                 //如下的语句不可能被执行,编译不通过
                 //System.out.println("今晚迪丽热巴要约我吃饭");
             }
 ​
             System.out.print(i);
         }
 ​
         System.out.println("####");
 ​
         //嵌套循环中的使用
         for(int i = 1;i <= 4;i++){
         
             for(int j = 1;j <= 10;j++){
                 if(j % 4 == 0){
                     //break; //结束的是包裹break关键字的最近的一层循环!
                     continue;//结束的是包裹break关键字的最近的一层循环的当次!
                 }
                 System.out.print(j);
             }
             System.out.println();
         }
 ​
     }
 }

4.3 带标签的使用

 break语句用于终止某个语句块的执行
 {    ……  
     break;
      ……
 }
 ​
 break语句出现在多层嵌套的语句块中时,可以通过标签指明要终止的是哪一层语句块 
     label1: {   ……        
     label2:      {   ……
     label3:          {   ……
                            break label2;
                            ……
                      }
                  }
             } 
 ​
  • continue语句出现在多层嵌套的循环语句体中时,也可以通过标签指明要跳过的是哪一层循环。

  • 标号语句必须紧接在循环的头部。标号语句不能用在非循环语句的前面。

  • 举例:

 class BreakContinueTest2 {
     public static void main(String[] args) {
         l:for(int i = 1;i <= 4;i++){
         
             for(int j = 1;j <= 10;j++){
                 if(j % 4 == 0){
                     //break l;
                     continue l;
                 }
                 System.out.print(j);
             }
             System.out.println();
         }
     }
 }

4.4 经典案例

题目:找出100以内所有的素数(质数)?100000以内的呢?

目的:不同的代码的实现方式,可以效率差别很大。

分析:素数(质数):只能被1和它本身整除的自然数。 ---> 从2开始,到这个数-1为止,此范围内没有这个数的约数。则此数是一个质数。 比如:2、3、5、7、11、13、17、19、23、...

实现方式1:

 class PrimeNumberTest {
     public static void main(String[] args) {
         
         
         //boolean isFlag = true; //用于标识i是否被除尽过
 ​
         long start = System.currentTimeMillis(); //记录当前时间距离1970-1-1 00:00:00的毫秒数
             
         int count = 0;//记录质数的个数
 ​
 ​
         for(int i = 2;i <= 100000;i++){  //i
 ​
             boolean isFlag = true; //用于标识i是否被除尽过
         
             for(int j = 2;j <= i - 1;j++){
                 
                 if(i % j == 0){ //表明i有约数
                     isFlag = false;
                 }
             
             }
 ​
             //判断i是否是质数
             if(isFlag){ //如果isFlag变量没有给修改过值,就意味着i没有被j除尽过。则i是一个质数
                 //System.out.println(i);
                 count++;
             }
 ​
             //重置isFlag
             //isFlag = true;
         
         }
 ​
         long end = System.currentTimeMillis();
         System.out.println("质数的个数为:" + count);
         System.out.println("执行此程序花费的毫秒数为:" + (end - start)); //16628
 ​
     }
 }

实现方式2:针对实现方式1进行优化

 class PrimeNumberTest1 {
     public static void main(String[] args) {
         
         long start = System.currentTimeMillis(); //记录当前时间距离1970-1-1 00:00:00的毫秒数
 ​
         int count = 0;//记录质数的个数
 ​
         for(int i = 2;i <= 100000;i++){  //i
 ​
             boolean isFlag = true; //用于标识i是否被除尽过
         
             for(int j = 2;j <= Math.sqrt(i);j++){ //优化2:将循环条件中的i改为Math.sqrt(i)
                 
                 if(i % j == 0){ //表明i有约数
                     isFlag = false;
                     break;//优化1:主要针对非质数起作用
                 }
             
             }
 ​
             //判断i是否是质数
             if(isFlag){ //如果isFlag变量没有给修改过值,就意味着i没有被j除尽过。则i是一个质数
                 //System.out.println(i);
                 count++;
             }
         
         }
 ​
         long end = System.currentTimeMillis();
         System.out.println("质数的个数为:" + count);
         System.out.println("执行此程序花费的毫秒数为:" + (end - start));//1062
 ​
     }
 }

实现方式3(选做):使用continue + 标签

class PrimeNumberTest2 {
	public static void main(String[] args) {
		
		long start = System.currentTimeMillis(); //记录当前时间距离1970-1-1 00:00:00的毫秒数

		int count = 0;//记录质数的个数

		label:for(int i = 2;i <= 100000;i++){  //i
		
			for(int j = 2;j <= Math.sqrt(i);j++){ //优化2:将循环条件中的i改为Math.sqrt(i)
				
				if(i % j == 0){ //表明i有约数
					continue label;
				}
			
			}
			//一旦程序能执行到此位置,说明i就是一个质数
			System.out.println(i);
			count++;
		}
		

		long end = System.currentTimeMillis();
		System.out.println("质数的个数为:" + count);
		System.out.println("执行此程序花费的毫秒数为:" + (end - start));//1062

	}
}

4.5 练习

练习1:

生成 1-100 之间的随机数,直到生成了 97 这个数,看看一共用了几次?

提示:使用 (int)(Math.random() * 100) + 1
public class NumberGuessTest {
    public static void main(String[] args) {
        int count = 0;//记录循环的次数(或生成随机数进行比较的次数)
        while(true){
            int random = (int)(Math.random() * 100) + 1;
            count++;
            if(random == 97){
                break;
            }
        }

        System.out.println("直到生成随机数97,一共比较了" + count + "次");

    }
}

5. Scanner:键盘输入功能的实现

  • 如何从键盘获取不同类型(基本数据类型、String类型)的变量:使用Scanner类。

  • 键盘输入代码的四个步骤:

    1. 导包:import java.util.Scanner;

    2. 创建Scanner类型的对象:Scanner scan = new Scanner(System.in);

    3. 调用Scanner类的相关方法(next() / nextXxx()),来获取指定类型的变量

    4. 释放资源:scan.close();

  • 注意:需要根据相应的方法,来输入指定类型的值。如果输入的数据类型与要求的类型不匹配时,会报异常 导致程序终止。

6. 如何获取一个随机数

如何产生一个指定范围的随机整数?

1、Math类的random()的调用,会返回一个[0,1)范围的一个double型值

2、Math.random() * 100 ---> [0,100) (int)(Math.random() * 100) ---> [0,99] (int)(Math.random() * 100) + 5 ----> [5,104]

3、如何获取[a,b]范围内的随机整数呢?(int)(Math.random() * (b - a + 1)) + a

4、举例

class MathRandomTest {
	public static void main(String[] args) {
		double value = Math.random();
		System.out.println(value);

		//[1,6]
		int number = (int)(Math.random() * 6) + 1; //
		System.out.println(number);
	}
}

  • 17
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值