一、程序控制
1.顺序控制
程序从上到下执行,程序默认的控制方法
//java中定义变量时,采取合法的向前引用原则
//即先定义后使用
int num1 = 12;
int num2 = num1 + 2;
2.分支控制
让程序有选择的执行
1.单分支
if(条件表达式){
执行代码块;
}
若条件表达式为真,执行大括号中的语句
否则直接跳出
2.双分支
if(条件表达式) {
执行代码块1;
}
else {
执行代码块2;
}
//下面是双分支语句的练习
int x = 7;
int y = 4;
if(x > 5) {
if(y > 5) {
System.out.println(x + y);//条件不成立,不输出
}
System.out.println("溪溪是帅哥~");//输出
} else
System.out.println("x is " + x);//条件不成立,不输出
3.多分支
if(条件表达式1) {
执行代码块1;
}
else if(条件表达式2) {
执行代码块2;
}
……
else {
执行代码块n;
}
最多只有一个执行入口,也可以没有else,如果所有的条件表达式都不成立,一个执行入口都没有
boolean b = true;
if(b == false)
System.out.println("a");
else if(b)
System.out.println("b");//最终输出
else if(!b)
System.out.println("c");
else
System.out.println("d");
boolean b = true;
if(b = false)
System.out.println("a");
else if(b)
System.out.println("b");
else if(!b)
System.out.println("c");//最终输出
else
System.out.println("d");
4.嵌套分支
if() {
if() {
//if -else…
}
}
嵌套不要超过三层(可读性不好)
import java.util.Scanner;
public class NestedIf {
//编写一个main方法
public static void main(String[] args) {
//参加歌手比赛,如果初赛成绩大于8.0进入决赛
//否则提示淘汰,并根据性别提示进入男子组或女子组
Scanner scanner = new Scanner(System.in);
double score = scanner.nextDouble();
char gender = scanner.next().charAt(0);
if(score > 8.0) {
System.out.println("进入决赛");
if(gender == '男') {
System.out.println("进入男子组");
} else if(gender == '女') {
System.out.println("进入女子组");
}
} else {
System.out.println("不好意思,您被淘汰");
}
}
}
5.switch分支结构
-
Switch关键字,表示Switch分支
-
如果匹配到case xx,则执行其中的语句
-
如果没有匹配到,则往下面是否匹配
-
如果所有的都没有匹配上,则默认执行default语句块
-
如果执行完语句块后没有发现break语句,则自动执行下面的语句,即Switch语句
//使用Switch语句,确定输入的a-g匹配周一到周日 Scanner scanner = new Scanner(System.in); char c1 = scanner.next().charAt(0); switch(c1) { case 'a': { System.out.println("今天星期一,猴子穿新衣"); } case 'b': { System.out.println("今天星期二,猴子当小二"); //case 'c'-'g'...... default: { System.out.println("输入的什么玩意儿,溪帅哥都瞧不起你"); } } }
switch语句细节注意
-
表达式数据类型,应和case后的常量类型一致,或者可以自动转换成可以相互比较的类型
-
Switch语句的表达式返回值必须是==(byte,short,int,char,enum,String)==
-
case子句中的值必须是常量或 常量表达式(计算得到),不能是变量(即使变量已赋值)
-
default语句时可选的,当没有default时,又没有匹配上其他子句,则没有输出
-
如果没有写break,程序会顺序执行到Switch结尾,除非遇到break,default语句也会执行(Switch穿透)
import java.util.Scanner; //使用Switch把小写类型的char转换成大写(键盘输入)。 //只转换a,b,c,d,e.其他输出"other" // public class SwitchExercise { //编写一个main方法 public static void main(String[] args) { Scanner scanner = new Scanner(System.in); char c = scanner.next().charAt(0); switch(c) { case 'a' : { System.out.println("A"); break; } case 'b' : { System.out.println("B"); break; } case 'c' : { System.out.println("C"); break; } case 'd' : { System.out.println("D"); break; } case 'e' : { System.out.println("E"); break; } default : { System.out.println("other"); } } } }
-
3.循环控制
1.for循环语句
1.基本语法
for(循环变量初始化;循环条件;循环变量迭代) {
循环操作(可多条语句);
}
2.基本流程
- 循环变量初始化
- 循环条件(条件为真往下走)
- 循环操作
- 循环变量迭代
- 循环条件……(条件为真往下走)
3.注意事项
1.循环条件返回是一个Boolean值(真或假)
2.for(;循环判断条件;)中的初始化和变量迭代可以写到其他地方,但分号不可省略
for(;😉 {
System.out.println(“
hello”);
}//无限循环
Ctrl + c 退出
int count = 3;
for (int i = 0, j = 0; i < count; i++, j += 2) {
System.out.println("i = " + i + " j = " + j);
//0
}
//打印1~100之间所有9的倍数的整数,统计个数及总和
public class ForExercise {
//编写一个main方法
public static void main(String[] args) {
int count = 0;
int sum = 0;
//编程思想
//1.化繁为简:即将复杂的需求,拆解为简单的需求,逐步完成
//2.先死后活:先考虑固定的值(利于思考),然后转成灵活变化的值
//先死后活
//为了适应更好的需求,把范围开始的值和结束的值做成变量
//还可以把9的倍数也作为变量
//这样就可以根据范围修改变量的值即可,代码实现的范围更广泛
int start = 1;
int end = 100;
int t = 9;
for(int i = start; i <= end; i++) {
//化繁为简
//先输出0-100所有的值
//在确定符合条件的数
int x = i;
if(x % t == 0) {
count++;
sum += x;
}
}
System.out.println("是9的倍数的有 " + count + "个,和是: " + sum);
}
}
2.while循环控制
1.基本语法
while(循环条件) {
循环体(语句);
循环变量的迭代;
}
- while循环也有四要素,只是与for循环的循环条件位置不一样
2.细节分析
- while循环也有四要素
- while循环先判断再执行
public class WhileExercise {
//编写一个main方法
public static void main(String[] args) {
//打印1-100之间所有能被3整除的数
int i = 1;
while(i <= 100) {
if(i % 3 == 0) {
System.out.println(i);
}
i++;
}
}
}
3.do…while循环
- do while是关键字
- 也有循环四要素,只是位置不一样
- 先执行再判断,至少会执行一次
- 最后有一个分号
4.多重循环控制
- 循环最多不要嵌套超过三层,过多影响可读性
- 实质上,嵌套循环就是把内层循环当成外层循环的循环体,当只有内层循环条件为FALSE时才会完全跳出循环体,才可以结束外层循环,开始下一次循环
- 设内层循环次数为m次,内层为n次,则内层循环是实际上需要执行m*n次
1.简单案例
for(int i = 0; i < 2; i++) {
for(int j = 0;j < 3; j++) {
System.out.println("i = " + i + "j = " + j);
}
}
//由上述3可得,这里要执行2*3次循环
//即可以理解为:假若走到内层循环时,内层循环未达到结束条件,会先执行完内层循环,
//再跳出到外层循环的条件判断语句中
//0 0
//0 1
//0 2
//1 0
//1 1
//1 2
2.成绩统计小程序
import java.util.Scanner;
public class MulForExercise {
//编写一个main方法
public static void main(String[] args) {
//统计3个班成绩情况,每个班五个同学
//求出每个班的平均分和所有班级的平均分
//统计三个班及格人数,每个班5名同学
//化繁为简:
//1.先计算一个班,5个学生的成绩,使用for循环
//创建一个scanner对象
//得到平均分,定义一个sum变量,把该班级所有成绩累计起来
//2.统计三个班,每个班五个学生 平均分
//
//3.所有班级平均分
//定义一个变量double totalScore统计所有学生成绩
//当多重循环结束后,totalScore / 15;
//统计三个班的及格人数
//int passNum = 0;当有一个人及格了,就passNum++
//完成基本结构后可以优化(效率、可读性、结构)
Scanner scanner = new Scanner(System.in);
double totalScore = 0;
int passNum = 0;
for(int i = 1; i <=3; i++) {//i表示班级
double sum = 0;//统计当前班级的总分
for(int j = 1; j <=5; j++) {
System.out.println("请输入第" + i + "个班的第" + j + "个学生的成绩");
double score = scanner.nextDouble();
if(score >= 60) {
passNum++;
}
sum += score;//因为sum是总成绩
System.out.println("成绩为" + score);
}
//因为sum是班级成绩总和
System.out.println("sum = " + sum + "平均分 = " + (sum / 5));
//把sum累计到totalScore
totalScore += sum;
}
System.out.println("三个班级的总分 = " + totalScore + " 平均分 = " + (totalScore / 15));
System.out.println("及格人数 = " + passNum);
}
}
3.9*9乘法表
//使用多重循环结构打印出9*9乘法表
public class temp {
//编写一个main方法
public static void main(String[] args) {
for(int i = 1; i <= 9; i++) {
for(int j = 1; j <= i; j++) {
System.out.print(j + " * " + i + " = " + i * j + "\t");
}
System.out.print("\n");
}
}
}
4.金字塔
//使用多重循环打印5层金字塔
//金字塔的打印
public class temp {
//编写一个main方法
//
/*
*的条件 空格的条件
* 第一行 1个* 2*1-1 4 (总层数-当前层)个空格
*** 第二行 3个* 2*2-1 3
***** 第三行 5个* 2*3-1 2
******* 第四行 7个* 2*4-1 1
********** 第五行 9个* 2*5-1 0
*/
/*
镂空金字塔 *的条件
* 第一行 1个* 当前行的第一个位置和最后一个位置都是*
* * 第二行 2个*
* * 第三行 2个*
* * 第四行 2个*
********** 第五行 9个* 最后一行直接全部输出
*/
/*
先死后活
层数5 改成变量int totalLevel;
*/
public static void main(String[] args) {
int totalLevel = 5;
for(int i = 1; i <= totalLevel; i++) {//i表示当前层层数
//在输出*之前还要考虑打印空格
for(int k = 1; k <= totalLevel - i; k++) {
System.out.print(" ");
}
for(int j = 1; j <= 2 * i - 1; j++) {//j表示每层*的个数
if(j == 1 || j == 2 * i - 1 || i == totalLevel) {//第一个位置和最后一个位置单独考虑,包括最后一行的内容是全部输出
System.out.print("*");
} else {
System.out.print(" ");//非特殊位置直接输出空格
}
}
System.out.println("");//每打印完一层*就换行,println会自动换行
}
}
}
1.半个金字塔
2.整个金字塔
3.镂空金字塔
4.镂空金字塔(进阶)
金字塔层数改变(层数自定)
4.break语句
随机生成1-100的一个数,知道生成了97这个数,看看一共用了多少次?
(int)(Math.random()*100)+1
循环,但循环次数未知。此时需要用到break语句,使得当某个条件满足时,终止循环。此时break相当重要。
-
注意事项
-
break出现在多层嵌套语句块中时,可以通过标签指明要终止的是哪一块
-
标签的基本使用
label1:{... label2: {... label3: {... break label2; ... } } }
-
break语句可以指定退出哪一层
label1是标签,名字可以自己随意命名
break后指定到哪个label就退出到哪里
如果没有指定break,默认退出最近的循环体
public class temp {
//编写一个main方法
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) {
break label1;
//如果不加标签,等价退出循环label2;
//会输出 01 01 01 01 01 01 01 01 (次数可以按照内循环*外循环得到 4 * 2)
//若是label1,即只输出一次01 就直接退出外层循环了
}
System.out.println("i = " + i);
}
}
}
}
实现用户登录
import java.util.Scanner;
public class temp {
//编写一个main方法
public static void main(String[] args) {
//实现登录验证,有三次机会
//如果用户输入用户名“溪溪”,密码“666”提示登录成功,否则提示还有几次机会
//
//String name = "贾宝玉";
//System.out.println("林黛玉".equals(name));//使用这种方法来比较两个字符串
int chance = 3;//记录还有几次登录机会
while(true) {
Scanner scanner = new Scanner(System.in);
System.out.println("");
System.out.println("****************");
System.out.println("欢迎来到登录界面");
System.out.println("请输入用户名:");
String userName = scanner.next();//用户输入账户名字
System.out.println("请输入用户名密码:");
String password = scanner.next();//用户输入账户密码
if("溪溪".equals(userName) && "666".equals(password)) {
System.out.println("成功登录,欢迎~");
break;
} else {
chance--;
if(chance != 0) {
System.out.println("密码错误,还有" + chance + "次机会");
}
if(chance == 0) {
System.out.println("系统不可用,请3650天后再试");break;
}
}
}
}
}
5.continue语句
continue语句用于结束本次循环,继续执行下次循环
continue语句出现在多层嵌套语句时,可以通过标签指明跳过的是哪一层循环
//continue示例
public class Continue {
//编写一个main方法
public static void main(String[] args) {
int i = 1;
while(i <= 4) {
i++;
if(i == 2) {
continue;
}
System.out.println("i = " + i);
}
}
}
public class Continue {
//编写一个main方法
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;//等价于continue label2
//0 1 3 4 5 6 7 8 9
//0 1 3 4 5 6 7 8 9
//0 1 3 4 5 6 7 8 9
//0 1 3 4 5 6 7 8 9
// continue label1;
// 0 1
// 0 1
// 0 1
// 0 1
// continue label2;
// 0 1 3 4 5 6 7 8 9
// 0 1 3 4 5 6 7 8 9
// 0 1 3 4 5 6 7 8 9
// 0 1 3 4 5 6 7 8 9
}
System.out.println("i = " + i);
}
}
}
}
6.return语句
使用在方法中,表示跳出所在方法
如果在主方法中,直接跳出程序
public class Return {
//编写一个main方法
public static void main(String[] args) {
for(int i = 1; i <= 5; i++) {
if(i == 3) {
System.out.println("溪溪");
return;//return语句用在方法中,表示跳出方法
//用在主方法中,直接跳出程序
}
System.out.println("Hello World~");
}
System.out.println("go on...");
//最终会输出:
//Hello World~
//Hello World~
//溪溪
}
}
二、习题训练
1.交过路费
溪溪有100000元,每经过一次路口,需要交费,规则如下:
-
当现金>500000时,每次交5%
-
当现金<=500000时,每次交1000
程序编程计算溪溪可以经过多少次路口
public class HomeWork01 {
//编写一个main方法
public static void main(String[] args) {
//溪溪有100000元,每经过一次路口,需要交费,规则如下:
// 1. 当现金>50000时,每次交5%
// 2. 当现金<=50000时,每次交1000
// 3.还有一种情况[0,1000)范围,需要单独考虑,此时已经不能过路了
// 程序编程计算溪溪可以经过多少次路口
int count = 0;//计算通过路口的次数
int money = 100000;
while(true) {
if(money > 50000) {
money *= 0.95;
count++;
} else if(money >= 1000) {
money -= 1000;
count++;
} else {//此时剩余的钱已经不够再过一次路口了
break;
}
}
System.out.println("溪溪可以通过" + count + "个路口");//62
}
}
2.正负还是零
import java.util.Scanner;
public class HomeWork02 {
//编写一个main方法
public static void main(String[] args) {
//实现判断一个整数属于哪个范围:大于0;小于0;等于0
Scanner scanner = new Scanner(System.in);
int input = scanner.nextInt();
if(input > 0) {
System.out.println(input + "大于0");
} else if(input < 0) {
System.out.println(input + "小于0");
} else if(input == 0) {
System.out.println(input + "等于0");
}
}
}
3.是否是闰年
import java.util.Scanner;
public class HomeWork03 {
//编写一个main方法
public static void main(String[] args) {
//判断一个年份是否为闰年
Scanner scanner = new Scanner(System.in);
int year = scanner.nextInt();
if((year % 4 == 0 && year % 100 != 0)||year % 400 == 0) {
System.out.println(year + "是闰年");
} else {
System.out.println(year + "不是闰年");
}
}
}
4.水仙花数
import java.util.Scanner;
public class HomeWork04 {
//编写一个main方法
public static void main(String[] args) {
//判断一个整数是否是水仙花数。
//所谓水仙花数就是一个三位数,
//各个位上的数字立方和等于本身
Scanner scanner = new Scanner(System.in);
int input = scanner.nextInt();
int x = input;
int sum = 0;
while(x > 0) {
int y = x % 10;
sum += y * y * y;
x /= 10;
}
if(sum == input) {
System.out.println(input + "是水仙花数");
} else {
System.out.println(input + "不是水仙花数");
}
}
}
5.案例分析
看看以下代码会输出什么
import java.util.Scanner;
public class HomeWork05 {
//编写一个main方法
public static void main(String[] args) {
int m = 0, n = 3;
if(m > 0) {
if(n > 2)
System.out.println("OK1");
else
System.out.println("OK2");
}
}
}
//不会输出结果
6.按要求输出
import java.util.Scanner;
public class HomeWork06 {
//编写一个main方法
public static void main(String[] args) {
//输出1-100之间的不能被5整除的数,每5个一行
int count = 0;
for(int i = 1; i <= 100; i++) {
if(i % 5 != 0) {
System.out.print(i + " ");
count++;
if(count == 5) {
System.out.println("");
count = 0;
}
}
}
}
}
import java.util.Scanner;
public class HomeWork07 {
//编写一个main方法
public static void main(String[] args) {
//输出小写a-z以及大写Z-A
for(char a = 'a'; a <= 'z'; a++) {
System.out.print(a + " ");
}
System.out.println("");
for(char b = 'Z'; b >= 'A'; b--) {
System.out.print(b + " ");
}
}
}
public class HomeWork08 {
//编写一个main方法
public static void main(String[] args) {
//求出1-1/2+1/3-1/4...1/100的和
double sum = 0;
double x = 0;
for(int i = 1; i <= 100; i++) {
if(i % 2 == 0) {
x = (1.0 / i) * (-1);
} else {
x = 1.0 / i;
}
sum += x;
}
System.out.println("1-1/2+1/3-1/4...1/100的和是" + sum);//0.688172179310195
}
}