笔者曾有耳闻,大学里初学C语言时,有些人提出,有了 while 语 句,for 语句不要也可以。有这种质疑其实并不奇怪,因为实际上 for 语 句能实现的功能用 while 语句已经能够实现了。 使用 for 语句的表达方式 我们来考察下面的 for 语句,它表示 i 在 0 至 N 的范围内按 1 递增 同时打印显示。 C语言 for(i = 0; i < N; i++){ printf("%dn", i); } 不使用 for 语句的表达方式 同样的逻辑使用 while 语句来表达,就变成了下面这样。 C语言 i = 0; while(i < N){ printf("%dn", i); i++; } 对在 0 至 N 范围的某数做某种操作,这样的需求时常能碰到。比如,要对数组 xs 中全部数值做某种处理,即,要对从 xs[0] 到 xs[N-1]范围内的各个元素做处理。如果用 while 语句来表达,就需要在循环体外写 i=0,循环条件写 i < N,循环体最后写 i++。代码分散在三处,对于阅读代码的人来说,原本的意图没那么直观。用 for 语句就不同了,相关代码更加紧凑,代码阅读者很容易就能理解循环的意图(图 4.1)。 图 4.1 三处散落的代码在 for 语句中只存在于一处 i = 0; for(i = 0; i < N; i++){ while (i < N){ printf("%dn", i); printf("%dn", i); } i++; } 像这样,带有初值、递增值和终值这三组数的 for 语句,早在于 1958 年发明的 ALGOL 58 语言里就已经出现了 ①。 ALGOL 58 for I : = 0 ( 1 ) N; …… foreach——根据处理的对象来控制循环操作 for 语句已经有了新的发展,这就是目前许多语言里采用的 foreach 句型。在 Java 语言里被称为扩展 for 语句,而在 Perl②、PHP、C# 等众多 语言里被叫做 foreach 语句。本书为了体现其与 for 语句的区别,把它称 为 foreach 语句 ③。 while 语句通过条件判断来控制循环操作,for 语句通过循环次数来 控制循环操作 ④,而 foreach 句型则是通过处理的对象来控制循环操作。 在没有 foreach 语句的 C 语言里,for 语句常常被用来实现对数组里各元素的处理操作。foreach 的句型的产生,就是为了方便编写对某对象 内所有元素进行某种处理的代码。 -------------------------------- ① 参见 A. J. PERLIS and K. SAMELSON, “Report on the Algorithmic Language ALGOL by the ACM Committee on Programming Languages and the GAMM Committee on Programming”, Numberische Mathematik, Bd.1, S.41-60, 1959, p.50. ② 在 Perl 语言中,for 和 foreach 为同义词,为了方便阅读,两者在语言中都有提供。 ③ Python 语言的 for 语句就是 foreach,它反而没有相当于C语言里功能的 for 语句。 ④ 准确来讲,for 语句也是通过条件判断来控制的,但它主要体现的还是对循环次数 的跟踪。 ------------------------------- Java // 数组 int[] items = new int[]{1, 2, 3, 4, 5}; // 用一般的for语句输出各元素 for(int i = 0; i < items.length; i++){ int item = items[i]; System.out.println(item); } // 用扩展的for语句输出各元素 for(int item: items){ System.out.println(item); } 如上,for 语句表达的是在 0 至数组 items 长度范围以内,对 i 按 1 递增同时打印显示数组 items 第 i 个元素。使用了 foreach 语句后,意思 就变成了将数组 items 里的各个元素都打印显示出来,相当地简洁易懂。