C语言第05次课.docx
《C语言第05次课.docx》由会员分享,可在线阅读,更多相关《C语言第05次课.docx(18页珍藏版)》请在冰点文库上搜索。
C语言第05次课
4.3 do-while语句
do-while语句与while语句十分相似,只是do-while语句先执行循环体语句再进行判断循环条件,而while语句是先判断循环条件再执行循环体语句。
do-while语句的一般格式:
do
{
循环体语句;
}while(表达式);
●表达式:
用作循环条件,与在while语句中的作用一样。
●循环体语句:
被重复执行的语句。
●注意:
在while(表达式)后面一定有分号“;”。
其语义是:
先执行循环体语句,再判断表达式的值,如为真(非0)则反复执行循环体语句,如为假(为0)则退出while循环继续执行do-while语句的后续语句。
其过程如图4.3所示。
用do-while语句完成本章任务
(1):
main()
{
inti,sum=0;
i=1;
do
{
sum=sum+i;
i++;
}while(i<=100);
printf("1+2+...+100=%d",sum);
getch();
}
输出结果:
1+2+...+100=5050
【例4.8】由键盘输入一个整数n,反序输出。
如输入:
3214665,则输出5664123
分析:
①可先取出此数n的最后一位:
n%10输出
②再用用此数除以10取整数部分n=n/10判断是不是为0,如果不是0则重复从①开始执行,直到(n=n/10)==0
程序如下:
main()
{
longn;
printf("Inputn:
");
scanf("%ld",&n);
do
{
printf("%ld",n%10);
}
while(n/=10);
getch();
}
【例4.9】编程实现猜数游戏,先由计算机随机生成一个1~100之间的数让人猜,如果人猜对了,在屏幕上输出此人猜了多少次猜对此数,以此来反映猜数者“猜”数水平,则结束游戏;否则计算机给出提示,告诉人所猜的数是太大还是太小,最多可以猜10次,如果猜了10次仍未猜中的话,给出失败提示,游戏结束。
分析:
本题要完成的主要任务有如下几步,
1计算机随机产生一个1~100间的数,C语言提供了随机函数rand(),功能产生0~32767之间的随机数。
可以用rand()%100+1来得到1~100间的任意数。
注意:
使用此函数有的编译器需要在程序的开始处添加文件包含:
#include
2用循环语句实现猜数功能,循环体内用if语句判断是否猜对,并对猜对与否处出相应处理。
程序如下:
#include/*由于要用到函数rando()及randomize()故需要添加此声明*/
main()
{
inti,n,ran,right;/*i用于统计猜数次数,ran用于存放计算机随机产生的数,
right用于标识是否猜的正确,如正确为1否则为0*/
i=0;
right=0;
randomize();/*用在TC编译器中,初始化随机数发生器,如没有此语句会使
每次运行时,rand()得到的随机值都一样,从而不能实现随机*/
ran=rand()%100+1;/*在上一条语句的基础上实现随机得到1个1~100之间的数*/
do
{
printf("\nYouhave%dchances.inputanum:
",10-i);
scanf("%d",&n);
if(n==ran)
right=1;
elseif(n>ran)
printf("\n%distoobig.\n",n);
else
printf("\n%distoosmall.\n",n);
i++;
}
while(right!
=1&&i<10);/*如没猜对且猜数次数没超过10次则重复进行猜数*/
if(right==1)
printf("\nCongratulations,num=%d,youarerightat%dthtime.",ran,i);
else
printf("\nSorry,youhavenochansetoguessthenum,num=%d.",ran);
getch();
}
4.4 用于循环中的break语句和continue语句
在第3章学习switch结构时学到了break语句,用于退出switch语句。
在循环语句中如果想要在循环条件仍然满足的情况下提前退出循环语句也可以用break语句。
在循环语句的应用中,有时在某种特殊的情况下想结束某次循环而不是完全退出循环语句时可以使用continue语句来实现。
下面就逐一介绍break语句与continue语句在循环语句中的应用。
4.4.1 break语句
break语句格式:
break;
break语句适用于学过的任何一种循环语句,一般放在循环体中的某个if语句的分支中。
作用在于一旦执行到break语句则立即结束break所在的循环语句。
也可以起到替代循环条件的作用。
【例4.10】分析如下程序,给出程序执行结果。
main()
{
inti;
for(i=0;;i++)
{
if(i>=10)break;/*执行到break语句则直接退出整个循环语句*/
if(i%2==0)
printf("%d",i);
}
getch();
}
本程序中的for语句中如没有break语句就成为死循环,break语句起到了替代for语句中的条件语句的作用,据for语句的执行流程可得到本题的输出结果为:
02468。
【例4.11】从键盘任意输入一个正数n,判断其是不是素数(因子只有1及其本身,其值大于1的自然数)。
分析:
可用2~n-1之间的各个自然数去除n,如某个数i整除则说明n除了1及其本身外还有其他的因子i,故可断定n不是素数。
如所有的数都不能整除则可断定n是素数。
经数学方法证明用于除n的数无需2~n-1只要用2~
之间的数去除即可。
同时在C语言中有sqrt()这个函数求一个数的平方根。
程序如下:
#include/*由于sqrt()的定义在库头文件math.h中因此要声明此文件包含*/
main()
{
intn,i,k;/*n作为要输入的数,i为循环变量,k存放n的平方根*/
clrscr();
printf("Inputn(n>=2):
");
scanf("%d",&n);
k=sqrt(n);/*把n的平方根存在k变量中*/
for(i=2;i<=k;i++)
{
if(n%i==0)break;/*如i取某值时能整除n,则提前结束for循环*/
}
if(i==k+1&&n>1)/*如i的值已累加到k+1,则说明for循环没有提前结束,同时判断n的值是不是大于1,如同时成立说明是素数*/
printf("%disaprimenumber.",n);
else
printf("%disnotaprimenumber.",n);
getch();
}
运行结果:
Inputn(n>=2):
19↙
19isaprimenumber.
4.4.2 continue语句
continue语句格式:
continue;
continue语句与break语句一样也适用于学过的任何一种循环语句,也是一般放在循环体中的某个if语句的分支中。
作用在于一旦执行到continue语句则立即结束本次循环进入下一次循环。
continue语句与break语句的作用是不同的,continue语句是结束一次循环,而break是结束整个循环。
【例4.12】分析如下程序,给出程序执行结果。
main()
{
inti;
for(i=0;i<10;i++)
{
if(i%2==0)continue;/*执行到continue语句则跳过其后的循环体语句,直
接去执行for语句的表达式3(即:
i++),继续进
行循环体的下一次循环*/
printf("%d",i);
}
getch();
}
本程序for语句中如没有continue语句则直接输出:
0123456789,而本题中的if语句使得当i能被2整除时则执行continue语句,同时continue语句的作用是跳过其后的语句进行下一次循环,所以导致无法输出能被2整除的数。
故本题输出结果是:
13579。
【例4.13】随机输入多个字符,直到输入回车结束,统计键入空格字符的次数。
程序如下:
#include
main()
{
intcount=0;
charch;
printf("Inputchars:
");
do
{
ch=getchar();
if(ch!
='')continue;
count++;
}
while(ch!
='\n');
printf("Thenumberofspacesis%d.\n",count);
getch();
}
运行结果:
Inputchars:
aabbccddeeff↙
Thenumberofspacesis5.
4.5 循环结构的嵌套
循环结构与分支结构一样也可能进行嵌套,所谓循环语句的嵌套就是把一个循环语句的整体嵌入到另一个循环语句的循环体中。
循环语句的嵌套可以有多重,一个层循环语句外面包围一层循环称为双重循环,如包围二层循环称作三重循环,……,一个循环的外面包围三层或三层以上的循环称为多重循环。
理论上循环结构的嵌套层数可以无限多,但实际应用中最好使嵌套的层次尽量少,因较多的层次会使程序的执行效率大大降低。
正常情况下:
应先执行内层的循环体操作,然后是外层循环。
例如:
对于双重循环,内层循环被执行的次数应为:
内层次数×外层次数。
三种循环语句for、while、do-while可以互相嵌套,自由组合。
外层循环体中可以包含一个或多个内层循环结构,但要注意的是,各循环必须完整包含,相互之间绝对不允许有交叉现象。
因此每一层循环体都应该用{}括起来。
下面的形式是不允许的:
for(;;)
{……
do
{……
}
}while();
在这个嵌套中for语句与do-while语句出现了交叉。
下面的循环嵌套都是合法的:
1:
for(;;)
{
……
for(;;)
{
……
}
}
2:
for(;;)
{
……
while()
{
……
}
}
3:
for(;;)
{
……
do
{
……
}while()
}
4:
while()
{
……
while()
{
……
}
}
5:
while()
{
……
for(;;)
{
……
}
}
6:
while()
{
……
do
{
……
}while()
}
7:
do
{
……
do
{
……
}while()
}while()
8:
do
{
……
for(;;)
{
……
}
}while()
9:
do
{
……
while()
{
……
}
}while()
循环嵌套应用实例:
【例4.14】编程实现在屏幕上输出九九乘法口诀。
分析:
分行与列考虑,可用i控制行,j控制列,共9行,且每行的等式的个数与所在行的序数相同,即第i行就有i列个等式。
程序如下:
main()
{
inti,j;
for(i=1;i<=9;i++)/*外层for循环控制口诀的行*/
{
for(j=1;j<=i;j++)/*内层for循环控制输出口诀中某行的各列*/
{
printf("%d*%d=%d\t",j,i,i*j);/*输出各等式*/
}
printf("\n");/*每输出一行后加一个回车符*/
}
getch();
}
【例4.15】在【例4.11】的基础上输出1000内所有的素数,要求每行输出15个数。
分析:
在【例4.11】判断素数算法的基础上外面包围一个循环语句可得。
程序如下:
#include
main()
{
inti,j,k,n=0;/*i,用于外层循环的循环变量,j,用于内层循环的循环变量,k,用于存放sqrt(i),n,用于控制一行输出15个数的变量*/
for(i=2;i<=1000;i++)/*外层循环提供2~1000的数*/
{
k=sqrt(i);
for(j=2;j<=k;j++)/*内层循环对外层提供的数进行是否是素数的判断*/
{
if(i%j==0)break;/*注意此时的break只是退出内层循环(即:
for(j=2;j<=k;j++)这个循环),而不是退出所有的循环*/
}
if(j==k+1)/*当j累加到k+1时说明此时的i就是素数*/
{
printf("%5d",i);/*以每个数占5个字符宽的方式输出i*/
n++;/*当输出一个素数是n累加1*/
if(n%15==0)/*当n累加到能被15整除时输出一个回车*/
printf("\n");
}
}
getch();
}
【例4.16】打印出如下图案(菱形)
*
***
*****
*******
*****
***
*
分析:
这类题无非就是正确输出每行的星号“*”与空格“”的数目。
本题可先把图形分成两部分来看待,前四行一个规律(每行空格的数目分别是3,2,1,0,同时每行“*”的数目分别是1,3,5,7),后三行一个规律(每行空格的数目分别是1,2,3,同时每行“*”的数目分别是5,3,1),再分析前一部分(前四行)想办法用数学等式把每行的空格数与星号数与行的序号(假设为i且从0开始计数,则前四行行序数分别是第0行,第1行,第2行,第3行)联系起来,容易得出每行的空格数是:
3-i,每行星号数是:
2*i+1。
最后分析后一部分(后三行)用数学等式把每行的空格数与星号数与行的序号(假设为仍为i且也从0开始计数,则后三行行序数分别是第0行,第1行,第2行)联系起来,容易得出每行的空格数是:
i+1,每行星号数是:
5-2*i。
利用双重for循环,外层控制行,内层控制列。
程序如下:
main()
{
inti,j;
for(i=0;i<=3;i++)/*此for循环及其内部的两个for循环处理前四行的输出,i作为行序号*/
{
for(j=0;j<3-i;j++)/*此for循环实现输出前四行中每行的空格*/
printf("");
for(j=0;j<2*i+1;j++)/*此for循环实现输出前四行中每行的星号*/
printf("*");
printf("\n");/*每输出一定数量空格及星号后输出一个回车符*/
}
for(i=0;i<=2;i++)/*此for循环及其内部的两个for循环处理后三行的输出,i作为行序号*/
{
for(j=0;j
printf("");
for(j=0;j<5-2*i;j++)/*此for循环实现输出后三行中每行的星号*/
printf("*");
printf("\n");/*每输出一定数量空格及星号后输出一个回车符*/
}
getch();
}
【例4.17】编程实现猜数游戏,先由计算机随机生成一个1~100之间的数让人猜,如果人猜对了,在屏幕上输出此人猜了多少次猜对此数,以此来反映猜数者“猜”数水平,则结束游戏;否则计算机给出提示,告诉人所猜的数是太大还是太小,最多可以猜10次,如果猜了10次仍未猜中的话,给出失败提示,则停止本次猜数,然后继续猜下一个数。
每次运行程序可以反复猜多个数,直到操作者想停止时才结束。
分析:
在【例4.9】的基础上再添加一个外层循环语句,就变得容易了。
程序如下:
#include/*由于要用到函数rando()及randomize()故需要添加此声明*/
main()
{
charch;/*新加的变量,要用户输入字符,如果输入的是“Y”或“y”则继续游戏,否则退出游戏*/
inti,n,ran,right;
do/*添加的外层循环*/
{
clrscr();
i=0;
right=0;
randomize();
ran=rand()%100+1;
do
{
printf("\nYouhave%dchances.inputanum:
",10-i);
scanf("%d",&n);
if(n==ran)
right=1;
elseif(n>ran)
printf("\n%distoobig.\n",n);
else
printf("\n%distoosmall.\n",n);
i++;
}
while(right!
=1&&i<10);
if(right==1)
printf("\nCongratulations,num=%d,youarerightat%dthtime.",ran,i);
else
printf("\nSorry,youhavenochansetoguessthenum,num=%d.",ran);
printf("\nDoyouwantcontinueplay(Y/N)?
");
scanf("%c",&ch);/*输入字符给ch*/
}
while(ch=='y'||ch=='Y');/*如ch值为y或Y则继续下次游戏*/
}
4.6 goto语句
goto语句是一种跳转语句,可以用于程序的任何地方。
goto语句的一般格式为:
goto语句标号;
其中语句标号就是一个合法的标识符。
能用goto语句的前提是在同一个函数(可以是主函数也可是其他函数)中某个语句前存在标号,语句标号的作用在于标识出其后语句的位置,语句标号的使用方法是在合法标识符后面加上一个冒号“:
”。
如:
label:
i=j+2;
中的label1就是一个语句标号。
这时可用goto语句来跳转到label处。
方法如下:
gotolabel;
此时程序遇到goto语句之后会无条件的跳到label所标识的语句(i=j+2)处开始执行。
goto语句的作用:
(1)与if语句合用可起到循环语句的作用。
当然在实际应用中能用学过的循环语句完成尽量不用goto语句,因程序中随意使用goto语句会使程序的可读性变差,流程变得混乱。
(2)跳出多重循环,学过的break只能退出break所在的循环语句,当循环语句多层嵌套时用goto语句实现较为方便。
【例4.18】用goto语句实现1+2+3+…+100结果的输出。
程序如下:
main()
{
inti=0,s=0;
label:
i++;
s+=i;
if(i<100)
gotolabel;
printf("1+2+3+…+100=%d",s);
getch();
}
【例4.19】分析如下程序总结goto语句的作用。
程序如下:
main()
{
inti=0,j;
while
(1)
{
while
(1)
{
while
(1)
{
while
(1)
{
printf("test");
gotolabel;
}
}
}
}
label:
printf("\nexit");
getch();
}
本程序是由四重永真循环嵌套而成,如不用goto语句需要4个break语句才能退出这个嵌套循环,而用goto语句显然使程序简洁得多。