2.for循环
for循环把上述3个行为(初始化、测试和更新)组合在一处。
程序示例1.1:
//sweetie2.c -- 使用for的计数循环
#include <stdio.h>
int main(viod)
{
const int NUMBER = 22;
int count;
for (count = 1; count <= NUMBER; count++)
printf("Be my Valentine!\n");
return 0;
}
关键字for后面的圆括号中有3个表达式,分别用两个分号隔开。第1个表达式是初始化,只会在for循环开始时执行一次。第2个表达式是测试条件,在执行循环之前对表达式求值。如果表达式为假(本例中,count大于NUMBER时),循环结束。第3个表达式执行更新,在每次循环结束时求值。完整的for语句还包括后面的简单语句或复合语句。for圆括号中的表达式也叫做控制表达式,它们都是完整表达式,所以每个表达式的副作用(如,递增变量) 发生在对下一个表达式求值之前。 图1.2演示了for循环的结构。
程序示例1.2:
/* for_cube.c -- 使用for循环创建一个立方表 */
#include<stdio.h>
int main (void)
{
int num;
printf(" n n cubed\n");
for (num = 1; num <= 6; num ++)
printf("%5d %5d\n",num,num*num*num);
return 0;
}
打印1~6及其对应的立力,该程序的输出如下:
n n cubed
1 1
2 8
3 27
4 64
5 125
6 216
for 循环的第一行包含了循环所需的所有信息:num的初值,num的终值和每次循环num的增量。
3.利用for 的灵活性
虽然for循环看上去和FORTRAN的Do 循环,Pascal的FOR循环,BASIC的FOR…NEXT循环类似,但是for循环比这些循环灵话。这些灵活性源于如何使用for循环中的3个表达式。以前面for循环为例,第1个表达式给计数器赋初值,第2个表达式表示计数器的范围,第3个表达式递增计数器。这样使用for循环确实很像其他语言的循环。除此之外,for 循环还有其他9种用法。
(1.)可以使用递减运算符来递减计数器:
/* for_down.c */
#include <stdio.h>
int main(void)
{
int secs;
for (secs = 5; secs > 0; secs --)
printf("%d seconds!\n",secs);
printf("We have ignition!\n");
return 0;
该程序输出结果如下:
5 seconds!
4 seconds!
3 seconds!
2 seconds!
1 seconds!
We have ignition!
(2.)可以让计数器递增2、10等:
/* for_13s.c */
#include <stdio.h>
int main(void)
{
int n; //从2开始,每次通增13
for (n = 2;n < 60;n = n +13)
printf("%d \n",n);
return 0;
}
每次循环n递增13,程序的输出如下:
2
15
28
41
54
(3.)可以用字符代替数字计数:
/* for char.c */
include <stdio.h>
int main(void);
{
char ch;
for (ch = 'a'; ch <= 'z'; ch++)
printf("The ASCII value for %c is %d.\n", ch, ch);
return 0;
}
该程序假定系统用ASCII码表示字符。由于篇幅有限,省略了大部分输出:
The ASCII value for a is 97.
The ASCII value for b 13 98.
. . .
The ASCII value for x is 120.
The ASCII value for y is 121.
The ASCII value for z is 122.
该程序能正常运行是因为字符在内部是以整数形式储存的,因此该循环实际上仍是用整数来计数。
(4.)除了测试迭代次数外,还可以测试其他条件。在for_cube程序中,可以把:
for (num = 1; num <= 6; num++)
替换成:
for (num = 1; numnumnum <= 216; num++)
如果与控制循环次数相比,你更关心限制立方的大小,就可以使用这样的测试条件。
(5.)可以让递增的量几何增长,而不是算术增长。也就是说,每次都乘上而不是加上一一个固定的量:
/* for_geo.c */
#include <stdio.h>
int main(void)
{
double debt:
for (debt = 100.0; debt < 150.0; debt = debt*1.1)
printf("Your debt is now $&.2f.\n",debt);
return 0;
}
该程序中,每次循环都把 debt 乘以1.1,即 debt 的值每次都增加10%,其输出如下:
Your debt is now $100.00.
Your debt is now $110.00.
Your debt is now $121.00.
Your debt is now $133.10.
Your debt is now $146.41.
(6.)第3个表达式可以使用任意合法的表达式。无论是什么表达式,每次迭代都会更新该表达式的值。
/*for_wlld.c*/
include <stdio.h>
int main(vold)
{
int x;
int y = 55;
for
}
该循环打印x的值和表达式++x * 5 + 50的值,程序的输出如下:
1 55
2 60
3 65
4 70
5 75
注意,测试涉及y,而不是x。for循环中的3个表达式可以是不同的变量(注意,虽然该例可正常运行,但是编程风格不太好。如果不在更新部分加入代数计算,程序会更加清楚)。
(7.)可以省略一个或多个表达式(但是不能省略分号),只要在循环中包含能结来循环的语句即可。
/*for_none.c /
include <stdio.h>
int main (void)
{
int ans, n;
ans=2;
for (n=3; ans <= 25;)
ans=ans*n;
printf("n = %d; ans = %d.\n",n, ans);
return 0;
}
该程序的输出如下:
n = 3; ans = 54
该循环保持n的值为3。变量ans开始的值为2,然后递增到6和18,最终是54 (18比25小所以for循环进入下一次迭代,18乘以3得54)。顺带一提,省略第2个表达式被视为真,所以下面的循环会一直运行:
for( ; ; )
printf(“I want some action\n”);
(8.)第1个表达式不一定是给变量赋初值,也可以使用printf()。记住,在执行循环的其他部分之前,只对第1个表达式求值一次或执行一次。
/* for show.c */
include <stdio.h>
int main(void)
{
int num = 0;
for (printf("Keep entering numbers!\n"); num != 6;)
scanf("%d", &num);
printf("That 's the one I want!\n");
return 0;
}
该程序打印第1行的句子一次, 在用户输入6之前不断接受数字:
Keep entering numbers!
3
5
8
6
That 's the one I want!
(9.)循环体中的行为可以改变循环头中的表达式。例如,假设创建了下面的循环:
for(n = 1;n<10000;n = n + delta)
如果程序经过几次迭代后发现delta太小或太大,循环中的1语句可以改变delta的大小。在交互式程序中,用户可以在循环运行时才改变delta的值。这样做也有危险的一面,例如,把delta设置为0就没用了。
总而言之,可以自己决定如何使用for循环头中的表达式,这使得在执行固定次数的循环外,还可以受更多的事情。接下来,我们将简要讨论些运算符,使for循环更加有用。