当前位置:文档之家› 第6章 循环结构程序设计

第6章 循环结构程序设计

第6章循环结构程序设计【计划课时】授课6课时+上机4课时6.1 概述循环是在循环条件为真时计算机反复执行的一组指令(循环体)。

循环控制通常有两种方式:·计数控制——事先能够准确知道循环次数时用之用专门的循环变量来计算循环的次数,循环变量的值在每次执行完循环体各语句后递增,达到预定循环次数时则终止循环,继续执行循环结构后的语句。

·标记控制——事先不知道准确的循环次数时用之由专门的标记变量控制循环是否继续进行。

当标记变量的值达到指定的标记值时,循环终止,继续执行循环结构后的语句。

在C语言中可用以下语句构成循环:if … gotowhiledo … whilefor6.2if … goto语句循环结构P106goto是一种无条件转向语句。

一般形式:goto标号;if … goto 可构成当型/直到型循环结构(尽量少用,以提高程序可读性/结构性)。

【例一】{int n=0,sum=0;loop: sum+=n;++n;if (sum<=10000) goto loop;printf(“n = %d\n”,n);}6.3 while 语句循环结构 P107一般形式 while (条件表达式) 循环体;用于构成当型循环:先判断后执行/条件为真继续循环,直到条件为假时结束循环。

【注意】条件表达式或循环体内应有改变条件使循环结束的语句,否则可能陷入“死循环”。

【例一】main() { int n=0; while (n<=2) { n++;printf(“%d”,n); } }结果:123【讨论】若去while 语句中的{},结果:3;若将n++移到printf 语句中,结果:012【例二】int n=0;while (n++<=2); printf(“%d”,n); 结果:4【讨论】n=3时,while 条件为假,结束循环,但比较后n 自加了一,所以n=4。

【例三】main() {int i=0; while (1) {printf(“*”); i++;【例二】 main() {int n=0,sum=0;loop: if (sum>=10000) goto end;sum+=n; ++n;goto loop;end: printf(“n = %d \n”,n);}if (i<3) break; }printf(“\n”);}}结果:*【讨论】若将if (i<3)改为if (i>3),结果:****【例四】编程实例研究:求解全班平均成绩问题描述:某个班中有n个学生,已知他们参加某次考试的成绩(0至100之间的整数),编程求全班学生在这次考试中的平均成绩。

思路:使用用自顶向下、逐步求精的技术,先用伪码表示问题的顶层:Determine the class average for the quiz (求解全班平均成绩)顶层只有一句(描述程序的整个功能,但未给出足够的细节)。

第一步求精——initialize variables (初始化变量)input,sum,count the quiz grades (输入各人成绩,求其总和,计数键入次数) calculate and print the class average (计算并输出全班的平均成绩)这里只用到顺序结构,即所列出的步骤是按顺序一个接一个执行的。

说明:如果用total表示总成绩,用counter表示键入成绩的次数,则使用前这两个变量应先初始化(设置为0)。

第二步求精:①伪码语句 initialize variables可作如下求精:initialize total to zeroinitialize counter to zero讨论:为什么只对这两个变量进行初始化?②伪码语句 input,sum,count the quiz grades可作如下求精:input the first gradewhile the user has not as yet entered the sentineladd this grade into the running totaladd one to the grade counterinput the next grade(possibly the sentinel)因为本例不知道要输入多少个成绩,所以程序必须能够处理任意个数的成绩。

程序如何判断何时终止输入成绩呢?方法之一是使用一个专门的值来指示数据输入的结束。

这个值称为“标志值”(sentinet value)。

由于考试成绩是非负的整数值,本例中将取-1为标记值。

③伪码语句 calculate and print the class average可作如下求精:if the counter is not equal to zeroset the average to the total divided by the counterprint the averageelseprint “No grades were entered”说明:被0除是一种致命的错误,如果不能明确检测并在程序中作适当的处理,将会导致程序执行失败(“崩溃”)。

当伪码算法详细到能够把伪码转换为C程序时,即可着手编写程序了。

参考程序如下:/*用标记控制的循环求全班平均成绩的程序*/#include <stdio.h>main( ){float average; /*变量声明*/int counter,grade,total;/*初始化阶段*/total=0;counter=0;/*处理阶段*/printf(“请输入成绩(用-1结束输入):”);scanf(“%d”,&grade);while (grade!=-1) {total=total+grade;counter=counter+1;printf(“(“请输入成绩(用-1结束输入):”);scanf(“%d”,&grade);}/*终止阶段*/if (counter!=0){average=(float)total/counter;printf(“全班平均值是%.2f”,average);}elseprintf(“还没有输入成绩!\n”);return 0; /*表明程序成功地结束*/}6.4 do … while语句循环结构P108一般形式 do {循环语句(组)} while (条件表达式);用于构成直到型循环:先执行后判断/条件为真继续循环,直到条件为假时结束循环。

【例一】main(){int n=0;do n++;while(n<5);printf(“%d”,n);}结果:5【讨论】如果将最后两句合成:do printf(“%d”,n++);while(n<5); 结果:01234【例二】求∑i =1+2+3+4…+99+100 (i=0~100)main(){int i=1,sum=0;do{ sum=sum+i;i++;} while (i<=100);printf(“Sum=%d\n”,sum);}【例三】从键盘输入一个整数,分析以下程序运行结果。

思路:若X为整数,则X%10可得X的个位数 X/10可得X的个位数移去后形成的新数如:125%10=5 → 125/10=12 → 12%10=2 → 12/10=1 → 1%10=0 → 1/10=0(结束)main(){int num,c;printf(“请输入一个整数:“);scanf(“%d”,&num);do{c=num%10; /*取得num的个位数*/printf(“%d”,c); /*输出num的个位数*/} while((num/=10)>0); /*直到num/10为0*/printf(“\n”);}结果:输入12456,输出65421(将各位数字反序显示出来)【讨论】如果while(num/=10>0),结果如何?陷入无限循环(输出无数个6)。

原因:num/=10>0中赋值号优先级最低,而num/(10>0)的结果除num=0(输出0)外均真。

6.5 for语句循环结构 P110一般形式 for (表达式1;条件表达式;表达式3){循环语句(组);}用于构成当型循环:先判断后执行/条件为真继续循环,直到条件为假时结束循环。

表达式1: 整个循环中只执行1次,常用来对循环变量设置初值条件表达式(表达式2): 其值为真(非0)时继续执行循环语句(组),否则结束循环表达式3: 常用于循环变量值的更新(循环体的一部分每次循环语句组执行完后执行一次)以下程序中执行几次循环?main(){ int i;for (i=2;i==0; )printf(“%d”,i++); }结果:0次【讨论】若i==2,结果为2,循环执行一次。

i为其他值时,同i==0。

【例二】求∑i =1+2+3+4…+99+100 (i=0~100)main(){ int i , sum=0;for (i=1;i<=100;i++) sum=sum+i;printf(“Sum=%d\n”,sum);}【例三】for ( a=1,i=-1; -1<=i<1;i++){ a++;printf(“%d”,a);}printf(“%d”,i);结果:-1【讨论】-1<=i<1为假(从左到右,-1<=i的值为1)【例四】for (i=0;i<3;i++)printf(“*”);printf(“%d”,i);结果:***3【例五】main(){ int a,i;for (i=0;printf(“a=”),scanf(“%d”,&a);i++) printf(“H”);}结果:a=1Ha=2Ha=6Ha=…(不管a为何整型数值,包括0,循环均不停止,但a为实型数值或字符等时,循环终止)scanf() 函数的返回值见P386。

正确输入时,返回数据个数,错误输入时返回0。

如c=scanf(“%d,%d,%d”,&a,&b,&c);如果a、b、c输入正确,c=3,否则c=0。

【讨论】如果for (i=0;printf(“a=”),scanf(“%d”,&a),a=a;i++) printf(“H”);则当a为0或-0时,循环结束(表达式2为逗号表达式,其值为最后赋值表达式的值。

【例七】下列程序段的for循环语句int i,x;for (i=0,x=0;i<=9&&x!=876;i++) scanf(“%d”,x);A)最多执行10次B)最多执行9次C)是无限循环D)循环体一次也不执行【例八】以下程序的输出结果是:main(){int y=10;while (y--);printf("y=%d\n",y);}A)y=0 B)y=1 C)y=随机值D)y=-16.8 break语句和continue语句 P114break在switch中退出switch结构/在循环中结束循环【例一】Array main(){int a,y;a=10,y=0;do { a+=2;y+=a;if (y>50) break;}while (a=14); /*每次循环到此 a值都为14*/printf(“a=%d,y=%d\n”,a,y);}结果:a=16,y=60②continue 循环“短路”(跳过循环体后面的语句,开始下一循环)。

相关主题