3.5 for语句的使用及注意事项
C语言中的for语句使用极为灵活,不仅可以用于循环次数已经确定的情况,还可以用于循环次数不确定而只给出循环结束条件的情况,它完全可以代替while语句。
1.简单for语句
在前面的代码中已经多次用到for循环,所以读者对for循环语句应该并不陌生。在讲解for循环语句之前,还是先来看看for循环语句的构成。for循环由4个部分所组成,即3个表达式和1个循环体,其一般形式为:
for(表达式1;表达式2;表达式3)
循环体;
值得注意的是,循环体中的表达式之间用“;”分隔开。表达式1通常用来为循环变量赋初始值;表达式2作为循环控制表达式,也就是循环条件;表达式3通常用来改变循环变量的值。for循环语句流程图如图3-8所示。
for循环的执行大致可分为4个步骤:
(1)执行表达式1,只执行一次。
(2)计算表达式2的值,看其否为真(非零),如果为真,那么就执行循环体部分,否则直接退出,执行for循环下面的语句。
(3)执行循环体。
(4)计算表达式3的值,然后返回步骤2。
图 3-8 for循环语句流程图
for循环语句的表达式1通常用来对循环变量做初始化操作,在for循环的执行流程中仅被执行一次。如果在for循环语句之前已经做了初始化处理,那么表达式1可以为空。表达式2提供一个循环体能够执行的条件,如果表达式2为空,那么该for循环就是死循环,这时可以在循环体中采用break语句来退出循环。表达式3通常用来改变循环变量,表达式3也可以为空并放在循环体中,但通常不建议这样做,因为这样会使for循环的可读性变差。值得注意的是,不管for循环中的3个表达式是否为空,其中的两个“;”一个都不能少。看看下面一段代码。
include<stdio.h>
void main(void)
{
int i;
char a[20]="Hello World!";
char b[20];
i=0;
for(;b[i];)
{
b[i]=a[i];
i++;
}
printf("%s\n",b);
return;
}
运行结果:
Hello World!
在上面的代码中,在for循环中没有使用表达式1和表达式3。在循环体外对i进行了初始化,用表达式b[i]作为循环的控制表达式,当“b[i]='\0'”的时候循环结束;将表达式3放到了循环体中来进行,所以为空。虽然表达式1和表达式3为空,但是表达式之间的“;”依然存在。
2.for语句的嵌套
for语句的嵌套,就是在一个for循环中包含另外一个for循环结构。值得注意的是,内层for循环被当成外层for循环的循环体的一部分在执行。for循环嵌套的一般形式为:
for(表达式11;表达式12;表达式13)
{
for(表达式21;表达式22;表达式23)
{
for(表达式31;表达式32;表达式33)
{
循环体;
}
}
}
接下来看一个for循环嵌套的示例。以下代码以下三角的方式打印出九九乘法表。
include<stdio.h>
void main(void)
{
int i,j;
for(i=1;i<10;i++)
{
for(j=1;j<=i;j++)
printf("%d×%d=%d\t",j,i,i*j);
printf("\n");
}
return;
}
运行结果:
1×1=1
1×2=2 2×2=4
1×3=3 2×3=6 3×3=9
1×4=4 2×4=8 3×4=12 4×4=16
1×5=5 2×5=10 3×5=15 4×5=20 5×5=25
1×6=6 2×6=12 3×6=18 4×6=24 5×6=30 6×6=36
1×7=7 2×7=14 3×7=21 4×7=28 5×7=35 6×7=42 7×7=49
1×8=8 2×8=16 3×8=24 4×8=32 5×8=40 6×8=48 7×8=56 8×8=64
1×9=9 2×9=18 3×9=27 4×9=36 5×9=45 6×9=54 7×9=63 8×9=72 9×9=81
下面分析一下for嵌套循环的特点。当外层循环不影响内层循环的执行次数时,内层循环体执行的次数等于一个完整的内层循环执行次数乘以外层执行次数;如果外层循环对内层循环执行的次数有影响,如上面的代码,那么内层循环执行的次数等于内层循环执行次数的叠加。
3.break语句在for循环中的使用
在for循环中使用break语句的一般形式为:
for(表达式1;表达式2;表达式3)
{
循环体1;
break;
循环体2;
}
通常都是在for循环的循环体中通过if语句与break搭配使用来实现在满足一定条件时退出整个for循环,其相应的流程图如图3-9所示。
图 3-9 含有break语句的for循环流程图
下面这一段代码的功能为查找一个三位数的最大水仙花数。
include<stdio.h>
void main(void)
{
int i,j,k;
int num;
int flag=0;
for(i=9;i>=1;i—)
{
for(j=9;j>=0;j—)
{
for(k=9;k>=0;k—)
{num=i100+j10+k;
if(iii+jjj+kkk==num)
{
flag=1;
printf("三位数中的最大水仙花数为:%d\n",num);
break;
}
}
if(1==flag)
break;
}
if(1==flag)
break;
}
return;
}
运行结果:
三
位
数
中
的
最
大
水
仙
花
数
为
:
4
0
7
与前面使用goto语句退出多重循环相比,这里使用了一个信号标记,当满足条件的时候,采用逐层退出的方式从内到外依次退出循环体,虽然每次都要判断信号标记是否满足条件,但是相比goto语句,break语句有更好的可读性和易控制性,所以建议使用break语句来退出循环。
4.continue语句在for循环中的使用
接下来看看continue语句在for循环中的使用。continue语句的作用是结束本次循环,其后的循环体将不会被执行,跳转至下一次循环。可以看出,continue语句与break语句的区别在于:执行break语句退出其所在的for循环,而执行continue语句只结束本次循环,跳转至下一次循环。含有continue语句的for循环流程图如图3-10所示。
图 3-10 含有continue语句的for循环流程图
下面这段代码的功能为求1到100之间不能被5整除的整数之和。
include<stdio.h>
void main(void)
{
int i;
int sum;
sum=0;
for(i=1;i<101;i++)
{
if(0==i%5)
continue;
sum+=i;
}
printf("1到100之间不能被5所整除的整数之和为:%d\n",sum);
return;
}
运行结果:
1到100之间不能被5所整除的整数之和为:4000
分析上面的代码,如果数i能被5所整除,那么就执行continue语句,跳过下面的“sum+=i;”语句部分,舍弃对不满足条件数据的求和。注意,continue不能用于goto语句构成的循环语句。