本小节开始我们开学时学习控制流程语句,控制流程语句在程序设计中占据非常重要的地位,通过这次学习我们应该能够了解java的控制语句的概念,掌握条件语句、循环语句和跳转语句的用法,并能使用Java控制语句解决简单的数学问题和应用问题。
1.分支【选择】结构
条件语句是程序中根据条件是否成立进行选择执行的一类语句。在Java语言中,条件语句主要有两类语法:if语句和switch语句,下面分别进行介绍
1.1if语句
if语句(单一条件)
该类语句的语法格式为:
if (表达式) {
执行语句块;
}
if语句的代码执行过程为:如果条件表达式返回真值,则执行功能代码块中的语句;如果条件表达式返回值为假,则不执行功能代码块。
执行流程如下图所示:
语法说明:
1. if是该语句中的关键字,后续小括号不可省略;
2. 条件表达式返回的结果为布尔型,当返回为真值时才能执行if功能代码;
3. 功能代码块为多行时,应将其放在花括号"{}"中间,当功能代码块为单行时,则不需要花括号;
4. 不论if语句块是单行还是多行,建议都用花括号"{}"括起来;
5. if()子句后不能跟分号";"
例 if语句的执行。
public class If_sample1 {
public static void main(String args[]){
int x = 0;
if(x==1){
System.out.println("x等于1");
}
System.out.println("x的值为"+x);
}
}
if语句(二选一)
在程序的执行过程中,if语句只执行条件表达式返回值为真时的操作。但如果需要返回值为真或假时都执行各自相应操作,就可以使用if-else语句来完成。if-else语句语法如下:
if(条件表达式){
功能代码块1
}else{
功能代码块2
}
if-else语句的代码执行过程为:当条件表达式返回值为真时,执行功能代码块1,当条件表达式返回值为假时,执行else后面的功能代码2。与if语句法格式相同,如果功能代码1和2只有一句,则不需要加花括号"{}"。
执行流程如下图所示
语法说明:
1. if-else语句的代码执行过程等价于 三目条件运算符,变量 = 布尔表达式 ? 语句1:语句2
2. 如果布尔表达式的值为true,则执行语句1;如果布尔表达式的值为false,则执行语句2
例 if-else语句的执行。
public class If_Sample2 {
public static void main(String[] args) {
int n = 7;
if (n % 2 != 0) {
System.out.println("n是奇数");
System.out.println("条件表达式返回值为真");
} else {
System.out.println("n不是奇数");
System.out.println("条件表达式返回值为假");
}
}
}
当有多个if在程序的语句中存在时,else与最近的if匹配。例如:
if(条件表达式1){
功能代码块1;
}
if(条件表达式2){
功能代码块2;
}else{
功能代码块3;
}
其中,else对应条件表达式2,条件表达式1的if语句将独立执行。
if语句(多选一)
当条件为多个时,Java提供了专门的多分支if- else if -else语句以实现条件的多重选择,多分支语句的语法如下:
if(条件表达式1){
功能代码块1;
}else if(条件表达式2){
功能代码块2;
}else if(条件表达式3){
功能代码块3;
... ...
}else{
功能代码块n;
}
多重选择的if语句的执行流程如下图所示。
多选一的if语句执行流程
语法说明:
1. else if是else和if两个关键字,中间使用空格进行间隔;
2. 条件表达式返回值都是布尔类型;
3. else if语句可以有任意多句;
4. 最后的else语句为可选;
5. 如果功能代码部分只有一条语句而不是语句块,花括号"{}"可以省略。
if-else if-else语句的代码执行过程为:
1.当条件表达式1返回值为真时,则执行功能代码块1;
2.当条件表达式1返回值为假时且条件表达式2返回值为真时,则执行功能代码块2;
3.如果条件表达式1、条件表达式2都返回假且条件表达式3返回值为真,则执行功能代码块3,
4.依次类推,如果所有条件都不成立,则执行else语句的功能代码。
例 使用if-else if-else语句实现百分制成绩到成绩等级的转换。
public class If_Sample3{
public static void main(String args[]) {
int i = 55;
if (i <= 100 && i >= 90) {
System.out.println("成绩是A");
} else if (i >= 80) {
System.out.println("成绩是B");
} else if (i >= 70) {
System.out.println("成绩是C");
} else if (i >= 60) {
System.out.println("成绩是D");
} else {
System.out.println("成绩是E");
}
}
}
1.2 switch语句
switch语句从多种情况中选择一种执行,在结构上比if语句要清晰很多。switch语句的语法格式如下:
switch(表达式){
case 取值1:
语句块1;
[break;]
case 取值2:
语句块2;
[break;]
......
case 取值n:
语句块n;
[break;]
default:
语句块n+1;
}
语法说明:
表达式的类型只能为byte、short、char、int,在JDK7中增加了对String类型的支持;
case语句是标号语句,只确定程序的入口;
值1、值2......值n只能为常数或常量,不能为变量,而且值不能重复;
功能代码部分可以写任意多句;
break关键字结束switch语句,为可选项;
default语句功能类似于if-else语句中的else。
switch语句的代码执行过程为:
将case语句后的值和表达式的值比较,若相等即从该case语句开始向下执行,如果没有break语句,则一直执行到switch语句的结束,如果遇到break语句,则结束switch语句的执行。
例 使用switch语句实现多重选择。
public class Switch_sample1 {
public static void main(String args[]) {
int n = 2;
int result;
switch (n) {
case 1:
System.out.println("Block A");
result = n;
break;
case 2:
System.out.println("Block B");
result = n * n;
break;
case 3:
System.out.println("Block C");
result = n * n * n;
break;
default:
result = 0;
break;
}
System.out.println("result="+result);
}
}
2 循环结构
为什么我们要学习循环结构呢?现在我们来解决一个问题,比如,请输出三行“***”,在我们没有学习循环结构之前,我们只能写出这样的代码:
public class App {
public static void main(String[] args) {
System.out.println("***");
System.out.println("***");
System.out.println("***");
}
}
我们发现一个问题,如果想要输出10086行的话,我们只能去打10086边这行代码,那么我们能不能简洁一些呢?这时候我们就要用到循环结构。
循环结构是指在程序中需要反复执行某个功能而设置的一种程序结构。需要被反复执行的这段代码称为循环体,它由循环结构中的循环条件决定是继续执行循环体还是终止循环。根据判断条件,循环结构又可细分为以下两种形式:
先判断后执行的循环结构
先执行后判断的循环结构。
在Java语言中,实现循环结构的语句有三种,分别是while语句、do-while语句和for语句。
2.1whlie语句
whlie
while(循环条件){
循环体;
}
while语句的代码执行过程为:
首先判断循环条件,如果循环条件为true,则执行循环体代码,然后再判断循环条件,直到循环条件不成立时停止执行。如果首先判断循环条件就为false,则不执行循环体,直接执行while语句后续的代码。
语法说明:
1. 循环条件的类型为布尔类型,指循环成立的条件;
2. 花括号{}不是必须的,当循环体中只有一条语句时,可以省略;
3. 循环体是需要重复执行的代码。
例 使用while语句输出x的值。
public class While_sample {
public static void main(String args[]){
int x=1;
while(x<3){
System.out.println("x="+x);
x++;
}
}
}
同样是上面的代码,调整内部代码的顺序,程序的执行结果会发生变化吗?下面通过下面的例子来看一下。
例 使用while语句输出x的值。
public class While_sample {
public static void main(String args[]){
int x=1;
while(x<3){
x++;
System.out.println("x="+x);
}
}
}
由上面的程序可以看出,修改了x++的位置,程序的执行结果就不同了,所以在循环语句中,代码之间的顺序会影响整个程序的逻辑,书写时特别注意。
例 使用while语句计算1+2+3+...+10的和。
public class While_Sum {
public static void main(String args[]) {
int i = 1;
int sum = 0;
while (i <= 10) {
sum += i;
i++;
}
System.out.println("1+2+...+10=" + sum);
}
}
例 使用while语句计算从1到100的所有奇数相加。
public class While_OddSum {
public static void main(String args[]) {
int i = 1;
int sum = 0;
while (i <= 100) {
if(i%2!=0)
sum += i;
i++;
}
System.out.println("1到100之间的奇数和为" + sum);
}
}
2.2do-whlie语句
do-while语句的语法格式为:
do{
循环体;
}while(循环条件);
do-while语句的执行流程如下图所示。
语法说明:
循环体是重复执行的代码部分,循环条件要求是布尔类型,值为true时执行循环体,否则循环结束,最后整个语句以分号结束;
do-while语句是 "先循环再判断"的流程控制结构。
例 使用do-while语句输出x的值。
class DoWhile_sample {
public static void main(String args[]){
int x=3;
do{
System.out.println("x="+x);
x++;
} while(x<3);
}
}
例 使用do-while语句计算从1到100的所有奇数相加。
class DoWhile_OddSum {
public static void main(String args[]) {
int i = 1;
int sum = 0;
do {
if (i % 2 != 0)
sum += i;
i++;
} while (i <= 100);
System.out.println("1到100之间的奇数和为" + sum);
}
}
2.3 for语句
现在我们再次回顾一下前文的案例
public class While_Sum {
public static void main(String args[]) {
int i = 1;
int sum = 0;
while (i <= 10) {
sum += i;
i++;
}
System.out.println("1+2+...+10=" + sum);
}
}
其中:第三行代码是准备循环变量,第五行是使用循环变量控制循环次数,第七行是改变循环变量实现计数,这就导致与while语句的与循环变量有密切关系的三条语句过于分散,不利于程序编写与阅读,我们可以使用
for语句使的这些内容更加紧凑,更方便阅读。
在Java语言中,和其它主流语言C、C++或者Python一样,也支持For语句。
for语句的语法格式为:
for(表达式1;表达式2;表达式3){
循环体;
}
for语句的结构和执行流程如下图所示。
语法说明:
表达式1用于初始化,一般书写变量初始化的代码,例如循环变量的声明、赋值等,它在for语句中执行且只执行一次。表达式1可以为空;
表达式2是循环条件,要求必须为布尔类型,如果该条件为空,则默认为true,即条件成立;
表达式3为迭代语句,是指循环变量变化的语句,一般书写i++、i--这样的结构。该语句可以为空。
循环体指循环重复执行的功能代码。
花括号{}不是必须的,当循环体部分只有一条语句时可以省略。
例 使用for语句输出x的值。
public class For_Sample {
public static void main(String[] args) {
for(int x=1;x<3;x++){
System.out.println("x="+x);
}
}
}
例 用for循环改写从1到100的所有奇数相加的和。
public class For_OddSum {
public static void main(String args[]) {
int sum = 0;
for (int i = 1; i <= 100; i++) {
if (i % 2 != 0)
sum += i;
}
System.out.println("1到100之间的奇数和为" + sum);
}
}
2.4 死循环
环语句中如果循环条件永远为真,那么这样的循环就是死循环。死循环的破坏力极强,导致软件的其它功能无法执行,而且只能通过杀死线程、结束进程等方法被动解除,所以一般情况下都要在代码中避免死循环的出现。
由于死循环识别算法实现困难,所以,当前任何编译系统都不做死循环检查,因此在开发过程中需要程序员认真对待,做到绝对避免。
课堂练习:下图是两个死循环的例子,如下图3.22所示,请说说导致死循环的原因,由如何解决呢?
注意:在某些特定场景,比如温控系统、十字路口的车牌识别系统,使用特定的技术后死循环还是可以存在的,并且发发挥着重要作用。
2.5 嵌套循环
例:问题描述:在控制台中用星号"*"输出如下样式的图形
***
***
***
当没有学习循环语句时,可以使用打印语句实现,实现方式如下。
public class Multiplication_Sample {
public static void main(String args[]) {
System.out.println("***");
System.out.println("***");
System.out.println("***");
}
}
在学习了循环之后可以实现如下。
public class Multiplication_Sample {
public static void main(String args[]) {
for (int i = 1; i<=3; i++) {
System.out.println("***");
}
}
}
如果使用嵌套循环,可以实现如下。
public class Multiplication_Sample {
public static void main(String args[]) {
for (int i = 1; i<=3; i++) {
for (int j = 1; j<=3; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
嵌套循环,程序中常用的一种方法,如果在一个循环语句A中又包含另一个循环语句B,那么语句A就是嵌套循环语句,这种结构称为循环嵌套。内嵌的循环B中还可以嵌套循环C,这就是多层循环。语句A也称为主循环或者外循环,B称为内循环。各种语言中关于循环的嵌套的概念都是一样的。
通过上面的例题可以看出嵌套循环应用的好,避免了相同代码的重复、以及硬编码,可以进行更好的复用和扩展。
例:在控制台打印九九乘法表
编程思路:总结九九乘法表的规律,得出总计9行,第一行有1个数字,第二行有2个数字,依次类推,数字的值为行号和列号的乘积。由于涉及到行与列的相互关系,可以使用嵌套循环,外部循环控制行数,内部循环解决如何输出每行的数值。
public class MultiplicationTable1 {
public static void main(String[] args) {
for(int i=1;i<=9;i++) // 外循环
{
for(int j=1; j<=i;j++) // 内循环
{
System.out.print(i+"*"+j+"="+i*j+"\t");
}
System.out.println();//换行
}
}
}
运行结果如下图所示。
2.6 循环的中断
在使用循环语句时,只有循环条件表达式的值为false时,才能结束循环。有时,想提前中断循环,要实现这一点,只需要在循环语句块中添加break或continue语句。
break语句
在前面switch语句的介绍中已经接触过break语句,其功能是中断switch语句的执行。同样,break语句可以出现在while、do...while、for循环等语句中,能够立即结束本循环语句的执行。
例 break语句的简单练习。
请计算一个最小整数N,使得1+2+3...+N的和大于666首次成立。
public class Break_Sample1 {
public static void main(String[] args) {
int i, sum=0;
for (i = 1; i < 101; i++) {
sum += i;
if (sum >= 666) {
break;
}
}
System.out.println("从1到" + i + "的和为" + sum);
}
}
运行结果如下图所示。
例 break语句在循环嵌套中的使用。
编写代码,实现以下结果。
public class Break_Sample2 {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
System.out.print(j+" ");
if (j == 5) {
break;
}
}
System.out.print("\n");
}
}
}
运行结果如下图所示。
break label语句可以出现在任何语句体中,其作用是结束指定语句的执行。【了解】
例 带标签的break语句。
public class Break_Sample3 {
public static void main(String[] args) {
label1: for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
System.out.print(j+" ");
if (j == 5) {
break label1;
}
}
}
}
}
运行结果如下图3.27所示。
Continue语句
continue语句只能出现在循环结构中,也完成循环的终止。但与break语句的区别在于:continue语句只跳出一次循环,整个语句还继续执行;break语句则完全跳出它所在或所标记的循环。下面以while语句为例,来说明continue语句的功能。
例 显示20以内的奇数。
public class Continue_Sample1 {
public static void main(String[] args) {
for (int i = 1; i < 20; i++) {
if ((i % 2) == 0) {
continue;
}
System.out.print(i + " ");
}
}
}
运行结果如下图3.29所示。
例 continue语句的简单使用。
public class Continue_Sample2 {
public static void main(String[] args) {
int i = 0;
while (i < 5) {
i++;
if (i == 3) {
continue;
}
System.out.println(i);
}
}
}
该代码的执行结果为:
1
2
4
5
continue label语句可以出现在任何语句体中,其作用是结束指定循环语句的当前循环次的执行。【了解】
例 带标签的continue语句。
public class Continue_Sample3 {
public static void main(String[] args) {
label1: for (int i = 0; i < 10; i++) {
System.out.print("\n");
for (int j = 0; j < 10; j++) {
System.out.print(j + " ");
if (j == 5) {
continue label1;
}
}
}
}
}
运行结果如下图所示。
这样在执行continue语句时,就不再是终止内部循环中的本次循环,而是直接终止外部循环的本次循环,执行i++语句,进入下一次外部循环。