第四章 控制结构

在前面的章节中,我们已经学习了数据类型和变量来存储数据,然后学习了运算符和表达式,使用他们可以简单的对数据进行算术运算,以及使用关系运算和逻辑运算来进行条件判断,但这些还远远不能够完整复杂的数据处理。接下来我们要学习的是控制结构,它能够控制程序的执行流程,可以让我们根据不同的条件对数据做不同的处理。这种结构化程序可以由顺序,分支,循环三种组成。

顺序结构是一种最简单的基本结构,其执行过程就是从上到下一次执行每行代码。在我们之前写的所有代码,都是顺序结构。这种结构我们就不再讲解了。

分支结构的程序根据判断条件的不同执行不同的代码块。代码块就是由一对花括号包裹的多行代码。分支结构的语法如下:

if ( 表达式 )

        代码块1

else

        代码块2

这里的“表达式”就是使用关系运算或逻辑运算组成的表达式,它的结果是一个布尔(boolean)结果。如果这个结果是真(true),就执行“代码块1”,如果结果为假(false),就执行“代码块2”。请注意,if 和 else 都是java语言的关键字,该结构可以没有else的部分。我们根据之前的优秀学生的例子,来讲解if-else分支结构的使用,代码如下:

		// 优秀学生的判断
		int yuwen = 92, shuxue = 98;
		if(yuwen > 90 & shuxue > 90)
			System.out.println("是优秀学生");
		else
			System.out.println("不是优秀学生");

如果我们的“代码块”中只有一行代码的时候,外面的花括号可以不用写。

另外,if-else的代码块中,还可以继续嵌套新的if-else结构,这样可以处理更复杂的数据判断,但是大家一定要注意花括号的前后对应关系。为了能够让我们直观的看到这种里外关系,我们一般在花括号的地方都会使用“Tab”键进行缩格。也就是说,if里面的代码块不能和if对齐,而是要缩进去一格,表示他们的“父子”关系。这不是Java语法规定的,而是编码规范。否则大家都把代码堆砌在一起,根本没法阅读理解。

在实际开发过程中,我们还可能这样使用if-else结构,如下:

		// 星期几的判断
		int week = 2;
		if(week == 1)
			System.out.println("星期一");
		else if(week == 2)
			System.out.println("星期二");
		else if(week == 3)
			System.out.println("星期三");
		else if(week == 4)
			System.out.println("星期四");
		else if(week == 5)
			System.out.println("星期五");
		else if(week == 6)
			System.out.println("星期六");
		else if(week == 7)
			System.out.println("星期日");
		else
			System.out.println("不知道");

对于少量的情况来讲,这种if-else结构使用起来非常的方便。但是,如果需要判断的条件情况比较多的话,我们使用if-else结构进行代码编写的话,阅读起来就不是很友好啦。接下来,我们介绍另一个分支结构,switch-case结构。其实这个switch-case是对if-else结构的补充。我们上面的条件判断是周几,也就是说最多会有8种可能(加上“不知道”),但是如果是判断每个月的几号的话,我们就需要连续使用else-if多达30多次,在代码简洁上,不是很好。这个时候,我们就需要借助 switch-case结构了,代码如下:

		// 星期几的判断
		switch(week){
			case 1: 
				System.out.println("星期一");
				break;
			case 2:
				System.out.println("星期二");
				break;
			case 3:
				System.out.println("星期三");
				break;
			case 4: 
				System.out.println("星期四");
				break;
			case 5:
				System.out.println("星期五");
				break;
			case 6:
				System.out.println("星期六");
				break;
			case 7:
				System.out.println("星期日");
				break;
			default: 
				System.out.println("不知道");
		}

在上面的代码中,紫色的switch,cash,default,break都是java关键字,都有特殊的含义。switch后面的括号里面就是条件,但是这个条件比较特殊,它不是关系运算或逻辑运算,而是byte,short,int,char四种类型之一,如果是其他类型的话,就会编译报错。case后面的值就对应了switch括号里面变量的可能值。如果switch括号中的变量值匹配到了某个case后面的值,就会执行其后面的代码,直到通过break关键字而结束。因为有了break结束标识,因此case后面一般,我们就不需要添加花括号进行代码代码包裹了。如果switch括号中的变量值都没有匹配到case后面的值,那么就会执行default后面的代码,default基本都会放在最后面,因此也就不需要添加break关键字了。这就是switch-case的分支结构,虽然该结构使用场景比较苛刻,但是在日常的编程中,还是能够使用到的。

循环结构的程序是根据判断条件是否成立,不断重复执行某个代码块。这是编程语言中非常强大的结构,正是因为循环结构的出现,才可能将我们日常中那些简单重复的枯燥的工作交由计算机来完成,解放人类的大脑和双手。循环控制语句有三种:计数型循环语句(for语句),当型循环语句(while语句)和直到型循环语句(do…while语句)。除此之外,还有break,continue语句用于结束所有循环和结束本次循环。下面是for循环语句的语法:

for ( 表达式1; 表达式2; 表达式3 )

循环体代码块

for循环结构是如何让计算机重复执行“循环体代码块”的呢?一般情况下,我们使用for循环结构的时候,都会使用“循环变量”来控制其“循环体代码块”执行的次数。假如,我们想让“循环体代码块”执行100次,那么我们可以定义一个循环变量i,然后让这个循环变量i从1一直递增到100,然后结束,这样就会递增100次,也就执行100次循环体代码块了。这样的代码要求,我们通过for循环结构如下实现:

		// 循环100次
		for(int i=1; i<=100; i++){
			System.out.println(i);
		}

我们根据上面的代码示例以及下面的语法结构来讲解for循环结构是如何执行的。

for ( 表达式1; 表达式2; 表达式3 )

循环体代码块

首先,执行表达式1,也就是 int i=1; 这个表达式只会执行一次哦!然后再执行表达式2,它明显是一个关系运算表达式,该表达式的结果是一个布尔变量,如果这个布尔变量值是ture,那么就执行一次循环体代码块,紧接着,会执行表达式3,也就是i++,那么i的数值由原来的1递增为2,然后再执行表达式2,也就是关系运算表达式,根据它的结果再次执行循环体表达式。这样不断的重复执行表达式3和表达式2,然后根据表达式2的结果来执行循环体代码块。这样需要注意的是,当i的值等于101的时候,表达式2的结果为false,就不会执行循环体代码块了,整个循环就彻底结束了。

那么,我们根据循环变量i的数值变化,就能推算出循环体代码块执行了100次。很显然,你已经被上面的描述搞晕了,如果脑子一片混乱的话,就把它忘记吧。我们只需要计算循环变量的数值,来推算重复执行次数即可。也就是说,我们只看for括号中的三个表达式即可:int i=1;  i<=100;  i++

我们可以看到循环变量i从1开始,i++的话,每次递增1,这样i的数值就是1,2,3,4…什么时候结束呢?就是 i<=100,也就是说i的最大有效值是100,那么i从1递增到100的话,共计100次,因此循环体代码会执行100次。

这里,还需要大家注意的是,我们在循环体内经常会使用整个循环变量i的,i是不断递增变化的,也就是说,每次循环体代码块中使用的i值是不一样的。第一次循环使用i的值是1,第二次循环使用i的值是2,以此类推。假如,我们现在有一个需求,要求计算1+2+3+4+…+98+99+100的结果,如何实现?

		// 累加1到100的和
		int he = 0;
		for(int i=1; i<=100; i++){
			he += i;
		}
		System.out.println(he);

我们首先定义整型变量he来存储结果,然后使用循环结构来实现。循环变量i从1递增到100,在循环体内,每次累加i到变量he中,这样经过100次循环之后,就能得到正确结果了。最后我们输出出来,就是最后的结果5050.

接下来,我们接收while循环结构,相对于for循环结构,它的语法非常的简单,如下:

while ( 表达式 )

循环体代码块

上面的“表达式”为循环条件,可以是任意合法的逻辑或关系表达式。如果表达式的结果为true,则执行循环体代码块,然后再次计算表达式结果,如果为true,则继续执行循环体代码块,如果为false的话,则结束循环。

一般情况下,循环体代码块中都会有影响“表达式”结果的代码语句。否则,表达式一直都是true的话,计算机将永远执行循环体代码块了。但是,如果第一次计算表达式的值就是false的话,那么循环体代码块那永远不会执行了,循环也就自然结束了!我们同样以累加1-100的和为示例,使用while循环结构来实现:

		// 累加1到100和
		int j = 1, he2 = 0;
		while(j <= 100){
			
			he2 += j++;
		}
		System.out.println(he2);

同样,我们还是定义了循环变量j和和变量he2,然后使用while循环结构进行累加。我们的循环条件是 j <= 100 ,我们可想而知,这个循环变量j仍然是从1到100的递增。如何实现循环变量从1递增到100的呢?肯定是在循环体代码块中实现。虽然循环体代码块中只有以及代码,但是含义还是比较复杂的。我们可以大概理解就是把j累加到he2中,然后再让j自增+1。这里我们要正确理解j++的含义,它确实让j值加1,但是该表达式返回的值是j没有加1的之前的值。如果是++j的话,它也能让j值加1,但是该表达式返回的值是j加1后的结果值,由于我们让j的初始值为1,因此如果我们使用 he2 += ++j; 的话,第一次循环的时候he2累加的值就是2,不是1,显然这是不对的。当然如果我们就必须使用 ++j 的话,我们可以让j的初始值为0,这样第一次循环的时候,he2累加的值就是1了。从这短短的几行代码中,我们可以看出,编程是一件非常严谨的事情,任何细小的变化都可能导致结果不正确。提醒大家,粗心大意的人还是不要学习编程了!

接下来我们继续讲解do-while循环结构,它的语法格式如下:

do

循环体语句

while (表达式)

do-while的循环结构和while循环结构大致相同,区别在于do…while的循环体语句至少会执行一次,尽管表达式的结果值是false。因为它是先执行循环体,然后在判断循环表达式。因此,我们不再介绍do-while循环结构了。我们可以根据实际的情况来选择使用do-while的循环结构还是while循环结构!

这里再次提醒大家的是,在循环结构中,一定要有退出循环的条件能够出现,否则就是无限循环(死循环),无限循环很可能会导致内存溢出,造成程序崩溃。我们之前还提到了两个关键字:continue和break。他们分别代表退出本次循环和所有循环。两者都是强制执行,不受循环条件的影响。我们举例如下:

		// continue使用
		for(int i=1; i<=5; i++){
			
			if(i==3) continue;
			System.out.println(i);
		}
		
		// break使用
		for(int i=1; i<=5; i++){
			
			if(i==3) break;
			System.out.println(i);
		}	

在上面的两组示例中,我们都让循环执行5次,每次循环输出循环变量i,可想而知,结果应该是1,2,3,4,5出现在屏幕上。但是,我们在两组中添加了退出判断。第一组在循环到i==3的时候,就使用continue退出本次循环,后面的代码不再执行,而直接进入到下一次循环。因此它的实际运行结果是输出1,2,4,5到屏幕上,没有数字3啦。而break就更狠了,直接退出所有循环了,它的实际运行效果是输出1,2到屏幕上,后面就下文了。

在上面的示例代码中,我们可以看到,在循环体代码块中,我们嵌套使用了if分支结构,这是允许的。实际上,分支结构和循环结构是可以随意进行嵌套的。在循环嵌套的案例中,最经典的莫过于打印99乘法表了。我们先来看代码允许的结果:

我们观察九九乘法表,它由9行构成,每1行的列数不一样,但有规律,比如第1行就有1列,第2行就有2列,依次类推,第9行就有9列。我们通过一个循环结构无法实现,比如借助循环嵌套的方式来实现,外层循环是行,内层循环是列。假如,我们外层循环变量是i,那么我们就可以让i从1递增到9,表示有9行。内层循环的是列,每行的列数不同,它不是一个固定循环次数。这也没关系,我们通过上述规律就能发现,每列的循环次数,其实就是外层循环变量i的次数,也就是说,如果外层循环变量i是第3行的话,那么内层循环变量j的值应该是1到i,也就是3列啦。剩下的就是代码实现了:

public class Hello {
	
	public static void main(String[] arg){
				
		// i 代表第一个乘数,从1-9循环次数
		for(int i=1; i<10; i++){
			
			// j 代表第二个乘数,从1-i循环次数
			for(int j=1; j<=i; j++){
				
				// 输出 1 * 1 = 1
				System.out.print(j + " * " + i + " = " + j * i + " ");
			}
			
			// 换行而已
			System.out.println();
		}
	}
}

外层循环变量i代表的是行,它从1-9固定次数。内层循环变量j代表的是列,由于列数不固定,因此我们让变量j从1到i,这样就能巧妙的动态设置列的数量了。最后我们输出乘法式就可以了。这里的print代表不换行的输出,在使用该命令输出完整的一行之后,我们在使用println再进行换行,就能达到一行一行的效果了。大家再细细琢磨吧。

本课程涉及的代码可以免费下载:
https://download.csdn.net/download/richieandndsc/85645935

今天的内容就讲的这里,我们来总结一下。今天我们主要讲了Java的控制结构,它主要用来控制代码的执行流程。顺序结构就是从上到下执行每一行的代码,这个是最简单的。然后就是分支结构,主要是if-else的使用,它的执行方式是根据if的条件结果来决定执行自己的代码块,还是else的代码块。其实if-else结构就是为了实现“如果…否则…”逻辑方式。紧接着,我们介绍了循环结构,主要是for和while两种。for循环结构可以根据循环变量来变化来得出循环次数,因此称之为记数型循环结构。提醒大家,活用循环变量对我们日后编程帮助很大。while的语法比较简单,使用也比较广泛。在我们日常编程中,这些控制结构不是孤立使用的,基本上都是相互嵌套使用。好的,谢谢大家的收看,欢迎大家在下方留言,我也会及时回复大家的留言的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值