Java语言程序设计:Chap3——流程控制语句

程序输入输出

输出语句

输出后换行:System.out.println()

输出后不换行:System.out.print()

格式化输出:System.out.printf()

  • int : %d
  • float : %f
  • double : %f
  • char : %c
  • String : %s
较高效率输出
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        bw.write("1\n");
        bw.flush(); 
    }
}
输出多个变量

以字符串形式拼接输出

public class Main {
    public static void main(String[] args) {
        int a = 1,b = 2;
        System.out.println(a + "," + b);
    }
}

以格式字符串输出

public class Main {
    public static void main(String[] args) {
        int a = 1,b = 2;
        System.out.printf("%d,%d\n",a,b);
    }
}

输入语句

输入都是通过字符串读入来实现的,有关方法见:https://blog.youkuaiyun.com/V_Akoasm/article/details/147993435?spm=1001.2014.3001.5501

import java.util.Scanner; //导包,告诉编译器和JVM去哪里找到这个工具类,JRE中包含很多核心类库

public class TestInput {
    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);

        System.out.print("请输入姓名:");

        String name = input.next();

        System.out.print("请输入年龄:");
        int age = input.nextInt();

        System.out.print("请输入体重:");
        double weight = input.nextDouble();

        System.out.print("是否已婚(true/false):");
        boolean marry = input.nextBoolean();

        System.out.print("请输入性别:");
        char gender = input.next().charAt(0);

        System.out.println("name = " + name);
        System.out.println("age = " + age);
        System.out.println("weight = " + weight);
        System.out.println("marry = " + marry);
        System.out.println("gender = " + gender);=

        input.close();
    }
}
高效率输入
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();
        System.out.println(str);
    }
}

程序流程控制结构

  • 顺序结构
  • 分支结构(选择结构)
    • if...else
    • switch-case
  • 循环结构
    • for
    • while
    • do-while

顺序结构

程序从上到下依次执行,表达式语句都是顺序执行

分支结构(选择结构)

if…else

基本语法
单分支条件判断if
if (condition) {
	do_sth;
}

在这里插入图片描述

双分支if…else
if (condition) {
	do_sth1;
} else {
	do_sth2;
}

在这里插入图片描述

多分支if…else if…else
if (condition1) {
	...
} else if (condition2) {
	...
} ... {

} else if(condition n) {
	...
} else {
	...
}

在这里插入图片描述

多分支书写时需要注意条件之间是否有交集,无交集条件顺序可以任意颠倒,有交集则不行。

int score = 67;
if (score == 100) {
	System.out.println("奖励1");
} else if(score > 80 && score <= 99) {
	System.out.println("奖励2");
} else if(score >= 60 && score <= 80) {
	System.out.println("奖励3");
} else {
	System.out.println("无奖励");
}

上述代码任意两个条件是可以互换的,对结果没有影响。

int score = 67;
if (score == 100) {
	System.out.println("奖励1");
} else if (score > 80) {
    System.out.println("奖励2");
} else if (score >= 60) {
    System.out.println("奖励3");
} else {
    System.out.println("无奖励");
}

此时就不能任意调换两个条件的顺序。

当条件之间没有交集的时候,条件判断语句和执行语句间顺序无所谓。

当条件之间是包含关系时(如score > 80也包含了score == 100),将“条件空间较小”的条件表达式往上写。

if…else嵌套

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

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

说明
  • if条件后跟的语句块如果只有一行,{}可以省略
  • if-else if-else结构可以没有最后的else
常见错误
  1. 忘记加必要的括号:只有语句块为一条语句的才可以不加括号{}

  2. if行尾错误的加了分号

  3. 对布尔值的冗余测试

    if (even == true)
        do_sth;
    //等价于
    if (even)
        do_sth;
    //而第一种方式可能会手误写成
    if (even = true)
        do_sth;
    
  4. else歧义

    • 在同一个块中,else总是和离它最近的if语句匹配,和缩进无关
  5. 浮点数判断相等

    • 浮点数有有限的计算精度,涉及浮点数的运算可能引发舍入错误

      double x = 1.0 - 0.1 - 0.1 - 0.1 - 0.1 - 0.1;
      System.out.println(x == 0.5); //false
      
      • 按道理这里应该是true,但其实它可能是0.50000000000001
      • 因此一般判断浮点数相等(以a和b举例)用如下操作
      double a = xxx;
      double b = xxx;
      final double EPSILON = 1e-8;
      if(Math.abs(a - b) < EPSILON)
          System.out.println("a = b");
      
较好的写法
  1. 简化boolean变量赋值

    if (num % 2 == 0)
        even = true;
    else
        even = false;
    //等价于
    boolean even = num % 2 == 0;
    
  2. 避免不同情形的重复代码

    if(condition) {
        tuition = 5000;
        System.out.println("The tuition is " + tuition);
    } else {
        tuition = 15000;
        System.out.println("The tuition is " + tuition);
    }
    //最好写成
    if(condition) {
        tuition = 5000;
    } else {
        tuition = 15000;
    }
    System.out.println("The tuition is " + tuition);
    

switch-case

传统语法
switch(表达式){
    case 常量值1:
        语句块1;
    case 常量值2:
        语句块2;
    case 常量值3:
        语句块3;
    default:
        语句块n+1;
}

在这里插入图片描述

执行过程:

  1. 根据switch中表达式的值,依次匹配各个case。如果表达式的值等于某个case中的常量值,则执行对应case中的执行语句。
  2. 执行完此case的执行语句以后,
    1. 情况1:如果遇到break,则执行break并跳出当前的switch-case结构
    2. 情况2:如果没有遇到break,则会继续执行当前case之后的其它case中的执行语句。—>case穿透
      ​ …
    3. 直到遇到break关键字或执行完所有的case及default的执行语句,跳出当前的switch-case结构

执行特点

  • 入口
    • case入口:优先考虑,switch(表达式)的值与某个常量值“相同”了,就从这个case进入
    • default入口:当所有case都不匹配时,就找default进入
  • 出口:
    • 自然出口:从入口一直往下直到switch-case执行到底
    • 中断出口:遇到break
  • 穿透性/贯穿性:
    • 无论你是从case进来,还是从default进入,只要没有遇到break,就会贯穿

使用注意点:

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

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

  • 同一个switch语句,所有case子句中的常量值互不相同,且必须是同一类型;

  • break语句用来在执行完一个case分支后使程序跳出switch语句块;如果没有break,程序会顺序执行到switch结尾;

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

与if…else区别
  • 适用性:凡是使用switch-case的结构都可以转换为if-else结构。反之,不成立。

  • 效率:如果既可以使用switch-case,又可以使用if-else,建议使用switch-case。因为效率稍高。

  • 细节对比:

    • if-else语句优势
      • if语句的条件是一个布尔类型值,if条件表达式为true则进入分支,可以用于范围的判断,也可以用于等值的判断,使用范围更广
      • switch语句的条件是一个常量值(byte,short,int,char,枚举,String),只能判断某个变量或表达式的结果是否等于某个常量值,使用场景较狭窄
    • switch语句优势
      • 当条件是判断某个变量或表达式是否等于某个固定的常量值时,使用if和switch都可以,习惯上使用switch更多。因为效率稍高。当条件是区间范围的判断时,只能使用if语句。
      • 使用switch可以利用穿透性,同时执行多个分支,而if…else没有穿透性。
体会case穿透

例1:对学生成绩大于60的输出合格,否则输出不合格

public class Main {
    public static void main (String[] args) {
        int score = 80;
        switch(score / 10) {
            case 0:
            case 1:
            case 2:
	    case 3:
	    case 4:
	    case 5:
		System.out.println("不及格");
		break;
             case 6:
	     case 7:
	     case 8:
 	      case 9:
	     case 10:
		System.out.println("及格");
		break;
	     default:
		System.out.println("成绩输入有误");
		break;
        }
    }
}

例2:从键盘上输入month和day,输出为一年中的第几天?

import java.util.Scanner;

class SwitchCaseTest2 {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		int month = input.nextInt();
		int day = input.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; 
			case 2:
				sumDays += 31; 
			case 1:
				sumDays += day;
				//break;
		}
		System.out.println("2023年" + month + "月" + day + "日是当前的第" + sumDays + "天");
		input.close();
	}
}
switch表达式(JDK17)
传统的switch-case语句结构switch表达式
case后面的标点符号:->
穿透性没有(可以不写break)
是否可以作为表达式给变量赋值不可以可以
case后面如果要写多个语句是否必须加{}不需要强制要求
default分支是否必选可选作为表达式是必选
import java.util.Scanner;

public class TestSwitchExpression {
    public static void main(String[] args) {
        //从控制台接收用户输入的星期值[1,7],然后输出它对应的英文单词
        Scanner input = new Scanner(System.in);

        System.out.print("请输入星期值[1,7]:");
        int week = input.nextInt();

        switch (week) {
            case 1 -> System.out.println("Monday");
            case 2 -> System.out.println("Tuesday");
            case 3 -> System.out.println("Wednesday");
            case 4 -> System.out.println("Thursday");
            case 5 -> System.out.println("Friday");
            case 6 -> System.out.println("Saturday");
            case 7 -> System.out.println("Sunday");
            default -> System.out.println("星期输入有误"); //可选
        }
        input.close();
    }
}
import java.util.Scanner;

public class TestSwitchExpression2 {
    public static void main(String[] args) {
        //从控制台接收用户输入的星期值[1,7],然后输出它对应的英文单词
        Scanner input = new Scanner(System.in);

        System.out.print("请输入星期值[1,7]:");
        int week = input.nextInt();

        String weekName = switch (week) {
            case 1 -> "Monday";
            case 2 -> "Tuesday";
            case 3 -> "Wednesday";
            case 4 -> "Thursday";
            case 5 -> "Friday";
            case 6 -> "Saturday";
            case 7 -> "Sunday";
            default -> "星期输入有误";//必选
        };
        System.out.println("weekName = " + weekName);

        input.close();
    }
}
import java.util.Scanner;

public class TestSwitchExpression3 {
    public static void main(String[] args) {
        //从控制台接收用户输入的星期值[1,7],然后输出它对应的英文单词
        Scanner input = new Scanner(System.in);

        System.out.print("请输入星期值[1,7]:");
        int week = input.nextInt();

        String weekName = switch (week) {
            case 1 -> "Monday";
            case 2 -> "Tuesday";
            case 3 -> "Wednesday";
            case 4 -> "Thursday";
            case 5 -> "Friday";
            case 6 -> "Saturday";
            case 7 -> {
                System.out.println("这一天是我最喜欢的一天!");
                yield "Sunday";//yield是一个上下文关键字,只在switch表达式的内部是关键字,在其他地方是普通单词,做返回值之用
            }
            default -> "星期输入有误"; //必选
        };
        System.out.println("weekName = " + weekName);

        input.close();
    }
}

循环语句

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

  • 循环结构分类:

    • for 循环
    • while 循环
    • do-while 循环
  • 循环结构四要素

    • 初始化部分
    • 循环条件部分
    • 循环体部分
    • 迭代部分

for循环

基本格式

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

在这里插入图片描述

注意:

  • for(;;)中的两个;不能多也不能少
  • 初始化部分可以声明多个变量,但必须是同一个类型,用逗号分隔
  • 循环条件部分必须为boolean类型表达式,当值为false时,退出循环
  • 可以有多个变量更新,用逗号分隔

例子

public class ShuiXianhua {
    public static void main(String[] args) {
        //水仙花数是指一个3位数,其各个位上数字立方和等于其本身。
        // 例如: 153 = 1*1*1 + 5*5*5 + 3*3*3,
        // 找出所有的水仙花数,并统计他们有几个。
        int count = 0;
        for(int i=100; i<=999; i++){
            //求各个位上数字,百位、十位、个位
            int bai = i / 100;
            int shi = i % 100 / 10;
            int ge = i % 10;

            if(bai * bai * bai + shi * shi *shi + ge * ge * ge == i){
                System.out.println(i);
                count++;
            }
        }
        System.out.println("一共有:" + count);
    }
}
  • 我们可以在循环中使用break。一旦执行break,就跳出当前循环结构。
  • 如何结束一个循环结构?

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

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

  • 如果一个循环结构不能结束,那就是一个死循环!要避免出现死循环。

while循环

基本格式

初始化部分
while(循环条件部分) {
    循环体部分
    迭代部分
}

在这里插入图片描述

说明:

  • while(循环条件)中循环条件必须是boolean类型。
  • 注意不要忘记声明迭代部分。否则,循环将不能结束,变成死循环。
  • for循环和while循环可以相互转换。二者没有性能上的差别。
  • for循环与while循环的区别:初始化条件部分的作用域不同。
//输出5行
class WhileTest1 {
	public static void main(String[] args) {
		
		int i = 1;
		while(i <= 5){
			System.out.println("Hello World!");
			i++;
		}
	}
}

do-while循环

基本格式:

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

在这里插入图片描述

说明:

  • 结尾while(循环条件)中循环条件必须是boolean类型
  • do{}while();最后有一个分号
  • do-while结构的循环体语句是至少会执行一次,这个和for和while是不一样的
  • 循环的三个结构for、while、do-while三者是可以相互转换的。

三种循环的对比

  • 三种循环结构都具有四个要素:
    • 循环变量的初始化条件
    • 循环条件
    • 循环体语句块
    • 循环变量的修改的迭代表达式
  • 从循环次数角度分析
    • do-while循环至少执行一次循环体语句。
    • for和while循环先判断循环条件语句是否成立,然后决定是否执行循环体。
  • 如何选择
    • 遍历有明显的循环次数(范围)的需求,选择for循环
    • 遍历没有明显的循环次数(范围)的需求,选择while循环
    • 如果循环体语句块至少执行一次,可以考虑使用do-while循环
    • 本质上:三种循环之间完全可以互相转换,都能实现循环的功能

无限循环:while(true) 和 for(;😉

嵌套循环

  • 所谓嵌套循环,是指一个循环结构A的循环体是另一个循环结构B。比如,for循环里面还有一个for循环,就是嵌套循环。其中,for ,while ,do-while均可以作为外层循环或内层循环。
    • 外层循环:循环结构A
    • 内层循环:循环结构B
  • 实质上,嵌套循环就是把内层循环当成外层循环的循环体。只有当内层循环的循环条件为false时,才会完全跳出内层循环,才可结束外层的当次循环,开始下一次的外层循环。
  • 设外层循环次数为m次,内层为n次,则内层循环体实际上需要执行m*n次。
  • **技巧:**从二维图形的角度看,外层循环控制行数,内层循环控制列数

跳转语句

breakcontinuereturn
使用位置switch-case,循环结构循环结构方法体中任意位置
作用用于结束/跳出当前的switch-case或循环结构用于跳过本次循环体剩下的语句用于结束当前方法

获取随机数

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

Math.random() * 100 —> [0,100)

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

如何获取[a,b]范围内的随机整数呢?

(int)(Math.random() * (b - a + 1)) + a

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值