第3章 流程控制语句结构(上)
3.1表达式和语句
1、常量、变量:都是数据
2、运算符:各种运算符(有赋值的、有算术计算的、有判断关系的等)
3、表达式:
(1)常量/变量 + 运算符构成一个计算表达式。
(2)new表达式
(3)方法调用表达式
计算表达式和new表达式都有一个结果,这个结果可以用于输出或下一步运算。
方法调用表达式有的有结果有的没有结果。
Math.sqrt(x)求x的平方根,有返回结果,可以进行下一步运算。
System.out.println(x)输出x,没有结果返回,只能单独加;构成语句.
4、语句
单语句 + 复合语句
单语句:
第一种:表达式;
(1)计算表达式中:赋值表达式,自增自减表达式
a = b;
a++;
(2)new 表达式
(3)方法调用表达式
如果是new 表达式直接加;构成语句,没有任何效果。
第二种:空语句(避免)
独立的一个;
复合语句:
if..else,switch..case
for,while,do...while
try...catch
代码:
class TestStatement{
public static void main(String[] args){
int a = 1;//a=1也是表达式,赋值表达式
int b = 2;
System.out.println(a+b);
//a+b也是表达式,是算术计算表达式
System.out.println(new String("hello"));
String str = new String("hello");
System.out.println(a+b > 5);
//例如:求9的平方根
System.out.println(Math.sqrt(9));
//int num = System.out.println(9);//错误
double result = Math.sqrt(9);//可以
//以下两句等于白写,浪费CPU的时间
//new String("hello");//语法正确,编译不会报错,但是啥也没有
//Math.sqrt(16);//语法正确,编译不会报错,但是啥也没有
;//空语句
;//空语句
;//空语句
}
}
3.2输出语句
输出
就是将结果输出在控制台
目前的输出语句就这两种:
System.out.println();
System.out.print();
区别:
(1)换行问题
System.out.println(内容);输出内容之后换行
System.out.print(内容);输出内容之后不换行
(2)()是否一定要填写内容
System.out.println(); ()中可以空着
System.out.print(); ()中不允许空着
相同点:
System.out.println();
System.out.print();
都是只能输出1个值。
即如果有多项数据需要输出,要么分为多个语句分别输出,
要么把这些数据“拼接”起来一个然后输出。
代码:
class TestOut{
public static void main(String[] args){
System.out.print("hello");
System.out.print("world");
System.out.print("\n");
System.out.println("hello");
System.out.println("world");
System.out.println();
System.out.println();
System.out.println();
//System.out.print();
//System.out.print("hello" "world");
//System.out.print("hello" , "world");
//System.out.println("hello" "world");
//System.out.println("hello" , "world");
System.out.println("hello" + "," + "world");
int a = 1;
System.out.println(a);//输出a变量的值
System.out.println("a");//输出字符串常量值"a"的值,和上面的变量a没有关系
System.out.println("a=" + a);
//先原样输出"a=" 这个字符串,然后拼接输出a变量中的值1
}
}
3.3输入语句
3.3.1各种类型数据的输入
什么是输入
从控制台接收用于输入的数据,
借助核心类库中的Scanner类型,它可以实现从键盘输入数据。
步骤:
(1)声明一个Scanner类型的变量,并且创建一个Scanner的对象
Scanner input = new Scanner(System.in);
System.in:输入
System.out:输出
核心类库中只有java.lang包下的类型,才能直接使用,
例如:String,System 其他包(文件夹)的类型必须先import引入后才能使用。
(2)提示用户输入xx信息(建议)
(3)接收用户输入的xx信息 input.nextInt(); 可以从键盘输入一个int值
(4)建议关闭输入通道,释放资源
代码:
import java.util.Scanner;
//这句话的作用是告诉编译器,Scanner在哪个包/文件夹中可以找到。
//每一个.java文件只要import一次就够了,而且是在所有class上面写import
class TestInput{
public static void main(String[] args){
//(1)声明一个Scanner的变量input,并且创建一个对象给他
Scanner input = new Scanner(System.in);
/*
这句代码中唯一可以修改的是input,
它是一个变量名,由程序员自己命名。
*/
//(2)提示输入
System.out.print("请输入一个整数:");
//(3)输入并接收
int num = input.nextInt();
//表示从键盘输入一个int的整数,然后赋值给num变量
System.out.println("num = " + num);
//(4)关闭资源,表示后面不用了
input.close();
}
}
各种类型数据的输入
int的变量 = input.nextInt();
String的变量 = input.next();
double的变量 = input.nextDouble();
boolean的变量 = input.nextBoolean();
char的变量 = input.next().charAt(0);
nextInt的I,nextDouble的D,nextBoolean的B,charAt的第二个A是大写。
其他都是小写的。
如果不按照要求输入,会报错
Exception in thread "main" java.util.InputMismatchException(输入不匹配)
代码:
class TestInput2{
public static void main(String[] args){
//(1)声明一个Scanner的变量input,并且创建一个对象给他
Scanner input = new Scanner(System.in);
/*
这句代码中唯一可以修改的是input,
它是一个变量名,由程序员自己命名。
*/
//(2)提示输入
System.out.print("请输入姓名:");
//(3)输入并接收
String name = input.next();
//(2)提示输入
System.out.print("请输入年龄:");
//(3)输入并接收
int age = input.nextInt();
//(2)提示输入
System.out.print("请输入体重:");
//(3)输入并接收
double weight = input.nextDouble();
//(2)提示输入
System.out.print("请输入是否已婚(true/false):");
//(3)输入并接收
boolean marry = input.nextBoolean();
//(2)提示输入
System.out.print("请输入性别(男/女):");
//(3)输入并接收
char gender = input.next().charAt(0);
//表示输入男等字符串,取第一个字符
System.out.println("姓名:" + name);
System.out.println("年龄:" + age);
System.out.println("性别:" + gender);
System.out.println("体重:" + weight);
System.out.println("婚否:" + (marry?"已婚":"未婚"));
//(4)关闭资源,表示后面不用了
input.close();
}
}
3.3.2 next和nextLine
Scanner要输入字符串:
(1)String next():
(2)String nextLine():
区别:
(1)遇到什么认为输入结束
String next():遇到空格等空白符就认为输入结束了
String nextLine():需要遇到回车换行符,才认为结束。
(2)和其他方法搭配使用问题
nextLine()的前面还有别的键盘输入操作,前面的输入操作不是nextLine(),
会发生nextLine()的这次输入失效了(不给机会输入)。
因为前面的其他输入,把数据拿走了,但是通道中的回车换行符没有取走,
接下来遇到了nextLine(),就会自动认为输入结束了。
如何解决呢?
在其他的输入操作后面,加一句 xx.nextLine();
结论:
非必要不用nextLine()输入字符串。
除非你特意要表示字符串中间需要包含空格。
三步式:
import java.util.Scanner;
//(1)声明一个Scanner的变量input,并且创建一个对象给他
Scanner input = new Scanner(System.in);
//(2)提示输入
System.out.print("请输入姓名:");
//(3)输入并接收
String name = input.next();
代码:
import java.util.Scanner;
class TestNextAndNextLine{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
System.out.print("请输入一个字符串:");
//String str = input.next();
/*
输入:hello world回车结束输入
str只能接收到hello
*/
String str = input.nextLine();
/*
输入:hello world回车结束输入
str接收:hello world
*/
System.out.println("str = " + str);
input.close();
}
}
import java.util.Scanner;
class TestNextAndNextLine2{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
System.out.print("请输入一个整数:");
int num = input.nextInt();
input.nextLine();//这句代码的作用是用来读取整数后面的回车换行符
System.out.print("请输入一个字符串:");
//String str = input.next();
String str = input.nextLine();
System.out.println("num = " + num);
System.out.println("str = " + str);
input.close();
}
}
3.4条件判断
流程控制语句结构:
(1)顺序执行的结构:上一行执行完才轮到下一行,依次执行。
(2)分支结构:根据条件判断再决定是否执行,执行哪些代码
(3)循环结构:只要满足条件就重复执行
分支结构:
(1)条件判断:if...else
(2)选择结构:switch...case
3.4.1单分支条件判断
(1)单分支条件判断
语法格式:
if(条件判断表达式){
当条件判断表达式为true时,需要执行的语句;
}
注意:
A:if()中必须是boolean类型的变量/常量/表达式
B:如果if的{}中只有1个语句时,可以省略{},但是不止一个语句时,不能省略{}
代码:
import java.util.Scanner;
class TestIf{
public static void main(String[] args){
/*
案例:从键盘第一个小的整数赋值给small,
第二个大的整数赋值给big,
如果输入的第一个整数大于第二个整数,就交换。
输出显示small和big变量的值。
*/
Scanner input = new Scanner(System.in);
System.out.print("请输入较小的整数:");
int small = input.nextInt();
System.out.print("请输入较大的整数:");
int big = input.nextInt();
if(small > big){
System.out.println("交换");
int temp = small;
small = big;
big = temp;
}
System.out.println(small + "<" + big);
input.close();
}
}
3.4.2双分支条件判断
(2)双分支条件判断
语法格式:
if(条件判断表达式){
当条件判断表达式为true时,需要执行的语句1;
}else{
当条件判断表达式为false时,需要执行的语句2;
}
注意:
A:if()中必须是boolean类型的变量/常量/表达式
B:如果if或else的{}中只有1个语句时,可以省略{},但是不止一个语句时,不能省略{}
代码:
import java.util.Scanner;
class TestIfElse{
public static void main(String[] args){
//从键盘输入1个整数,判断它是偶数还是奇数
Scanner input = new Scanner(System.in);
System.out.print("请输入一个整数:");
int num = input.nextInt();
//偶数:和2相除的余数为0
if(num%2==0){
System.out.println(num +"是偶数");
System.out.println(num +"是双数");
}else{
System.out.println(num +"是奇数");
}
System.out.println(num + "是" + (num%2==0?"偶数" :"奇数"));
input.close();
}
}
3.4.3多分支条件判断
(3)多分支条件判断
语法格式:
if(条件判断表达式1){
当条件判断表达式1为true时,需要执行的语句1;
}else if(条件判断表达式2){
当条件判断表达式2为true时,需要执行的语句2;
}else if(条件判断表达式3){
当条件判断表达式3为true时,需要执行的语句3;
}...
【else{
当以上所有的if条件都不成立,执行语句n+1
}】
注意:
A:if()中必须是boolean类型的变量/常量/表达式
B:如果if或else的{}中只有1个语句时,可以省略{},但是不止一个语句时,不能省略{}
C:最后独立的else是可选
执行特点:
从上往下依次判断if条件,
当上面的if条件满足了,下面的条件就不看了,
当上面的if条件不满足,下面的条件继续判断。
当多个if条件中范围是没有交集/互斥的,那么条件的顺序可以随意。
当多个if条件中范围是有交集/包含的,那么条件的顺序不可以随意。
代码:
import java.util.Scanner;
class TestIfElseIf{
public static void main(String[]args){
/*
从键盘输入成绩,范围[0,100]
如果输入的成绩不在[0,100]范围,提示输入错误
如果输入的成绩是100分,显示满分
如果输入的成绩是[80,99]分,显示优秀
如果输入的成绩是[70,79]分,显示良好
如果输入的成绩是[60,69]分,显示及格
剩下的是不及格
*/
Scanner input = new Scanner(System.in);
System.out.print("请输入成绩:");
int score = input.nextInt();
if(score<0 || score>100){
System.out.println("输入错误!");
}else if(score == 100){
System.out.println("满分!");
}else if(score >= 80 && score <= 99){
System.out.println("优秀!");
}else if(score >= 70 && score <= 79){
System.out.println("良好!");
}else if(score >= 60 && score <= 69){
System.out.println("及格!");
}else{
System.out.println("不及格!");
}
System.out.println("=====故意调整多个if的顺序========");
if(score<0 || score>100){
System.out.println("输入错误!");
}else if(score >= 70 && score <= 79){
System.out.println("良好!");
}else if(score == 100){
System.out.println("满分!");
}else if(score >= 80 && score <= 99){
System.out.println("优秀!");
}else if(score >= 60 && score <= 69){
System.out.println("及格!");
}else{
System.out.println("不及格!");
}
input.close();
}
}
还有另一种写法,>=80的就是比80分大的。>=70的就是70-80这个区间,不再看大于80分的
import java.util.Scanner;
class TestIfElseIf2{
public static void main(String[]args){
/*
从键盘输入成绩,范围[0,100]
如果输入的成绩不在[0,100]范围,提示输入错误
如果输入的成绩是100分,显示满分
如果输入的成绩是[80,99]分,显示优秀
如果输入的成绩是[70,79]分,显示良好
如果输入的成绩是[60,69]分,显示及格
剩下的是不及格
*/
Scanner input = new Scanner(System.in);
System.out.print("请输入成绩:");
int score = input.nextInt();
if(score<0 || score>100){
System.out.println("输入错误!");
}else if(score == 100){
System.out.println("满分!");
}else if(score >= 80){
System.out.println("优秀!");
}else if(score >= 70){
System.out.println("良好!");
}else if(score >= 60){
System.out.println("及格!");
}else{
System.out.println("不及格!");
}
System.out.println("=====故意调整多个if的顺序========");
if(score<0 || score>100){
System.out.println("输入错误!");
}else if(score >= 70){//使得==100和>=80失效了
System.out.println("良好!");
}else if(score == 100){
System.out.println("满分!");
}else if(score >= 80){
System.out.println("优秀!");
}else if(score >= 60){
System.out.println("及格!");
}else{
System.out.println("不及格!");
}
input.close();
}
}
3.4.4嵌套
案例:
编写程序:由键盘输入三个整数分别存入变量num1、num2、num3,
实现从小到大输出三个整数。
import java.util.Scanner;
class Exercise6_2{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
System.out.print("请输入第1个整数:");
int num1 = input.nextInt();
System.out.print("请输入第2个整数:");
int num2 = input.nextInt();
System.out.print("请输入第3个整数:");
int num3 = input.nextInt();
/*
方式二:先考虑2个,再考虑第3个
num1 <= num2
num3插入到3个位置
num1 <= num2 <= num3
num3 <= num1 <= num2
num1 <= num3 <= num2
num1 > num2
num3插入到3个位置
num2 <= num1 <= num3
num3 <= num2 <= num1
num2 <= num3 <= num1
*/
if(num1 <= num2){
if( num2 <= num3){//num1 <= num2 <= num3
System.out.println(num1 + "<=" + num2 + "<=" + num3);
}else if(num3 <= num1){//num3 <= num1 <= num2
System.out.println(num3 + "<=" + num1 + "<=" + num2);
}else{//num1 <= num3 <= num2
System.out.println(num1 + "<=" + num3 + "<=" + num2);
}
}else{//相当于num2 < num1
if(num1 <= num3){//num2 <= num1 <= num3
System.out.println(num2 + "<=" + num1 + "<=" + num3);
}else if(num3 <= num2){//num3 <= num2 <= num1
System.out.println(num3 + "<=" + num2 + "<=" + num1);
}else{//num2 <= num3 <= num1
System.out.println(num2 + "<=" + num3 + "<=" + num1);
}
}
input.close();
}
}
3.4.5多个单分支和1个多分支的区别
对比:
多个单分支 和 一个多分支
多个单分支:
if(){
}
if(){
}
if(){
}
...
一个多分支:
if(){
}else if(){
}else if(){
}
...
多个单分支:不定项选择,可能是1个答案,可能是多个答案
一个多分支:无论选项有多少个,答案只有1个
代码:
import java.util.Scanner;
class TestIfs{
public static void main(String[] args){
/*
从键盘输入一个整数:
(1)判断它是否是3的倍数
(2)判断它是否是偶数
(3)判断它是否是5的倍数
思考:这多个条件是只能满足1个呢?还是多个可能都满足?
*/
Scanner input = new Scanner(System.in);
System.out.print("请输入一个整数:");
int num = input.nextInt();
if(num%3==0){
System.out.println(num + "是3的倍数");
}
if(num%2==0){
System.out.println(num + "是2的倍数,是偶数");
}
if(num%5==0){
System.out.println(num + "是5的倍数");
}
System.out.println("=================");
if(num%3==0){
System.out.println(num +"是3的倍数");
}else if(num%2==0){
System.out.println(num +"是2的倍数,是偶数");
}else if(num%5==0){
System.out.println(num +"是5的倍数");
}
input.close();
}
}
3.5选择结构
分支结构除了if...else系列,还有另一种,就是switch...case。
通常把if...else叫做条件判断。
通常把switch...case叫做选择结构。
switch...case的语法结构:
switch(表达式){
case 常量值1:
语句块1;
【break;】
case 常量值2:
语句块2;
【break;】
....
【default:
语句块n+1;
【break;】
】
}
执行的特点:
(1)入口
A:先用switch()中的值和case后面的值进行从上往下匹配,
匹配上谁了,就从这个case进入执行。
B:当所有的case都不满足时,看一下是否存在default入口,
如果有default分支,就从default进入。
(2)出口
A:switch的结束 }
B:中断出口:break等
(3)贯穿/穿透
从入口进入switch结构执行后,在遇到出口之前,
会从一个case/default分支贯穿到下面的其他分支,
一直到出口。
注意:
(1)如果每一个分支都有break,那么各个分支的顺序无所谓。
如果存在某些分支没有break,那么分支的顺序就很重要。
(2)case后面必须是空格,然后是”常量值或常量表达式”,
不能是变量值
(3)而且所有case的常量值不能重复
(4)switch()中的值只能是
byte,short,int,char 4种基本数据类型,
String(JDK7之后)、枚举(JDK5之后)两种引用数据类型。
代码:
import java.util.Scanner;
class TestSwitchCase{
public static void main(String[] args){
//从键盘输入1-7的星期的数字,然后输出对应星期的单词
Scanner input = new Scanner(System.in);
System.out.print("请输入星期的数字(1-7):");
long week = input.nextInt();
//final int a = 1;
switch(week){
//case a:
case 1:
System.out.println("Monday");
break;
/*default:
System.out.println("输入有误");
break;*/
case 2:
System.out.println("Tuesday ");
break;
case 3:
System.out.println("Wednesday");
break;
case 4:
System.out.println("Thursday");
break;
case 5:
System.out.println("Friday");
break;
case 6:
System.out.println("Saturday");
break;
case 7:
System.out.println("Sunday");
break;
/*
default:
System.out.println("输入有误");
break;//这里break可以去掉 */
}
input.close();
}
}
3.6条件判断和选择结构的对比
3.6.1 案例一:两种代码不相上下
if...else和switch...case的对比:
(1)用if...else和switch...case都可以
代码:
import java.util.Scanner;
class TestIfAndSwitch{
//请输入月份值,然后输出对应的季节
//3,4,5 春季,6,7,8 夏季,9,10,11秋季 12,1,2冬季
public static void main(String[] args){
Scanner input = new Scanner(System.in);
System.out.print("请输入月份:");
int month = input.nextInt();
if(month==3 || month==4 || month==5){
System.out.println("春季");
}else if(month==6 || month==7 || month==8){
System.out.println("夏季");
}else if(month==9 || month==10 || month==11){
System.out.println("秋季");
}else if(month==12 || month==1 || month==2){
System.out.println("冬季");
}else{
System.out.println("输入有误!");
}
System.out.println("----------------");
switch(month){
case 3:
case 4:
case 5:
System.out.println("春季");
break;
case 6:
case 7:
case 8:
System.out.println("夏季");
break;
case 9:
case 10:
case 11:
System.out.println("秋季");
break;
case 12:
case 1:
case 2:
System.out.println("冬季");
break;
default:
System.out.println("输入有误!");
}
System.out.println("---------------");
//Java12的写法
/*
switch(month){
case 3||4||5://||是短路或,只针对boolean类型,逻辑运算符
System.out.println("春季");
break;
case 6||7||8:
System.out.println("夏季");
break;
case 9||10||11:
System.out.println("秋季");
break;
case 12||1||2:
System.out.println("冬季");
break;
default:
System.out.println("输入有误!");
}*/
/*
switch(month){
case 3|4|5://|是按位或
// 011 | 100 | 101 结果是 111
//case 7 :
System.out.println("春季");
break;
case 6|7|8:// 0110 | 0111 | 1000 结果是1111,
//case 15:
System.out.println("夏季");
break;
case 9|10|11://1001 | 1010 | 1011 结果是1011
//case 11:
System.out.println("秋季");
break;
//case 12|1|2://1100 | 0001 | 0010 结果是1111
//case 15:
//System.out.println("冬季");
//break;
default:
System.out.println("输入有误!");
}
*/
/*
switch(month){
case 3,4,5://Java8不允许这样写
System.out.println("春季");
break;
case 6,7,8:
System.out.println("夏季");
break;
case 9,10,11:
System.out.println("秋季");
break;
case 12,1,2:
System.out.println("冬季");
break;
default:
System.out.println("输入有误!");
}*/
input.close();
}
}
3.6.2 案例二:switch更胜一筹
if...else和switch...case的对比:
(1)用if...else和switch...case都可以
(2)使用if...else可以完成,但是麻烦,
使用switch...case显得更加的清晰和简洁
代码:
import java.util.Scanner;
class TestIfAndSwitch2{
//从键盘输入年、月、日,请输入这一天是这一年的第几天
public static void main(String[] args){
Scanner input = new Scanner(System.in);
System.out.print("请输入年份:");
int year = input.nextInt();
System.out.print("请输入月份:");
int month = input.nextInt();
System.out.print("请输入日期:");
int day = input.nextInt();
//假设上面输入的年、月、日都正确
/*
计算这一天是这一年的第几天?
(1)第month月的day天
(2)[1, month-1]月的满月天数
例如:
输入2022年8月9日
(1)9天
(2)1-7月的满月天数
31+29/28+31+30+31+30+31
*/
int days = day;//days初始化为day天,相当于第month月的day天已经加完了
//后面只要在days现在值的基础上,累加上[1, month-1]月的满月天数
/*
if(month==2){//例如:输入2022年2月5日
days += 31;//1月份总天数
}else if(month == 3){//例如:输入2022年3月5日
days += 31 + 28;//1和2月份总天数
if(year是闰年){
days++;
}
}else if(month == 4){//例如:输入2022年4月5日
days += 31 + 28 + 31;//1和2、3月份总天数
if(year是闰年){
days++;
}
}*/
switch(month){
case 12:
days += 30;//11月份总天数
case 11:
days += 31;//10月份总天数
case 10:
days += 30;//9月份总天数
case 9:
days += 31;//8月份总天数
case 8:
days += 31;//7月份总天数
case 7:
days += 30;//6月份总天数
case 6:
days += 31;//5月份总天数
case 5:
days += 30;//4月份总天数
case 4:
days += 31;//3月份总天数
case 3:
days += 28;//2月份总天数
if(year % 4 == 0 && year%100 != 0 || year%400 == 0){
days++;
}
case 2:
days += 31;//1月份总天数
}
System.out.print(year + "年" + month +"月" + day + "日");
System.out.println("这一天是这一年的第" + days +"天");
input.close();
}
}
3.6.3 案例三:switch...case无能为力
if...else和switch...case的对比:
(1)用if...else和switch...case都可以
(2)使用if...else可以完成,但是麻烦,
使用switch...case显得更加的清晰和简洁
(3)只能使用if
结论:
凡是可以使用switch...case,一定可以使用if...else,
但是反过来不行。
即if...else 比 switch...case的使用面更广
只有少数场景使用switch...case才可以简化代码,
要求变量/表达式值 的比较是固定的几个常量值比较时,
才可以选择使用switch...case。
代码:
import java.util.Scanner;
class TestIfAndSwitch3{
//从键盘输入一个整数,判断是正数、负数、还是零。
public static void main(String[] args){
Scanner input = new Scanner(System.in);
System.out.print("请输入整数:");
int num = input.nextInt();
if(num > 0){
System.out.println("正数");
}else if(num<0){
System.out.println("负数");
}else{
System.out.println("零");
}
input.close();
}
}