三种基本流程结构
1. 顺序结构
2.分支结构
3.循环结构
顺序结构
程序从上到下逐行地执行,中间没有任何判断和跳转。
分支结构
根据条件,选择性地执行某段代码。
有if...else和switch-case两种分支语句。
1.分支结构中的if-else(条件判断结构)
一、三种结构
第一种:
if(条件表达式){
执行表达式1
}
第二种:二选一
if(条件表达式){
执行表达式1
}else{
执行表达式2
}
第三种:n选一
if(条件表达式){
执行表达式1
}else if{
执行表达式2
}else if{
执行表达式3
}
...
else{
执行表达式n
}
2.分支结构中的switch-case
switch(表达式){
case 常量1:
语句1;
//break;
case 常量2:
语句2;
//break;
case 常量3:
语句3;
//break;
... ...
case 常量n
语句n;
//break;
default:
语句;
//break;
}
循环结构
根据循环条件,重复性的执行某段代码。
有while、do... while、for三种循环语句。
四个组成部分:
1.初始化部分(init_statement)
2.循环条件部分(test_exp)
3.循环体部分(body_statement)
4.迭代部分(alter_statement)
循环结构的4个要素
①初始化条件
②循环条件--->是boolean类型
③循环体
④迭代条件
1.for循环结构
for(①;②;④){
③
}
执行顺序:① → ② → ③ → ④ → ② → ③ → ④ → ② → ③ → ④ → ②
2.while循环结构
①
while(②){
③;
④;
}
执行顺序:① → ② → ③ → ④ → ② → ③ → ④ → ② → ③ → ④ → ②
说明:
1.写while循环千万小心不要丢了迭代条件。一旦丢了,就可能导致死循环!
2.我们写程序,要避免出现死循环
3.for循环和while循环是可以相互转换的!
区别:for循环和while循环的初始化条件部分的作用范围不同。
3.do...while循环结构
①
do{
③;
④;
}while(②);
执行顺序:① → ③ → ④ → ② → ③ → ④→ ② → ③→ ④→ ②
说明:
1.do-while循环至少会执行一次循环体!
2.开发中,使用for和while更多一些。较少使用do-while
注意:JDK1.5提供了foreach循环,方便的遍历集合、数组元素。
嵌套循环
嵌套循环的使用
1.嵌套循环:将一个循环结构A声明在另一个循环结构B的循环体中,就构成了嵌套循环
2.外层循环:循环结构B
内层循环:循环结构A
3.说明:
①内层循环结构遍历一遍,只相当于外层循环循环体执行了一次
②假设外层循环需要执行m次,内层循环需要执行n次。此时内层循环的循环体一共执行了m *n次
4.技巧:
外层循环控制行数,内层循环控制列数
break和continue关键字的使用
使用范围 | 循环中使用的作用(不同点) | 相同点 | |
break: | switch-case | ||
循环结构中 | 结束当前循环 | 关键字后面不能声明执行 | |
continue: | 循环结构中 | 结束当次循环 | 关键字后面不能声明执行语句 |
附加:如何从键盘获取不同类型的变量:需要使用Scanner类
1.导包:import java.util.Scanner;
2.Scanner的实例化:Scanner scan = new Scanner(System.in);
3.调用Scanner类的相关方法(next() / nextXxx()),来获取指定类型的变量
Scanner scan = new Scanner(System.in);
System.out.println("请输入你的姓名:");
String name = scan.next();
System.out.println("name = " + name);
System.out.println("请输入你的年龄:");
int age = scan.nextInt();
System.out.println("age = " + age);
System.out.println("请输入你的体重:");
double weight = scan.nextDouble();
System.out.println("weight = " + weight + "KG");
System.out.println("你是否相中我了呢?(true/false)");
boolean isLove = scan.nextBoolean();
System.out.println("isLove = " + isLove);
System.out.println("你的性别是男是女呢?");
String gender = scan.next();
char genderChar = gender.charAt(0);
System.out.println(genderChar);
注意:需要根据相应的方法,来输入指定类型的值。如果输入的数据类型与要求的类型不匹配时,会报异常: InputNisNatchException导致程序终止。
分支结构
案例1(if...else)
/*
* 岳小鹏参加Java考试,他和父亲岳不群达成承诺:如果:
* 成绩为100分时,奖励一辆BMW;
* 成绩为(80,99]时,奖励一台iphone xs max;当成绩为[60,80]时,奖励一个iPad;
* 其它时,什么奖励也没有。
* 请从键盘输入岳小鹏的期末成绩,并加以判断
*/
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("请输入岳小鹏的Java考试成绩:");
int chengji = scan.nextInt();
if(chengji == 100){
System.out.println("奖励一辆BMW");
}else if (chengji > 80 && chengji <= 99){
System.out.println("奖励一台iphone xs max");
}else if (chengji >= 60 && chengji <= 80) {
System.out.println("奖励一个iPad");
}else {
System.out.println("什么奖励也没有");
}
}
说明:
1. else结构是可选的(可以将else注释掉)。
2.针对于条件表达式:
〉如果多个条件表达式之间是“互斥”关系(或没有交集的关系),哪个判断和执行语句声明在上面还是下面,无所谓。
〉如果多个条件表达式之间有交集的关系,需要根据实际情况,考虑清楚应该将哪个结构声明在上面。
〉如果多个条件表达式之间有包含的关系,通常情况下,需要将范围小的声明在范围大的上面。否则,范围小的就没机会执行了
案例二(if...else)
/*
*编写程序:由键盘输入三个整数分别存入变量num1、num2、num3
* 对它们进行排序(使用if-else if-else),并且从小到大输出。
*/
Scanner scan = new Scanner(System.in);
System.out.println("请输入变量num1:");
int num1 = scan.nextInt();
System.out.println("请输入变量num2:");
int num2 = scan.nextInt();
System.out.println("请输入变量num3:");
int num3 = scan.nextInt();
if (num1 >= num2){
if (num1 >= num3){
if (num2 >= num3){
System.out.println(num3 + "," + num2 + "," + num1);
}else {
System.out.println(num2 + "," + num3 + "," + num1);
}
}else {
System.out.println(num2 + "," + num1 + "," + num3);
}
}else {
if (num2 >= num3){
if (num1 >= num3){
System.out.println(num3 + "," + num1 + "," + num2);
}else {
System.out.println(num1 + "," + num3 + "," + num2);
}
}else {
System.out.println(num1 + "," + num2 + "," + num3);
}
}
说明:
1.if-else结构是可以相互嵌套的。
2.如果if-else结构中的执行语句只有一行时,对应的一对可以省略的。但是,不建议大家省略。
练习1(if...else)
/*
*我家的狗5岁了,5岁的狗相当于人类多大呢?其实,狗的前两年每一年相当于人类的10.5岁,
* 之后每增加一年就增加四岁。那么5岁的狗相当于人的多少岁?
*/
Scanner scan = new Scanner(System.in);
System.out.println("请输入狗的年龄:");
int dogAge = scan.nextInt();
if (dogAge > 0 && dogAge <= 2){
System.out.println("狗的年龄相当于人的" + dogAge*10.5 + "岁");
}else if (dogAge > 2){
System.out.println("狗的年龄相当于人的" + (21 + (dogAge-2)*4) + "岁");
}else {
System.out.println("请输入正确的值!");
}
练习2(if...else)
/*
*假设你想开发一个玩彩票的游戏,程序随机地产生一个两位数的彩票,提示用户输入一个两位数,然后按照下面的规则判定用户是否能赢。
* 1)如果用户输入的数匹配彩票的实际顺序,奖金10000美元。
* 2)如果用户输入的所有数字匹配彩票的所有数字,但顺序不一致,奖金3000美元。
* 3)如果用户输入的一个数字仅满足顺序情况下匹配彩票的一个数字,奖金1000美元
* 4)如果用户输入的一个数字仅满足非顺序情况下匹配彩票的一个数字,奖金500美
* 5)如果用户输入的数字没有匹配任何一个数字,则彩票作废。
*提示:使用(int)(Math.random() * 90 +10)产生随机数。
*Math.random() : [0,1) * 90 →>[0,90)+10>[10,100)>[10,99]
*/
int caiPiao = (int)((Math.random() * 90) + 10);
// int caiPiao = 38;
Scanner scan = new Scanner(System.in);
System.out.println("请输入一个两位数为你的彩票:");
int userCaiPiao = scan.nextInt();
if (userCaiPiao == caiPiao){
System.out.println("恭喜你获得10000美元奖金" + "," + "中将彩票号是:" + caiPiao);
}else {
if((userCaiPiao / 10 ) == (caiPiao % 10) && (userCaiPiao % 10) == (caiPiao /10)){
System.out.println("恭喜你获得3000美元奖金" + "," + "中将彩票号是:" + caiPiao);
}else if ((userCaiPiao / 10 ) == (caiPiao / 10) || (userCaiPiao % 10) == (caiPiao %10)){
System.out.println("恭喜你获得1000美元奖金" + "," + "中将彩票号是:" + caiPiao);
}else if ((userCaiPiao / 10 ) == (caiPiao %10) || (userCaiPiao % 10) == (caiPiao / 10)){
System.out.println("恭喜你获得500美元奖金" + "," + "中将彩票号是:" + caiPiao);
}else {
System.out.println("很遗憾,您的彩票作废了!" "," + "中将彩票号是:" + caiPiao);
}
}
注意:公式:[a,b] : (int)(Math.random() *(b - a +1) + a)
练习3(if...else)
/*
*大家都知道,男大当婚,女大当嫁。那么女方家长要嫁女儿,当然要提出一定的条件:高:180cm以上:富:财富1千万以上;帅:是。
*如果这三个条件同时满足,则:“我一定要嫁给他!!!”
*如果三个条件有为真的情况,则:“嫁吧,比上不足,比下有余。”>如果三个条件都不满足,则:“不嫁!”
* 提示:Sysout(“身高: (cm))
* scanner.nextlnt();
* Sysout(“财富:(千万))scanner.nextDouble();
* Sysout(“帅否:(true/false))(是/否)
* scanner.nextBoolean(); scanner.next();“是".equals(str)
*/
Scanner scan = new Scanner(System.in);
System.out.println("请问你身高多少(cm): ");
int high = scan.nextInt();
System.out.println("请问你财富有多少(千万): ");
double money = scan.nextDouble();
System.out.println("请问你帅吗(是/否): ");
String face = scan.next();
if (high >= 180 && money >= 1.0 && face.equals("是")){
System.out.println("我一定要嫁给他!!!");
}else if (high < 180 && money < 1.0 && face.equals("否")){
System.out.println("不嫁!");
}else {
System.out.println("嫁吧,比上不足,比下有余。");
}
案例1(switch-case)
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.break,可以使用在Iwitch-case结构中,表示一旦执行到此关键字,就跳出switch-case结构
3.switch结构中的表达式,只能是如下的6种数据类型之一: byte . short、char、 int、枚举类型(jdk5.0新增)、String类型(jdk7.0新增)
4.case之后只能声明常量。不能声明范围
5.break关键字是可选的(不加也不会报错)
6.default:相当于if-else结构中的else,default结构也是可选的,而且位置是灵活的
案例2(switch-case)
/*
*对学生成绩大于60分的,输出“合格”。低于60分的,输出“不合格”。
*/
int score = 78;
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;
}
说明:如果switch-case结构中的多个case的执行语句相同,则可以考虑进行合并。
例子(switch-case)
/*
*编写程序:从键盘上输入2019年的“month”和“day”,
* 要求通过程序输出输入的日期为2019年的第几天。
*/
Scanner scan = new Scanner(System.in);
System.out.println("请输入2019年的month: ");
int month = scan.nextInt();
System.out.println("请输入2019年的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;
case 2:
sumDays += 31;
case 1:
sumDays += day;
}
System.out.println("2019年" + month + "月" + day+ "日是当年的第" + sumDays + "天");
说明:break在switch-case中是可选的
总结:
1.凡是可以使用switch-case的结构,都可以传换为if-else。反之,不成立。
2.我们写分支结构时,当发现既可以使用switch-case,(同时switch中表达式的取值情况不太多),又可以使用if-else时,我们优先选择使用switch-case。原因:switch-case执行效率稍高。
循环结构
案例1(for)
/*
编写程序从1循环到150,并在每行打印一个值,另外在每个3的倍数行上打印出“foo”,
在每个5的倍数行上打印“biz”,
在每个7的倍数行上打印输出“baz”。
*/
for (int i = 0;i <= 150;i++){
System.out.print(i + " ");
if (i % 3 == 0){
System.out.print("foo ");
}
if (i % 5 == 0){
System.out.print("biz ");
}
if (i % 7 == 0){
System.out.print("baz ");
}
System.out.println();
}
案例2(for)(break的使用)
/*
题目:输入两个正整数m和n,求其最大公约数和最小公倍数。比如:12和20的最大公约数是4,最小公倍数是60。
说明: break关键字的使用
*/
Scanner scan = new Scanner(System.in);
System.out.println("请输入一个正整数:");
int m = scan.nextInt();
System.out.println("请输入另一个正整数:");
int n = scan.nextInt();
//最大公约数
int min = (m <= n) ? m : n;
for (int i = min;i >= 1;i--){
if (m % i == 0 && n % i == 0){
System.out.println("最大公约数为:" + i);
break;
}
}
//最小公倍数
int max = (m >= n) ? m : n;
for (int i = max;i <= m * n;i++){
if (i % m == 0 && i % n == 0){
System.out.println("最小公倍数为:" + i);
break;
}
}
案例(while)
/*
题目:
从键盘读入个数不确定的整数,并判断读入的正数和负数的个数,输入为0时结束程序。
*/
Scanner scan = new Scanner(System.in);
System.out.println("请输入一个整数:");
int zheng = 0;
int fu = 0;
while (true){
int num = scan.nextInt();
if (num > 0){
zheng++;
}else if (num < 0){
fu++;
}else {
break;
}
}
System.out.println("正数有" + zheng + "个");
System.out.println("负数有" + fu + "个");
注意: for(;;){} == while(true)
说明:
1.不在循环条件部分限制次数的结构: for(;;)或while(true)
2.结束循环有几种方式?
方式一:循环条件部分返回false
方式二:在循环体中,执行break
循环嵌套
案例1
/*
打印
*
**
***
****
*****
*/
for (int i = 1;i <= 5;i++){
for (int j = 1;j <= i;j++){
System.out.print("*");
}
System.out.println();
}
案例2
/*
打印菱形
*/
//上半部分
for (int i = 0; i < 5; i++){
//输出"-”
for (int j = 0;j < 4 - i; j++){
System.out.print(" ");
}
//输出“* ”4
for (int k = 0; k < i + 1; k++) {
System.out.print("* ");
}
System.out.println();}
//下半部分
for (int i = 0; i< 4; i++) {
for (int j = 0; j < i + 1; j++) {
System.out.print(" ");
}
for (int k = 0; k < 4 - i; k++) {
System.out.print("* ");
}
System.out.println();
}
案例3
/*
打印九九乘法表
*/
for (int i = 1;i <= 9;i++){
for (int j = 1;j <= i;j++){
System.out.print(i + " * " + j + " = " + (i*j) + " ");
}
System.out.println();
}
案例4
/*
打印100以内的质数
*/
boolean zhishu = true;
int count = 0;
long start = System.currentTimeMillis();
for (int i = 2;i <= 100;i++){
//优化二:对本身是质数的自然数是有效的。
for (int j = 2;j <= Math.sqrt(i);j++){
if (i % j == 0){
zhishu = false;
break;//优化一:只对本身非质数的自然数是有效的。
}
}
if (zhishu == true){
//System.out.println(i);
count++;
}
zhishu = true;
}
long end = System.currentTimeMillis();
System.out.println("质数个数为:" + count);
System.out.println("花费的时间为:" + (end-start));
//方式二(带标签的break和continue的使用)
int count = 0;
long start = System.currentTimeMillis();
label:for (int i = 2;i <= 100;i++){
//优化二:对本身是质数的自然数是有效的。
for (int j = 2;j <= Math.sqrt(i);j++){
if (i % j == 0){
continue label;
}
}
count++;
}
long end = System.currentTimeMillis();
System.out.println("质数个数为:" + count);
System.out.println("花费的时间为:" + (end-start));