第一章 面向对象
第二章 异常
第三章 数组
第四章 常用类
第五章 集合
第六章 IO流
第七章 线程
第八章 反射
第九章 Socket编程

java循环语句之for

 

在不少实际问题中有许多具有规律性的重复操作,因此在程序中就需要重复执行某些语句。一组被重复执行的语句称之为循环体,能否继续重复,取决于循环的终止条件。循环结构是在一定条件下反复执行某段程序的流程结构,被反复执行的程序被称为循环体。循环语句是由循环体及循环的终止条件两部分组成的。

为了帮助大家理解循环语句存在的意义,我们来看一段代码:

 

System.out.println("hello world!");
System.out.println("hello world!");
System.out.println("hello world!");
System.out.println("hello world!");
System.out.println("hello world!");
System.out.println("hello world!");
System.out.println("hello world!");
System.out.println("hello world!");
System.out.println("hello world!");
System.out.println("hello world!");
//...
//...

 

以上程序的业务背景是:输出100行“hello world!”,如果我们像以上方式进行代码编写的话,代码将无法得到重复使用,大家也可以看到“System.out.println("hello world!")”这行代码重复出现,直到输出100个为止。显然程序应该找一种更好的实现方式,这个时候我们就可以借助java语言中的循环语句来实现了。

java中的循环语句共包括三个,分别是:for循环、while循环、do..while循环,接下来我们先来学习for循环。

for循环的语法格式如下图所示:

 

图6-13:for循环语法结构

 

对以上for循环语法结构进行说明:初始化表达式最先执行,并且在整个循环当中初始化表达式只执行一次,布尔表达式结果是true或者false,true表示循环可以继续执行,false表示循环结束,循环体当中的代码就是需要反复执行的代码,更新表达式一般是用来更新某个变量的值,更新操作之后可能布尔表达式的结果就不再是true了。那么for循环的执行顺序以及原理如下图所示:

 

图6-14:for循环语句执行顺序及原理

 

对于for循环来说,初始化表达式、布尔表达式、更新表达式都不是必须的,当布尔表达式缺失的时候,没有条件控制的前提下,会形成死循环,我们来看一下最简单的for循环形式:

 

for(;;){
	System.out.print("死循环、");
}

 

执行结果如下图所示:

 

图6-15:死循环输出结果

 

最常见的for循环是怎样的呢?看以下代码:

 

for(int i = 1; i <= 10; i++){
	System.out.println("i = " + i);
}

 

运行结果如下图所示:

 

图6-16:for循环输出1~10

 

对以上代码进行分析:首先执行int i = 1,并且只执行一次,定义初始化变量i,赋值1,然后判断i <= 10结果为true,则执行循环体打印i = 1,循环体结束之后,执行i++,然后i变成了2,继续判断i <= 10结果为true,则执行循环体打印i = 2,如此循环执行,直到打印i = 10之后,再执行i++让i变成了11,然后判断i <= 10结果为false,循环结束,这样就完成了1~10的输出,当然程序不是固定的,大家也可以把条件i <= 10修改为i < 11,这样也是可以的。

关于for循环的使用我们还需要注意初始化变量的作用域,在for循环当中声明的变量只在for循环中有效,当for循环结束之后,初始化变量的内存就释放了/消失了,所以在for循环之外是无法访问该变量的,例如以下代码在编译的时候就会报错了:

 

//在for循环内部声明的变量i只在for循环中可见/有效
for(int i = 1; i <= 10; i++){
	System.out.println("i = " + i);
}
//这行编译报错,i变量不存在
System.out.println("i = " + i);

 

当然,这样写就不会报错了:

 

public static void test(){
	//变量的声明位置放到了for循环之外
	int i = 1;
	for(; i <= 10; i++){
		System.out.println("i = " + i);
	}
	//这里就可以访问变量i了
	System.out.println("i = " + i);
}

 

为什么这样写就可以了呢?那是因为i变量的作用域已经被扩大了,不再只是for循环中可以使用,for循环之外也可以使用,换句话说,以上的for循环结束之后i变量的内存并不会被释放。后续的程序可以继续使用。i变量的作用域是在整个test()方法中都有效,直到test()方法执行结束的时候才会释放i变量的内存空间。

接下来我们再来看看for循环还有哪些其它的写法:

 

for(int i = 10; i > 0; i--){
	System.out.println("i = " + i);
}
System.out.println("-------------分割线---------------");
for(int i = 10; i > 0; i -= 2){
	System.out.println("i = " + i);
}
System.out.println("-------------分割线---------------");
for(int i = 100; i >= 10; i /= 3){
	System.out.println("i = " + i);
}

 

以上程序运行结果,请看下图:

 

图6-17:for循环的其它编写方式执行结果

 

接下来,我们再使用for循环实现1~100所有数字的求和,实现思路是:定义变量i,初始值从1开始,每循环一次加1,这样就可以取到1~100的每一个整数了,那么求和怎么做呢?求和就是将1~100的每一个整数累加,这必然需要提前定义一个变量,使用变量实现累加,例如:a += 1,a += 2,a += 3...,代码如下所示:

 

int sum = 0;
for(int i = 1; i <= 100; i++){
	sum += i;
}
System.out.println("sum = " + sum);

 

运行结果如下所示:

 

图6-18:1~100所有整数求和

 

通过以上程序我们可以学到什么?编程语言当中的累加可以使用扩展类赋值运算符+=来实现,另外sum变量为什么定义到for循环外面,而不是定义到循环体当中呢?那是因为当定义到循环体内之后,每一次循环体在执行的时候,都会重新定义sum变量,这样会让sum变量归0,无法达到累加的效果。

接下来,我们在以上程序的基础之上实现1~100所有奇数的和,编程思路是:在累加之前先判断变量i是否为奇数,如果是奇数则累加,这就需要在sum += i外面套一个if语句进行控制,代码如下所示:

 

int sum = 0;
for(int i = 1; i <= 100; i++){
	if(i % 2 != 0){
		sum += i;
	}
}
System.out.println("sum = " + sum);

 

运行结果如下所示:

 

图6-19:1~100所有奇数和的执行结果

 

其实以上的方式是将每一个数字取出来,然后再判断是否为奇数,这种方式会导致循环次数达到100次,实际上可以换成另外一种解决方案,假设从1开始,每次累加2,那么每次取出的数字为1,3,5...,这样正好每次取出的数字都是奇数,可以直接累加了,这样循环的次数基本上会减半,效率则提高了,这种代码既优雅,又高效。请看以下代码:

 

int sum = 0;
for(int i = 1; i < 100; i += 2){
	sum += i;
}
System.out.println("sum = " + sum);

 

运行结果如下所示:

 

图6-20:1~100所有奇数和的执行结果

 

以上演示的所有循环都是单层的,循环当中可以嵌套循环吗?答案是:当然可以,之前我们就说过所有控制语句都是可以嵌套使用的,当循环A中嵌套循环B的时候就等于在A循环体中的代码是B循环。其实大家在学习循环嵌套的时候完全没必要特殊化对待,完全可以把A循环体当中的B循环看做是一段普通的java代码。接下来我们看一段代码:

 

//循环5次(B循环)
for(int i = 1;i <= 5; i++){
	System.out.print("i = " + i + ",");
}

System.out.println();

//循环2次(A循环)
for(int j = 1;j <= 2; j++){
	System.out.print("j = " + j + ",");
}

System.out.println();

//将B循环放到A循环体当中
for(int j = 1;j <= 2; j++){ //A循环(2次)
	
	for(int i = 1;i <= 5; i++){ //B循环(5次)
		
		System.out.print("i = " + i + ",");
		
	}
}

 

运行结果如下图所示:

 

图6-21:for循环嵌套

 

分析以上for循环嵌套,请看下图:

 

图6-22:for循环嵌套分析

 

分析循环嵌套的小窍门,如下图所示:

 

图6-23:for循环嵌套小窍门

 

学习了for循环嵌套的使用,我们一起来写一下经典的九九乘法表,九九乘法表的结构大家还记得吗,我们一起来回顾一下小学的知识(嘿嘿):

 

图6-24:九九乘法表结构

 

通过观察九九乘法表结构我们可以看出来它有9行,所以可以得出一定需要以下代码:

 

public static void main(String[] args) {
	for(int i = 1; i <= 9; i++){
		System.out.println("i = " + i);
	}
}

 

运行结果如下:

 

图6-25:九九乘法表9行

 

观察上图我们可以得出i是行号,那么再次观察九九乘法表的规律得知,第1行1个式子,第2行2个式子,第3行3个式子...,第9行9个式子,那么结论是第i行有i个式子,以上循环确定为外层循环,共循环9次,外层循环每循环一次要保证能够输出九九乘法表的1整行。那么输出九九乘法表1整行的时候又需要一个循环进行控制,而且这个循环被放到内部,循环的次数随着行号的变化而变化。代码如下所示:

 

for (int i = 1; i <= 9; i++) {

	for (int j = 1; j <= i; j++) {

		System.out.print(i * j + " ");

	}

	System.out.println();

}

运行结果如下所示:

 

图6-26:九九乘法表每个表达式的执行结果

 

分析以上代码,请看下图:

 

图6-27:分析九九乘法表程序

 

接下来我们在每一个“结果”前添加“i * j = ”,代码如下所示:

 

for (int i = 1; i <= 9; i++) {

	for (int j = 1; j <= i; j++) {

		System.out.print(i + "*" + j + "=" + i * j + " ");

	}

	System.out.println();

}

 

运行结果如下所示:

 

图6-28:九九乘法表运行结果

 

通过以上代码的学习,需要每位读者能够掌握什么是循环,为什么要使用循环,for循环的语法结构是什么,for循环的执行顺序以及原理是什么,嵌套的for循环又应该怎么理解,大家也可以挑战一下三层for循环嵌套,或者更多。总之for循环在实际开发中使用非常频繁,大家务必掌握。

全部教程