文章目录
for 循环概述
创建一个计数循环时有三个行为:
- 初始化计数器
- 计数器和有限值作比较
- 每次循环计数器递增
用 while 循环创建计数循环时未能将这三个行为组织在一起.
用 for 循环创建计数循环时能将这三个行为组织在一起.
程序示例:
#include<stdio.h>
int main(void)
{
const int NUMBER = 10;
int count;
for (count = 1; count <= NUMBER; count++)
{
printf("Be my valentine.\n");
}
return 0;
}
一般, 建议 for 语句的控制变量的取值范围是前开后闭, 即:
count = 1; count <= NUMBER;
这里的 NUMBER 可以展示出特殊的意义, 如循环的次数, 元素的总的个数等等.
结果:
Be my valentine.
Be my valentine.
Be my valentine.
Be my valentine.
Be my valentine.
Be my valentine.
Be my valentine.
Be my valentine.
Be my valentine.
Be my valentine.
for 循环的格式:
for (expression1 ; expression2 ; expression3)
语句
expression1
是初始化语句, 一般用来初始化计数器. 只在 for 循环刚开始时执行一次.
expression2
是测试条件, 在循环之前对 expression2
求值, 为真则执行 for 循环的语句, 为假则结束 for 循环.
expression3
执行更新, 更新计数器, 使得 expression2
会变成假, 否则出现死循环.
for 的圆括号里的三个表达式也叫做控制表达式, 它们都是完整表达式, 因此每个表达式的副作用都发生在对下一个表达式求值之前.
程序示例:
#include<stdio.h>
int main(void)
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
printf("ok\n");
}
}
return 0;
}
结果:
ok
ok
ok
ok
ok
ok
ok
ok
ok
程序示例:
#include<stdio.h>
int main(void)
{
int i = 0, j = 0;
for (; i < 3; i++)
{
for (; j < 3; j++)
{
printf("ok\n");
}
}
return 0;
}
结果:
ok
ok
ok
程序示例:
#include<stdio.h>
int main(void)
{
int num;
printf(" n n cubed\n");
for (num = 1; num <= 6; num++)
{
printf("%5d %7d\n", num, num * num * num);
}
return 0;
}
结果:
n n cubed
1 1
2 8
3 27
4 64
5 125
6 216
递减计数器的程序示例:
#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!
计数器每次循环都增加一个较大的值:
#include<stdio.h>
int main(void)
{
int n;
for (n = 2; n < 40; n += 13)
{
printf("n = %d\n", n);
}
return 0;
}
结果:
n = 2
n = 15
n = 28
用字符代替计数:
#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;
}
结果:
The ASCII value for a is 97.
The ASCII value for b is 98.
The ASCII value for c is 99.
The ASCII value for d is 100.
The ASCII value for e is 101.
The ASCII value for f is 102.
The ASCII value for g is 103.
The ASCII value for h is 104.
The ASCII value for i is 105.
The ASCII value for j is 106.
The ASCII value for k is 107.
The ASCII value for l is 108.
The ASCII value for m is 109.
The ASCII value for n is 110.
The ASCII value for o is 111.
The ASCII value for p is 112.
The ASCII value for q is 113.
The ASCII value for r is 114.
The ASCII value for s is 115.
The ASCII value for t is 116.
The ASCII value for u is 117.
The ASCII value for v is 118.
The ASCII value for w is 119.
The ASCII value for x is 120.
The ASCII value for y is 121.
The ASCII value for z is 122.
由于字符在计算机内存中是以整数存储的, 所以该循环实际上仍是用整数来计数的.
测试条件除了可以测试循环的次数, 还可以测试其他条件:
#include<stdio.h>
int main(void)
{
int num;
printf(" n n cubed\n");
for (num = 1; num*num*num <= 666; num++)
{
printf("%5d %7d\n", num, num * num * num);
}
return 0;
}
结果:
n n cubed
1 1
2 8
3 27
4 64
5 125
6 216
7 343
8 512
这里的程序更加关心立方的值不超过一个限度, 而不是关心循环的次数.
让计数器几何增长, 而不是算数增长, 即每次都是乘以一个固定的值, 而不是加上一个固定的值.
#include<stdio.h>
int main(void)
{
double debt;
for (debt = 100.0; debt < 150.0; debt = debt * 1.1)
{
printf("Your debt is now %2.2f.\n", debt);
}
return 0;
}
结果:
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.
for 循环三个表达式的省略
三个表达式都可以是任意合法的表达式.
可以省略一个或多个表达式, 但不能省略分号.
省略第二个表达式被视为真.
省略第一个表达式的程序示例:
#include<stdio.h>
int main(void)
{
int i = 0;
int j = 0;
for (; i < 10; i++)
{
for (; j < 10; j++)
{
printf("Hello\n");
}
}
return 0;
}
结果:
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
从结果可以看出, 只打印了十次, 因为在第一次执行完外层循环后, j 的值为 10, 在第二次外循环时, 执行到内循环时, j 没有被赋值, 所以还是10, 内层循环的条件不成立, 内层循环不执行. 所以除了第一次外层循环外的其余外层循环都不执行, 最终只有 10 次打印.
嵌套循环 (nested loop)
嵌套循环常用于按行和列显示数据, 一个循环处理一行中的所有列, 另一个循环处理所有的行.
程序示例:
#include<stdio.h>
int main(void)
{
const int ROW = 6;
const int CHAR = 10;
int num;
char ch;
for (num = 0; num < ROW; num++) // 外层循环 (outer loop)
{
for (ch = 'A'; ch < 'A' + CHAR; ch++) // 内层循环 (inner loop)
{
printf("%c", ch);
}
printf("\n"); // 在下一次运行内层循环时将在下一行打印字符
}
return 0;
}
结果:
ABCDEFGHIJ
ABCDEFGHIJ
ABCDEFGHIJ
ABCDEFGHIJ
ABCDEFGHIJ
ABCDEFGHIJ
可以用外层循环控制内层循环, 使得每次外层循环迭代时内层循环执行不同的任务:
#include<stdio.h>
#define ROW 6
#define CHAR 6
int main(void)
{
int num;
char ch;
for (num = 0; num < ROW; num++)
{
for (ch = 'A' + num; ch < 'A' + CHAR; ch++) // ch 的初始化随外层循环改变, 测试条件不变
{
printf("%c", ch);
}
printf("\n");
}
return 0;
}
结果:
ABCDEF
BCDEF
CDEF
DEF
EF
F
注意事项
不要在循环体内部改变计数器的值.
for 循环和 while 循环内的 continue 的比较
for 循环内的 continue:
#include<stdio.h>
int main(void)
{
int i = 0;
for (i = 1; i <= 10; i++)
{
if (i == 5)
continue;
printf("%d ", i);
}
return 0;
}
结果:
1 2 3 4 6 7 8 9 10
for 循环里的 continue 执行完了后, 下一步是执行循环头中的表达式 3, 表达式 3 执行完了后执行表达式 2, 即判断表达式.
while 里的 continue:
#include<stdio.h>
int main(void)
{
int i = 0;
while (i <= 10)
{
if (i == 5)
continue;
printf("%d ", i);
i++;
}
return 0;
}
结果: 一个死循环.
while 循环里的 continue 执行完了后执行循环头中的判断条件.
for 循环和 while 循环内的 break 的比较
for 循环中, 执行完 break 语句之后, 执行循环体外的第一条语句, 连循环头内的更新子表达式都不会执行.