目录标题
- 前言
- 1、流程控制
- 1.1 流程控制结构的分类
- 1.2 顺序结构
- 1.3 分支结构
- 1.3.1 if-else语句
- 1.3.2 switch-case结构
- 1.4 循环结构
- 1.4.1 循环语句分类:
- 1.4.2 for循环
- 1.4.3 while 循环
- 1.4.4 do-while循环
- 1.4.5 嵌套循环
- 1.4.6 特殊关键字的使用
- 1.4.6.1 特殊流程控制语句1:break
- 1.4.6.2 特殊流程控制语句2:continue
- 1.4.6.3 特殊流程控制语句3:return
- 1.4.6.4 特殊流程控制语句说明
- 1.4.7 总结:
- 2 循环经典练习题
- 2.1 打印任意行数为n的上直角三角,下直角三角
- 2.2 打印行数为n(奇数)的菱形
- 2.3 其他练习题
前言
本文主要介绍java语言中的流程控制
1、流程控制
流程控制:用来控制程序中各语句执行顺序的语句,可以把语句组合成能完成一定功能的小逻辑模块。
1.1 流程控制结构的分类
①顺序结构:程序从上到下逐行地执行,中间没有任何判断和跳转。
②分支结构:根据条件,选择性地执行某段代码。
③循环结构:在某些条件满足的情况下,反复执行特定代码的功能。
1.2 顺序结构
1.3 分支结构
1.3.1 if-else语句
if-else语句三种格式:
- if(条件表达式){
执行代码块;
}
@Test
public void ifTest() {
int num1=23;
int num2=24;
if(num2>num1) {
System.out.println("num2比num1大");
}
}
- if(条件表达式){
执行代码块1;
}
else{
执行代码块2;
}
@Test
public void ifTest() {
//声明变量并赋值
int num1=23;
int num2=24;
if(num2>num1) {//如果num2>num1,执行下面代码块
System.out.println("num2比num1大");
}else {//否则,执行下面代码块
System.out.println("num2比num1小");
}
}
- if(条件表达式1){
执行代码块1;
}
else if (条件表达式2){
执行代码块2;
}
……
else{
执行代码块n;
}
@Test
public void ifTest() {
//声明变量并赋值
int age = 75;
if (age< 0) {
System.out.println("不可能!");
} else if (age>250) {
System.out.println("是个妖怪!");
} else {
System.out.println("人家芳龄 " + age +" ,妥妥的美少驴啦!");
}
}
if-else使用说明:
- 条件表达式必须是布尔表达式(关系表达式或逻辑表达式)、布尔变量
- 语句块只有一条执行语句时,一对{}可以省略,但建议保留
- if-else语句结构,根据需要可以嵌套使用
- 当if-else结构是“多选一”时,最后的else是可选的,根据需要可以省略
- 当多个条件是“互斥”关系时,条件判断语句及执行语句间顺序无所谓
- 当多个条件是“包含”关系时,“小上大下 / 子上父下”,使用if语句,先处理包含范围更小的情况,会使代码更加简单。
- 当if后的语句块中,只有一条语句的时候,{} 可以省略。但建议不省略。
1.3.2 switch-case结构
switch语句由一个控制表达式和多个case标签组成。
switch(表达式){
case 常量1:
语句1;
// break;
case 常量2:
语句2;
// break;
… …
case 常量N:
语句N;
// break;
default:
语句;
// break;
}
说明:
- switch(表达式)中表达式的值必须是下述几种类型之一:byte,short,
char,int,枚举 (jdk 5.0),String (jdk 7.0),不能是Long类型、boolean类型、浮点型、StringBuilder和StringBuffer类; - case子句中的值必须是常量,不能是变量名或不确定的表达式值;
- 同一个switch语句,所有case子句中的常量值互不相同;
- break语句用来在执行完一个case分支后使程序跳出switch语句块;如 果没有break,程序会顺序执行到switch结尾。
- default子句是可任选的。同时,位置也是灵活的。当没有匹配的case时,执行default。
@Test
public void switchCaseTest() {
//变量声明
int i = 1;
//执行switch分支
switch (i) {
case 0:
System.out.println("zero");
break;
case 1:
System.out.println("one");
break;
default:
System.out.println("default");
break;
}
}
1.4 循环结构
循环结构:在某些条件满足的情况下,反复执行特定代码的功能。
1.4.1 循环语句分类:
- for 循环
- while 循环
- do-while 循环
循环语句的四个组成部分:
- 初始化部分(init_statement) :一条或多条语句,这些语句用于完成一些初始化工作,初始化语句在循环开始之前执行。
- 循环条件部分(test_exp) :一个boolean表达式,这个表达式能决定是否执行循环体。
- 循环体部分(body_statement) :如果循环条件允许,这个代码块将被重复执行。如果这个代码块只有一行语句,则这个代码块的花括号是可以省略的。
- 迭代部分(alter_statement):一次循环体执行结束后,对循环条件求值之前执行,通常用于控制循环条件中的变量,使得循环在合适的时候结束。
1.4.2 for循环
语法格式:
for (①初始化部分; ②循环条件部分; ④迭代部分){
③循环体部分;
}
执行过程: ①-②-③-④-②-③-④-②-③-④-…-②
说明:
- ②循环条件部分为boolean类型表达式,当值为false时,退出循环
- ①初始化部分可以声明多个变量,但必须是同一个类型,用逗号分隔
- ④可以有多个变量更新,用逗号分隔
- 循环体语句如果是一条语句,大括号可以省略(建议不要省略括号)
for循环的变形:
表达式1
for(;表达式2;){
循环体;
表达式3;
}
@Test
public void forTest() {
/*打印1-100之间13的倍数,使用for循环*/
for (int i = 1; i <= 100; i++) {
if (i%13==0) {
System.out.println(i);
}
}
System.out.println("循环结束!");
}
1.4.3 while 循环
语法格式:
①初始化部分
while(②循环条件部分){
③循环体部分;
④迭代部分;
}
执行过程:①-②-③-④-②-③-④-②-③-④-…-②
说明:
- 注意不要忘记声明④迭代部分。否则,循环将不能结束,变成死循环。
- for循环和while循环可以相互转换
while的结束条件:
- 在循环体当中定义使表达式趋于false的式子。
- 在while循环体当中可以定义break关键字。结束break关键字所在的循环。
return。但是return表示结束整个方法,return所在的循环和之后的语句都不会执行了,所以慎用。 - System.exit(int status)方法,会结束整个线程,慎用。Main方法中return和exit效果是一样的。
@Test
public void whileTest() {
int result = 0;
int i = 1;
while (i <= 100) {
result += i;
i++;
}
System.out.println("result=" + result);
}
1.4.4 do-while循环
语法格式:
①初始化部分;
do{
③循环体部分
④迭代部分
}while(②循环条件部分);
执行过程:①-③-④-②-③-④-②-③-④-…②
说明:
- do-while循环至少执行一次循环体。
@Test
public void doWhileTest() {
int result = 0;
int i = 1;
do {
result += i;
i++;
} while (i <= 100);
System.out.println("result=" + result);
}
1.4.5 嵌套循环
嵌套循环(多重循环):
- 将一个循环放在另一个循环体内,就形成了嵌套循环。其中,for ,while ,do…while均可以作为外层循环或内层循环。
- 实质上,嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的 循环条件为false时,才会完全跳出内层循环,才可结束外层的当次循环,开 始下一次的循环。
- 设外层循环次数为m次,内层为n次,则内层循环体实际上需要执行m*n次。
@Test
public void forTest1() {
/*打印九九乘法表*/
for (int j = 1; j <= 9; j++) {
for (int k = 1; k <= j; k++) {
System.out.print(k+"*"+j+"="+j*k+"\t");
}
System.out.println();
}
}
1.4.6 特殊关键字的使用
1.4.6.1 特殊流程控制语句1:break
break 语句:
- break语句用于终止某个语句块的执行
{
……
break;
……
}
- break语句出现在多层嵌套的语句块中时,可以通过标签指明要终止的是
哪一层语句块
label1: { ……
label2: { ……
label3: { ……
break label2;
……
}
}
}
示例代码:
@Test
public void forTest2() {
for (int i = 0; i < 10; i++) {
if (i == 3)
break;
System.out.println(" i =" + i);
}
System.out.println("Game Over!");
}
1.4.6.2 特殊流程控制语句2:continue
continue 语句:
- continue只能使用在循环结构中
- continue语句用于跳过其所在循环语句块的一次执行,继续下一次循环
- continue语句出现在多层嵌套的循环语句体中时,可以通过标签指明要跳过的是哪一层循环
示例代码:
@Test
public void forTest2() {
for (int i = 0; i < 10; i++) {
if (i == 3)
continue;
System.out.println(" i =" + i);
}
System.out.println("Game Over!");
}
1.4.6.3 特殊流程控制语句3:return
return 语句:
- return:并非专门用于结束循环的,它的功能是结束一个方法。 当一个方法执行到一个return语句时,这个方法将被结束。
- 与break和continue不同的是,return直接结束整个方法,不管这个return处于多少层循环之内。
1.4.6.4 特殊流程控制语句说明
① break只能用于switch语句和循环语句中。
② continue 只能用于循环语句中。
③ 二者功能类似,但continue是终止本次循环,break是终止本层循环。break、continue之后不能有其他的语句,因为程序永远不会执行其后的语句。
④ 标号语句必须紧接在循环的头部。标号语句不能用在非循环语句的前面。很多语言都有goto语句,goto语句可以随意将控制转移到程序中的任意一条 语句上,然后执行它,但使程序容易出错。Java中的break和continue是不同 于goto的。
1.4.7 总结:
while循环和for循环的使用时机:
(1)当明确循环次数,有限使用for循环。
(2)不明确循环次数的前提下,只能使用while循环。
(3) while(true){} 如果要使用无限循环,使用while。
键盘的录入:
(1)导包: import java.util.Scanner;
(2)创建对象: Scanner sc = new Scanner(System.in);
(3)调用对象的方法:
sc.nextInt(); //接收键盘录入的int类型的
sc.nextDouble(); //接收小数
next(); //接收一个String类型。
nextLine();
2.1 打印任意行数为n的上直角三角,下直角三角
@Test
public void forTest3() {
//打印任意行数为n的上直角三角,下直角三角
/*
* *
**
***
****
*****
*/
Scanner scanner = new Scanner(System.in);
int i = scanner.nextInt();
for (int k = 0; k < i; k++) {
for (int j = 0; j < k + 1; j++) {
System.out.print("*");
}
System.out.println();
}
System.out.println("--------------------------------");
/*
*
*****
****
***
**
*
*/
for (int k = i; k > 0; k--) {
for (int j = k; j > 0; j--) {
System.out.print("*");
}
System.out.println();
}
}
2.2 打印行数为n(奇数)的菱形
@Test
public void forTest3() {
// 打印实心菱形
Scanner scanner = new Scanner(System.in);
// 行数
int n = scanner.nextInt();
for (int j = 0; j < n; j++) {
// 空白
// 求绝对值:Math.abs(i / 2 - j)
for (int k = 0; k < Math.abs(n / 2 - j); k++) {
System.out.print(" ");
}
// *
for (int k = 0; k < n - 2 * Math.abs(n / 2 - j); k++) {
System.out.print("*");
}
System.out.println();
}
System.out.println("------------------------");
// 打印空心菱形
for (int j = 0; j < n; j++) {
// 空白
for (int k = 0; k < Math.abs(n / 2 - j); k++) {
System.out.print(" ");
}
// *+空白
for (int k = 0; k < n - 2 * Math.abs(n / 2 - j); k++) {
if (k == 0 || k == n - 2 * Math.abs(n / 2 - j) - 1) {
System.out.print("*");
} else {
System.out.print(" ");
}
}
System.out.println();
}
}
2.3 其他练习题
@Test
public void forTest3() {
// 判断年份:
Scanner sc = new Scanner(System.in);
System.out.println("请输入年份:");
int year = sc.nextInt();
System.out.println("=========================");
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
System.out.println(year + "是闰年!");
} else {
System.out.println(year + "是平年!");
}
/*斐波那契数列:
1 1 2 3 5 8 13 21 34 ...*/
int m = 1;
int n = 1;
int k = m + n;
System.out.println(m);
System.out.println(n);
while (k <= 100000) {
System.out.println(k);
m = n;
n = k;
k = m + n;
}
// 水仙花数:
int m1, n1, k1;
for (int i = 100; i <= 999; i++) {
m1 = i / 100;
n1 = i % 100 / 10;
k1 = i % 10;
if (i == m1 * m1 * m1 + n1 * n1 * n1 + k1 * k1 * k1) {
System.out.println("水仙花数:" + i);
}
}
}
@Test
public void forTest4() {
/*输入两个正整数m和n,求其最大公约数和最小公倍数*/
Scanner sc = new Scanner(System.in);
System.out.println("请输入两个整数:");
int m = sc.nextInt();
int n = sc.nextInt();
int min = (m < n) ? m : n;
int max = (m > n) ? m : n;
// 求最大公约数
//最大公约数不会大于最小的正整数,通过三目运算获得最小整数,然后从大往小取余,第一个能够把两个整数取余的数就是最大公约数
for (int i = min; i >= 1; i--) {
if (m % i == 0 && n % i == 0) {
System.out.println(m + "和" + n + "的最大公约数:" + i);
break;
}
}
// 求最小公倍数
//最大公倍数不会大于两个整数的乘积,肯定大于等于最大整数,
//通过三目运算获得最大整数,然后从小往大取余,第一个能够被两个整数取余为0的数就是最大公约数
for (int i = max; i <= m * n; i++) {
if (i % m == 0 && i % n == 0) {
System.out.println(m + "和" + n + "的最小公倍数:" + i);
break;
}
}
/*100以内的所有质数*/
//质数:只能能1和本身整除的自然数
//从2开始,到这个数-1结束为止,都不能被这个数本身整除。
long start = System.currentTimeMillis();
//设置采用标志位的时候,循环中使用的时候,注意标志位的重置
boolean isFlag = true;// 标识i是否被j除尽,一旦除尽,修改其值
for (int i = 2; i <= 100000; i++) {
for (int j = 2; j <= Math.sqrt(i); j++) {// 优化二:对本身是质数的自然数是有效的。
if (i % j == 0) {
isFlag = false;
break;// 只对本身非质数的自然数是有效的。
}
}
if (isFlag) {
System.out.println(i);
}
// 重置
isFlag = true;
}
long end = System.currentTimeMillis();
System.out.println((end - start) + " ms");
}