第5章第5章循环结构程序设计5.1学 习 要 求 循环结构可以解决需要重复处理的问题。 本章学习���求: (1) 主要掌握C语言的while循环语句,dowhile语句以及for语句的用法。 (2) 了解goto语句的用法,掌握break和continue关键字在循环结构中的使用方法和作用。 (3) 认识循环嵌套在C语言中的重要性,掌握循环嵌套的执行过程。 (4) 学会循环结构程序设计的方法和步骤,能够进行循环结构的程序设计。 5.2基 本 知 识 〖1〗5.2.1while循环与dowhile循环在C语言的循环结构中,while循环与dowhile循环是非常重要的两种语句。while循环称为当型循环,dowhile循环称为直到型循环。 1. while循环 while语句的一般形式为: while (表达式) 循环体语句 功能: 当循环条件表达式为真,执行循环体语句,执行完后,再判断条件表达式是否为真,为真,则再执行,直到条件表达式为假时退出while循环。 2. dowhile循环 dowhile语句的一般形式为: do 循环体 while (表达式);C语言程序设计习题与实验指导(第2版)第5章循环结构程序设计dowhile循环与while循环的不同之处在于: 它先执行循环体中的语句,然后再判断表达式是否为真,如果为真则继续循环;如果为假,则终止循环。因此,dowhile循环至少要执行一次循环体语句。 5.2.2for循环 for循环是C语言循环结构中使用*广泛的一种循环控制语句,尤其适合已知循环次数的情况。 1. for循环的格式 for循环的一般形式为: for ( 表达式1; 表达式2 ; 表达式3 ) 语句其中: 表达式1一般为赋值表达式,给控制变量赋初值。 表达式2通常为关系表达式或逻辑表达式,是循环控制的条件。 表达式3一般为赋值表达式,给控制变量增量或减量。 语句是循环体,当有多条语句时,必须使用复合语句。 for语句的执行过程如下: 首先计算表达式1,然后计算表达式2。若表达式2为真,则执行循环体;否则,退出 for循环,执行for循环后的语句。如果执行了循环体,则循环体每执行一次,都计算表达式3,然后重新计算表达式2,依此循环,直至表达式2的值为假,退出循环。 注意: for语句的三个表达式都是可以省略的,但分号“;”不能省略。 2. for循环的其他形式 (1) for语句的一般形式中的表达式1可以省略,此时应在for语句之前给循环变量赋初值,但省略表达式1时后面的分号不能省略。 (2) 如果表达式2省略,即不判断循环条件,循环无终止地执行下去,认为表达式2始终为真。 (3) 表达式3也可以省略,但应另外设法保证循环能正常结束。通常可将循环增量放在表达式3后面的位置作为循环体的一部分,起到的效果是一样的。 (4) 可以省略表达式1和表达式3,保留表达式2,相当于只给出循环条件。 (5) 三个表达式都可以省略,例如,for( ; ; )语句,相当于while(1) 语句。 即不设初值,不判断条件(认为表达式2始终为真值),循环变量不增值,无终止地执行循环体。 (6) 表达式1可以是设置循环变量初值的赋值表达式,也可以是与循环变量无关的其他表达式。 5.2.3循环的嵌套 一个循环体语句中又包含另一个循环语句,称为循环嵌套。 循环嵌套注意事项: (1) 使用循环嵌套时,内层循环和外层循环的循环控制变量不能相同。 (2) 循环嵌套结构的书写,*好采用“右缩进”格式,以体现循环层次的关系。 (3) 尽量避免太多和太深的循环嵌套结构。 循环嵌套可以解决很多问题,在C语言中经常用于按行列方式输出数据。前面涉及的for语句、while语句和dowhile语句三种循环可以互相嵌套。但要注意,各循环必须完整,相互之间不能交叉。 5.2.4流程的转移控制〖*4/5〗1. goto语句goto语句也称为无条件转移语句。 一般形式为: goto 语句标号 ; 其中语句标号是按标识符规定书写的符号,放在某一行的前面,标号后加冒号。语句标号起标识语句的作用,与goto语句配合使用。goto语句的作用是改变程序流向,转去执行语句标号所标识的语句,通常与条件语句配合使用,可用来实现条件转移、构成循环、跳出循环体等功能。C语言不限制程序中使用标号的次数,但各标号之间不能重名。 结构化程序设计中一般不主张过多使用goto语句,以免造成程序流程的混乱,使理解和调试程序产生困难。 2. break语句 break语句可以用于从循环体内跳出,即提前结束循环,接着执行循环后面的语句。 一般形式为: break;例如: int i,j=20; for(i=0;i<100;i++) if(i>j) break; j=i;当程序循环到i的值变为21时,执行break语句,跳出for循环,然后执行j=i的语句,*后j的值为21。 3. continue语句 continue语句的作用为结束本次循环,即跳过循环体中下面尚未执行的语句,提前进行下一次是否执行循环的判定。 一般形式为: continue;例如: int i,j=50; for(i=0;i<100;i++) { f(i>j) continue; j=i; }当程序循环到i的值变为51时,执行continue语句,结束本次循环,即不执行下面的j=i语句,而是执行i++,即i等于52,故i<100循环的条件成立,循环继续执行,直到i<100的条件不成立,for循环才终止。 注意: 在循环结构中,continue语句只用于结束本次循环,而break语句则是结束整个循环过程。 5.2.5典型例题 【例51】编写程序,在输入的10个整数中查找指定的某个数,输出该数出现的次数,并给出是否找到的提示信息。 问题解析: 编写程序时,先定义需要的变量并选好合适的数据类型。对于数的统计方法,可定义一个变量来实现计数器的功能。在10个数中查找某一个数,主要利用两个数的比对,如果相等,说明查到该数值,否则,说明不存在。*后,输出结果。 编写程序如下: #include int main( ) { int m,t,k,num=0; printf("输入要查找的数:"); scanf("%d",&m); printf("输入10个数:"); for(k=1;k<=10;k++) { scanf("%d",&t) ; if (m==t) num++; } if(num==0) printf("%d没有出现在输入的数中\n",m); elseif(num>0) printf("%d在输入的10个数中出现了%d次\n",m,num); return 0; }运行结果: 输入要查找的数: 2 输入10个数: 1 3 2 5 2 4 2 8 9 10 2在输入的10个数中出现了3次注意事项: (1) 利用循环实现多个数的输入,需要用变量记录输入数的个数。 (2) 编程时要注意必要的提示信息。 【例52】编写程序,输出10~1000正序读和反序读相同的所有数,并统计符合条件的数的个数。 问题解析: 先对10~1000的数进行分类考虑,将数分成两位数和三位数。两位数的情况需要求出每一个数的个位、十位上的数值,然后判断是否相等,如果相等,用计数器统计个数。三位数的情况则需要求出每一个数的个位、百位上的数值,然后判断这两个数是否相等,如果相等,同样用计数器计数,*后输出结果即可。 编写程序如下: #include void main() { int n; int j=0; for(n=10;n<=1000;n++) if(n<100) { if(n/10==n%10) { printf("%3d",n); j++; if(j%11==0)printf("\n"); } } else if (n>=100) if(n/100==n%10) { printf("%3d",n); j++; if(j%11==0) printf("\n"); } printf("符合要求的数有%d个\n ",j); }运行结果: 112233445566778899101111 121131141151161171181191202212222 232242252262272282292303313323333 343353363373383393404414424434444 454464474484494505515525535545555 565575585595606616626636646656666 676686696707717727737747757767777 787797808818828838848858868878888 898909919929939949959969979989999 符合要求的数有99个注意事项: 连续输出若干个数后换行的表达方法。 思考: 如果要筛选出10~100符合条件的数,for(n=10;(n<=100)&& (n/10==n%10);n++) 这样的写法是否正确? 5.3等级考试知识〖1〗5.3.1等级考试考点〖*4/5〗1. while和dowhile循环结构这两个考点属于C语言中**掌握的内容,通常考察while和dowhile两种循环结构的格式和循环的执行过程,要求能够区分两种循环的不同。可能出现在选择题和操作题的各种题型当中,考核概率约为80%。 2. for循环结构 本考点属于C语言中的**和难点,主要考察for语句的格式和循环的执行过程。for语句功能很强,表达式的省略形式变化*灵活,可能出现在操作题的各种题型当中,考核概率为****。 3. 循环结构的嵌套 循环结构作为循环结构的子语句,即一个循环体语句中包含另一个循环语句构成了循环嵌套。循环嵌套是二级考试中的**和难点,通常考察嵌套中内外循环的执行过程。循环嵌套中,内循环体从头到尾执行完,外循环体执行一遍。本考点考核概率约为60%,可能出现在操作题的各种题型当中。 4. continue语句和break语句 本考点在选择题、操作题中都有可能出现,要求掌握continue语句和break语句对循环的作用和影响,应注意比较两种语句的异同点。本考点属于难点,考核概率约为60%。 5. goto语句 goto语句为无条件转向语句,可以从循环体内跳出循环,尤其在多层循环中,使用goto语句可以跳到任一层循环体内。此知识点在操作题中可能出现,考核的概率约为20%。 5.3.2等级考试例题〖*4/5〗一、 选择题1. a和b为int型变量,则执行以下程序段后b的值为()。a=1; b=10; while (b--<0) { b-=a; a++; } A. 9 B. 8 C. -3 D. -4 【解析】本题考察while循环结构的执行过程。while循环是先判断条件是否满足,再执行循环体语句。b的初始值为10,b<0的判断是先取b的当前值10和0进行比较,然后b再减1,变成9。由于10<0的比较结果为假,循环条件不为真,循环体语句不执行。 【答案】A 2. 以下程序段()。x = -1; do{x = xx ; } while (!x); A. 是死循环 B. 循环执行一次 C. 循环执行二次 D. 有语法错误 【解析】本题考察dowhile语句的用法。dowhile的执行过程是先执行再判断,因此首先执行一次x=xx,x的值变为1,接着判断循环条件!x的逻辑值,!x为0,循环条件为假,循环退出。 【答案】B 3. 以下语句的循环执行次数是()。int i; for (i=2;i==0;) printf("%d",i--);A. 无限次 B. 0次 C. 1次 D. 2次 【解析】本题考察for语句的用法。本题中,for语句先执行表达式1,i=2,接着判断表达式2中i==0的值是否为真,i的值不为0,因此表达式比较的结果为假,不满足条件,for循环不执行循环体语句。 【答案】B 4. 以下程序段中t的*终值是()。int t=1,i=5; for(;i>=0;i--)t=i; printf("%d\n",t); A. 5 B. 20 C. 0 D. 60 【解析】本题考察for语句的用法。for语句表达式1省略,因此循环会在表达式2,循环体语句和表达式3中进行,i从5变化到0,并不断地与t相乘,使得t*终值变为0,接着i,i的值变为-1,i>=0的条件已经不满足,循环正常结束。 【答案】C 5. 执行以下程序后,输出字符'#'号的个数是()。#include void main() { int i,j; for(i=1; i<=4; i++) for(j=2; j<=i; j++) putchar('#'); }A. 1 B. 2 C. 4 D. 6 【解析】本题考察对循环嵌套执行过程的掌握。循环嵌套中,外循环执行一遍,内循环从头到尾执行完。上面程序中,外循环i从1到4, 当i值为1时,内循环中j从2开始,j<=i的表达式结果为假,因此循环体语句不执行。当外循环中i变为2时,内循环执行一次,打印一个字符'#'号,以此类推,随着i值增加,内循环执行次数随之也多一次,字符总共打印6次。 【答案】D 6. 以下关于break、continue语句的描述不正确的是()。 A. break语句可用在switch语句中 B. continue语句在循环语句中,作用是结束本次循环 C. break语句在循环语句中,作用是跳出循环体 D. break语句可用在switch语句和循环语句之外的其他语句中 【解析】本题考察对break和continue语句的理解。break语句不能用在switch语句与循环语句之外的其他语句中。 【答案】D 7. 以下程序运行后,输出结果是()。#include void main( ) { int i; for(i=100;i<200;i++) { if(i%5==0) continue; printf(“%d\n”,i); break; } }A. 20 B. 50 C. 101 D. 199 【解析】本题考察for循环中continue和break语句的作用。for语句中i的初始值为100,满足i<200的条件,进入循环体中执行if语句。由于****5结果为0,满足if条件,因此执行continue语句,本次循环提前结束。i++后,i值为101,重新进入for语句循环体中再次进行if条件的判断,这时101不能被5整除,因此 continue语句不执行,程序可以继续往下执行,输出i值101,接着又遇到了break语句,循环被彻底终止。 【答案】C 二、程序填空题 下列给定程序的功能是计算下面公式SN的值: SN=1+3/1十5/4+…+2N-1/SN-1 例如,当N=20时,SN=29.031674。 请填空,把程序补充完整,使它能得出正确的结果。#include void main() { int n=0,k; double sum=1.0,s1=0.0; printf("\nPlease input N=\n"); scanf("%d",&n); for(【1】;k<= 【2】;k++) { s1=sum; 【3】; } printf("\nsum=%f",sum); }【解析】本题是利用for循环来进行公式的计算。编程的关键是注意分析SN和SN-1前后两项数据的关系。由题目所给公式可知,多项式的**项为1,变量sum中存放多项式的和,其初始值为1。因此,循环从第二项开始,【1】处填“k=2”,k从2增加到n,【2】处填“n”。由公式可知,变量s1中存放各项表达式的值,因此,【3】处填“sum+=(2k-1)/sl”。 【答案】【1】 k=2,【2】 n,【3】 sum+=(2k-1)/s1。 三、 程序修改题 下列给定程序的功能是计算如下公式的值: Y=1-1/(22)+1/(33)-1/(44)+…+(-1)(n+1)/(nn) 例如,n中的值为10,则应输出0.817962。 请改正下面程序中的错误,使它能得出正确的结果。程序其他地方不做任何改动。#include void main() { int n=10; double y=1.0; /found/ int j=1; int i; for(i=2;i<=n;i++) { j=-1j; /found/ y+=1/(ii); } printf("\nThe result is%lf\n",y); }【解析】在程序中,变量j的作用是控制每一项符号的变化,并且作为运算的分子,应改为double型变量。因此,“int j=1;”应改为“double j=1.0;”。变量y中存放多项式的值,多项式中的每一项符号由变量j决定。因此,“y+=1/(ii);”应改为“y+=j/(ii);”。 【答案】(1) double j=1.0; (2) y+=j/(ii);