循环结构 - for循环

通常我们需要处理同一类事务,一般的编程语言都提供了循环结构逐个处理类似事务。

for循环一般会明确指定需要循环的变量

1. 基本循环结构

一个经典的Java循环结构为

    for (int i = 0; i < 5; i = i + 2) {
        // do something
    }

这里,for后面的括号里包含三条语句(必须按顺序):

  • int i = 0; 初始化语句:这里定义一个按要求变化的量(通常是下标),并初始化为0
  • i < 5; 条件语句:此处为i小于5(当i递增到大于等于5时,停止循环);
  • i = i + 2; 每轮循环后执行的语句:每个循环后i的值增加2

Tips.

  • 因为for()括号里是三条语句,所以是用';'分割。
  • 上面的例子中,i可以在for()的括号外定义,比如
// 依次打印1~5
    int j = 0;
    for (j = 1; j <= 5; j++) {
        System.out.println(j);
    }

某条语句甚至可以不写,但是必须保留分号';'确保括号里有三条语句(空语句也需要占个位置),比如:

    int j = 0;
    for (; j <= 5; j++) {
        System.out.println(j);
    }

我们甚至可以三条语句都不写,那么就会得到如下一个奇怪的结构:

    for(;;) {
        // do something
    }

但是一定要注意:如果 for( ; ; ) 的括号里没有明确何时退出循环,那么就需要在循环体 { } 内定义何种情况下退出循环,而且需要保证这个循环是的确可以自动退出的(比如i有个上限5,而每一轮i都会增加1),不然程序就会陷入死循环而导致故障。


2. 更多例子

例1. 分别计算1到100以内能被3和7整除的数的和。

SumUpIntegers.java

public class SumUpIntegers {

	public static void main(String[] args) {
		int sumNumberDivisibleByThree = 0;
		int sumNumberDivisibleBySeven = 0;
		for (int i = 1; i <= 100; i = i + 2) {
			if(i % 3 == 0) {
				sumNumberDivisibleByThree += i;
			}
			if (i % 7 == 0) {
				sumNumberDivisibleBySeven += i;
			}
		}
		System.out.println("The sum of numbers divisible by 3 is " + sumNumberDivisibleByThree);
		System.out.println("The sum of numbers divisible by 7 is " + sumNumberDivisibleBySeven);
	}
}

例2. 计算1到100以内能被13或者17整除的数的和

SumUpIntegersExt.java

public class SumUpIntegersExt {

	public static void main(String[] args) {
		int sum = 0; // 定义一个局部变量,用来记录和
		for (int num = 1; num <= 100; num++) {
			if (num % 13 == 0 || num % 17 == 0) {
				System.out.print(num + "\t"); // 打印这个合适的数,后面加个Tab
				sum += num; // 将这个数加到sum上
			}
		}
		System.out.println("\nThe sum of numbers between 1 and 100 and divisible by 13 or 17 is " + sum);
	}
}

Just for fun:

  • 学有余力的同学可以尝试下面的代码,比较上下两个方法的结果;
  • 你需要添加import java.util.stream.IntStream; 引入IntStream类;
  • 要是不能理解就算了,不要把脑子弄乱了。
	IntStream
		.rangeClosed(1, 100)
		.filter(x -> x % 13 == 0 || x % 17 == 0)
		.forEach(x -> System.out.print(x + "\t"));

	int sum2 = IntStream
			.rangeClosed(1, 100)
			.filter(x -> x % 13 == 0 || x % 17 == 0)
			.sum();
	System.out.println("\nA weird sum is " + sum2);

例3. 设计一个程序,数值计算

的值。(用定积分的定义,不通过先求不定积分的方式)

public class MyIntegral {

	public static void main(String[] args) {

		double step = 0.000001;  //积分区域切割的步长
		double ub = Math.E;		// 积分上限
		double lb = 1;			// 积分下限
		double sum = 0;			// 记录累计值
		for (double x = lb; x <= ub; x+=step) {
			sum += step * 1/x;
		}
		System.out.println(sum);
	}
	
}

3. 嵌套循环

一个循环内还可以有内层循环,用来处理更复杂的事务。

例4. 编写一个Java程序,生成10以内的乘法表

multiplication table

MultiplicationTable.java

public class MultiplicationTable {

	public static void main(String[] args) {
		for (int i = 1; i <= 10; i++) { // i:第一个乘数,行号
			for (int j = 1; j <= 10; j++) { // j: 第二个乘数,列号
				System.out.print(i * j + "\t");
			}
			System.out.println();
		}
	}
}

该程序的运行流程:

  • 开启外层对i的循环, i = 1;
    • 开启内层对j的循环:j = 1;
      - 打印1 x 1; // 因为(i=1, j=1) - j = 2;
      • 打印1 x 2; // (i=1, j=2) - j = 3;
      • 打印1 x 3; // (i=1, j=3) - 。。。 - j = 10;
      • 打印1 x 10; // (i=1, j=10)
  • 打印回车符
  • i = 2;
    • j = 1;
      • 打印2 x 1; // (i=2, j=1)
    • j = 2;
      • 打印2 x 2; // (i=2, j=2)
    • j = 3;
      • 打印2 x 3; // (i=2, j=3)
    • 。。。
    • j = 10;
      • 打印2 x 10; // (i=2, j=10)
  • 打印回车符
  • i = 3;
    • j = 1;
      • 打印3 x 1; // (i=3, j=1) 。。。。。。