一、实现循环结构的语句
1.while语句
1.1while语句相当于当型循环结构,其一般形式为:
while(表达式)
{
循环体语句
}
1.2while语句的执行流程是:
首先计算表达式的值,若结果为“真”(非零),则执行循环体语句:然后再计算表达式的值,重复上述过程,直到表达式的值的值为“假”(零)时结束循环,流程控制转到while语句的下一语句。
(while语句中的表达式就是循环条件)
举一个简单的例子:显示1~100的平法和。
【编程思路】
(1)定义变量i;并赋初始值为1,用i来表示底数和行数,让i在循环体中递增。
(2)循环结束的条件为i<=100,即底数增加到100的时候进行最后一次循环。
(3)循环体中使用print()函数输出平方数。
【程序代码】
#include<stdio.h>
int main()
{
int i=1;
while(i<=100) //循环条件
{
printf("%d*%d=%d",i,i,i*i); //循环语句
i++; //循环语句
}
}
1.3使用while循环的注意事项:
(1)while循环的特点是先判断条件后执行循环语句,因此,循环体语句有可能一次都执行不到。
(2)while循环中的表达式一般是关系表达式或逻辑表达式,但也可以是数值表达式或字符表达式,只要其值非0,就可以执行循环体。
(3)循环体语句可以是一个语句,也可以是多个语句。当只有一个语句时,外层的大括号“{ }”可以省略,如果循环体是多个语句,一定要用花括号“{ }”括起来,以复合语句的形式出现。
(4)循环体内一定要有改变循环条件的语句出现,使循环趋于结束,否则循环将无休止地进行下去,即形成“死循环”。
例1:求自然数1~100的和,即计算sum=1+2+3+···+100。
【编程思路】
(1)首先定义两个变量,用i表示累加数,用sum存储累加和。
(2)给累加数i赋初值1,表示从1开始进行累加,给累加变量sum赋初值0。
(3)使用循环结构反复执行加法,在sum原有值的基础上增加新的i值,加完后再使i自动加1,使其成为下一个要累加的数。
(4)在每次执行完循环后判断i的值是否达到100,如果达到100就停止循环累加。
(5)最后输出计算结果,即输出sum的值。
【程序代码】
#include<stdio.h>
int main()
{
int i,sum;
i=1,sum=0; //为循环控制变量i、累加变量sum赋初值
while(i<=100) //循环条件
{
sum=sum+i; //累加
i++; //变为下一个加数
}
printf("sum=%d",sum);
return 0;
}
输出结果为:
解析:
这是一个典型的累加问题,程序中用sum存储每次累加后的和值,用i表示要累加的数。第一次先计算0+1的值,并将其存入sum,第2次再计算sum+2的值,并将结果存回到sum中,第三次计算sum+3的值,再将结果存回到sum中,如此重复下去,直到计算完sum+100的值为止。每次累加完成后,加数i自动加1,变为下一个加数,当i达到100时,累加结束。
2.do-while 语句
2.1do-while 语句属于直到型循环,其一般形式为:
do
{
循环体语句
}while(表达式)
举一个简单的例子:下面是一个可以输出30个“ * ”的do-while语句
i=1;
do
{
printf("*")
i++;
}while(i<=30); //do-while语句中的while语句后面带“;” 。
2.2 do-while语句的执行流程:
首先执行一次循环体语句,然后计算表达式(循环条件)的值,若结果为“真”(非零),返回执行循环体语句,重复上述过程,直到表达式的值为“假”(零)时退出循环,流程控制转到while语句的下一语句。
例2:输入一个整数,计算这个整数是几位数?
例:
输入:1234 输出:4
输入:12 输出:2
【程序代码】
#include<stdio.h>
int main()
{
int n; //n表示输入的数字
scanf("%d",&n);
int cnt=0; //cnt表示数字的位数
do
{
cnt++; //至少有一位
n=n/10;
}while(n) ; //n=0时跳出循环(注意后面是有分号的)
printf("%d\n",cnt);
return 0;
}
输入2098,得到结果为:
这里并非必须使用do-while语句,但是这个代码就比较适用do-while循环,因为n即使是0,也是一位数,要统计位数的。
2.3 使用do-while循环结构时应注意以下几点:
(1)do-while循环结构的特点是先执行循环体语句后判断条件,因此不管循环条件是否成立,循环体语句都至少被执行一次。这是它与while循环的本质区别。
(2)不论循环体是一个语句,还是多个语句,花括号“{ }”都不要省略。
(3)避免出现“死循环”。
(4)注意do-while循环最后的分号“ ;”不能省略。
(5)do-while循环特殊的地方:
do-while语句中循环体是至少执行一次。
(6)do-while循环和其它两种循环不同的地方:
while和for这两种循环都是先判断,条件如果满足就进入循环,执行循环语句,如果不满足就跳出循环;
而do-while循环则是先直接进入循环体,执行循环语句,然后在执行while后的判断表达式,表达式为真,就会进行下一次,表达式为假,则不在继续循环。
例3: 求n!,即求n的阶乘,n由键盘输入。
【编程思路】
求阶乘实际上是求累乘,即求1*2*3*4···*n。累乘与累加除运算类型不同外,其执行过程相同。
【运行代码】
#include<stdio.h>
int main()
{
printf("输入一个数字求阶乘:\n");
int i=1, n;
scanf("%d",&n);
long s=1;
do
{
s=s*i;
i++;
}while(i<=n);
printf("%d!=%d\n,n,s);
return 0;
}
【输出结果】输入5,得到结果:
3.for 循环
3.1 for语句相当于当型循环,其一般形式为:
for(表达式1;表达式2;表达式3)
{
循环体语句
}
例如,下面是一个可以输出30个“*”的for语句:
for(i=1;i<=30;i++)
{
printf(" * ");
}
for语句的执行流程是:
(1)首先进行表达式1的计算。
(2)判断表达式2的值,若其值为“真”(非零),则执行循环体语句,然后转到第(3)步执行;若其值为“假”(零),循环结束。
(3)进行表达式3的计算,然后转至第(2)步重复执行。
举一个上面的例子:求自然数1~100的和(用for语句写)。
#include<stdio.h>
int main()
{
int i,sum=0;
for(i=1;i<=100;i++)
{
sum=sum+i;
}
printf("sum=%d\n",sum);
return 0;
}
本例中的for语句的3个表达式实现了程序设计中的3个功能,即循环变量赋初值,循环条件和循环变量递增,因此写法更简洁。
3.2 使用for循环应注意以下几点:
(1)for循环相当于以下的while循环:
表达式 1;
while(表达式 2)
{
循环体语句
表达式 3;
}
(2)for语句有3个表达式,它们之间由分号“:”分隔,不能更换成其他分隔符号。
(3)有时根据需要可以将for语句格式中的部分或所有表达式省略,比如可以写成如下形式:
for( ;表达式2;表达式3)
{循环体语句}
上面那个求和的例子可以改为:
int i=1,sum=0;
for( ;i<=100;i++) //把赋初值i=1放置在for循环之前,
//即在for循环外提前对循环变量赋初值。
{
sum=sum+i;
}
接下来就看几个典型的例题吧。
例4:把100~200之间的不能被3整除的数输出。
【编程思路】
(1)用变量n表示100~200之间的所有整数。
(2)利用for循环遍历每个n,在循环体中判断n是否能被3整除,如果能整除,则输出n的值,如果不能整除,则啥也不做,这个判断用if语句实现。
#include<stdio.h>
int main()
{
int n;
for(n=100;n<=200;n++)
{
if(n%3!=0)
printf("%4d",n);
}
return 0;
}
【输出结果】
例5:判断正整数m是不是素数,m由键盘输入。
【编程思路】
首先明确什么是素数,素数是只能被1和它自身整除的数(1不是素数),即除了1和自身外 不能被其他任何数整除的数(素数即质数)。
判断方法:用2和m-1之间的数依次去除m,如果都除不尽,则m就是素数;反之,只要有一次除尽,则m不是素数,这时循环可以提前结束。
程序中定义变量i来表示除数,那么i的初值为2,终值为m-1,循环结构使用for语句实现。在循环过程中,如果一直没有除尽,则i要一直递增到m,循环正常结束;反之,如果除尽了,而i还没有递增到m,循环就提前结束。提前结束循环可用break语句完成。
【程序代码】
#include<stdio.h>
int main()
{
int m,i;
printf("请输入一个数:\n");
scanf("%d",&m);
for(i=2;i<=m-1;i++)
{
if(m%i==0) //如果某个数能整除m,则提前结束循环
break;
}
if(i==m) //判断i是否递增到m,即循环是否正常结束
printf("%d是素数",m);
else
printf("%d不是素数",m);
return 0;
}
输入23,结果为:
输入42,结果为:
实际上除数2只需从2判断到即可,所以本例的for语句还可以写成:
for(i=2;i<=sqrt(n);i++)
这样可以减少循环次数,提高程序的运行效率。当然在程序的开头必须增加命令行“#include<math.h> ”。
本例中用到 break 语句。在switch语句中已经介绍过break语句,它的功能是终止选择执行,跳出switch语句,那么在循环结构中使用 break 语句,其作用是终止循环的执行,即跳出循环语句。
使用break语句应注意以下几点:
(1)break 语句只能跳出或终止包含它的循环语句,对其他语句没有影响。
(2)break 语句通常要和 if 语句配合使用。
(3)除了在 switch 结构和循环结构中使用外,在其他情况下一般不使用 break 语句。
例6:程序预期输出半径为1~10的圆的面积,但是如果有圆的面积值超过100时,则停止执行。
【编程思路】
定义变量i表示圆的半径,使其从1递增到10。循环中计算并判断每个圆的面积值是否大于100,不大于100时输出圆面积,如果大于100,则使用 break 跳出循环。
【程序代码】
#include<stdio.h>
#define PI 3.14159
int main()
{
int r;
float s;
for(r=1;r<=10;r++)
{
s=PI*r*r;
if(s>100)
break; //break语句用于终止循环的执行,以便提前结束循环
printf("r=%d,s=%.2f\n",r,s);
}
return 0;
}
运行结果为:
二、循环嵌套
一个循环体内又包含了另一个完整的循环结构,这种循环称为循环的嵌套或多重循环。使用循环嵌套时,3种循环语句可以自身嵌套,也可以互相嵌套。
举一个简单的例子:
for(i=1;i<=3;i++) //外循环
for(k=1,k<=5;k++) //内循环,也是为循环的循环体
printf("*");
输出结果是:15个“*”。
显然,上面的程序是for循环中又包含了一个for循环,属于两层循环结构。外循环用变量 i 控制,内循环用变量 k 控制,外循环 i 从1到3,外循环每执行1次,内循环 k 从1到5,循环5次,所以输出结果为3*5=15个“ * ”。
又例如:
for(i=1;i<=3;i++)
for(k=1;k<=5;k++)
printf(" * ");
printf("\n");
上面的程序段仍然输出15个“ * ”,不过因为加了换行操作,输出的是3行5列的“ * ”方阵。
注:输出若干行,若干列的图案时,可考虑使用两层循环,外循环控制行数,内循环控制各行的列数,内外循环之间要加入换行操作。
例7:输出九九乘法表。
【编程思路】
(1)九九乘法表共有9行,定义变量 i 表示行数,使其从1递增到9.
(2)每一行中的被乘数从1变化到和本行行号相同的数字,用变量 j 表示被乘数,让其从1递增到当前行号 i 。
(3)用外层循环实现行的转换,内层循环输出一行中的内容,而内层循环的循环体是输出每一行中的某一项。
【程序代码】
#include<stdio.h>
int main()
{
int i,j;
for(i=1;i<=9;i++) //外循环控制要输出的行号
{
for(j=1;j<=i;j++) //内循环控制要输出的项目数
printf("%2d*%1d=%2d",i,j,i*j); //输出第i行第j项的内容
printf("\n"); //每行结束换行
}
return 0;
}
【输出结果】
例8:编写程序,如图所示。
【编程思路】
(1)图形中共有6行,定义变量 i 表示行数,使其从1递增到6.
(2)每行中要有若干个空格,若干个“ * ”及换行。
(3)仔细数会发现,每行空格数分别为6、5、4、3、2、1,如果与行号联系起来,每行要输出的空格数为7-i个。
(4)每行“ * ”的个数分别为1、3、4、7、9、11,正好是2*i-1个。
(5)用外层循环实现行的转换,内层循环输出各行内容。
【程序代码】
#include<stdio.h>
int main()
{
int i,j;
for(i=1;i<=6;i++) //外循环控制要输出的行数
{
for(j=1;j<=7-i;j++) //内循环1控制要输出的空格符
printf(" ");
for(j=1;j<=2*i-1;j++) //内循环2控制输出的“ * ”
printf("*");
printf("\n");
}
return 0;
}