第5章 循环结构 在第1章中看到算法中有一些步骤是被重复执行的。这种重复执行是通过 某一个有条件的跳转指令实现的,即根据某一条件决定某些语句是否被重复执 行。这种在程序中不断被重复执行的结构,被称为循环结构。循环结构有时也 被称为重复结构。本章主要介绍三种循环结构语句及其应用。 本章学习目标 (1)掌握三种循环语句的基本用法。 (2)能应用循环结构编程解决问题。 (3)能灵活应用穷举法和多重循环。 (4)能灵活使用break和continue语句。 第5章案例代码 5.1 循环语句 ●1.while循环(当型循环) C语言中,while语句用来实现“当型”循环结构(图5-1),它的一般形式如下: while(表达式) 循环体语句; 功能说明: (1)首先求解表达式的值,若表达式的值为真,则执行循环体,否则结束循环。 (2)循环体语句执行完成后,自动转到循环开始处再次求解表达式的值,开始下一次 循环。 (3)循环体只能是一个语句。若有多个语句,则应该用大括号将其括起来使之成为 一个复合语句。 ●2.do-while循环(直到型循环) 在C语言中,可以用do-while语句实现“直到型”循环结构(图5-2),它的一般形式 如下: do 循环体语句; while(表达式); 图5-1 while循环 图5-2 do-while循环 功能说明: (1)在此结构中,do相当于一个标号(其后面不用加:),标志循环结构开始。 (2)首先无条件地执行一次循环体,然后求解表达式的值。若表达式的值为真,则再 次执行循环体(转到do),开始下次循环,否则结束循环。 (3)若循环体多于一个语句,则应使用复合语句。 ·95· (4)do-while结构整体上是一条语句,所以大家不要忘记在while的括号后加上语句 结束符———分号。 ●3.for循环 除了while语句和do-while语句,C语言还提供了另外一个使用最为广泛的循环语 句———for语句(图5-3)。 图5-3 for语句 for语句的一般形式为: for(表达式1;表达式2;表达式3) 循环体语句; 功能说明: (1)求解表达式1(该表达式只在这一步骤被求解一次)。 (2)求解表达式2,若为真,则执行循环体,否则结束for语句。 (3)循环体执行结束后,求解表达式3,并转向步骤(2)。 (4)循环体语句应该为一条语句,如果有多条语句要执行,则应该使用复合语句。 案例05-01-01 输出从1加到n 的和 案例代码05-01-01-A.c(while语句实现) #include int main(){ int i,s,n; i=1; s=0; scanf("%d",&n); while(i<=n){ s=s+i; i=i+1; } printf("%d",s); ·96· return 0; } 执行程序,输入:1000,输出:500500 案例代码05-01-01-B.c(do-while语句实现) #include int main(){ int i,s,n; scanf("%d",&n); i=1; s=0; do{ s=s+i; i=i+1; }while(i<=n); printf("%d",s); return 0; } 案例代码05-01-01-C.c(for语句实现) #include int main(){ int i,s=0,n; scanf("%d",&n); for(i=1;i<=n;i++) s=s+i; printf("%d",s); return 0; } 案例拓展输出约数 编程输入一个正整数,输出它所有的约数。 输入样例:100 输出样例:1 2 4 5 10 20 25 50 100 案例05-01-02 输出最大公约数 输入两个数,输出它们的最大公约数。 输入样例:36 24 输出样例:12 案例代码05-01-02-A.c (穷举法,用while语句实现) #include int main(){ int m,n,i,k; scanf("%d%d",&m,&n); ·97· i=1; while(i<=n&&i<=m){ if(m%i==0&&n%i==0) k=i; i++; } printf("%d",k); return 0; } 执行程序,输入: 36 48 输出: 12 案例代码05-01-02-B.c (穷举法,用for语句实现) #include int main(){ int m,n,i,k; scanf("%d%d",&m,&n); for(i=1;i<=n&&i<=m;i++) if(m%i==0&&n%i==0) k=i; printf("%d",k); return 0; } 案例代码05-01-02-C.c (辗转相除法,用while语句实现) #include int main(){ int m,n,t; scanf("%d%d",&m,&n); while(m%n!=0){ t=m%n; m=n; n=t; } printf("%d",n); return 0; } 案例拓展输出最小公倍数 输入两个数,输出它们的最小公倍数。 输入样例:36 24 输出样例:72 ·98· 案例05-01-03 素数判断 输入一个正整数,输出其是否为素数。 案例代码05-01-03-A.c #include int main(){ int n,i,f=1; scanf("%d",&n); for(i=2;i int main(){ int n,i,f=1; scanf("%d",&n); for(i=2;i<=sqrt(n)&&f==1;i++) //判断n 在区间[2,sqrt(n)]是否有约数 if(n%i==0) f=0; printf(f==1? "YES":"NO"); return 0; } 执行程序,输入: 17 输出: YES 案例拓展2的迭代 有一个迭代公式很神奇:xn = xn-1+2,无论x 的初值(正数)选得多么大,若干次迭 ·99· 代之后,都与2无限接近,也就是说,x 序列的极限是2。假设x0=99999999,编程输入 一个正整数n,输出xn 的值(保留10位小数)。 输入样例1:16 输出样例1:x [16]=2.0000000790 输入样例2:8 输出样例2:x [8]=2.0051798692 案例05-01-04 用穷举法算阶乘 输入一个正整数n 的值,编程输出n! (n 的阶乘)。 案例代码05-01-04-A.c (穷举法,用for语句实现) #include int main(){ long long i, n; long long fact=1; / * 将 累 乘积fact 初始化为1 */ scanf("%lld", &n); for(i=1; i<=n; i++) fact *= i; /* 实现累乘*/ printf("%lld!=%lld", n, fact); return 0; } 执行程序,输入:5 输出:5!=120 案例代码05-01-04-B.c (穷举法,用while语句实现) #include int main(){ long long i, n; long long fact=1; /* 将累乘积fact 初始化为1 */ scanf("%lld", &n); i=1; while(i<=n){ fact *= i; /* 实现累乘*/ i++; } printf("%lld!=%lld", n, fact); return 0; } 案例拓展乘方计算 给出一个整数a 和一个正整数n,求乘方an 。 输入格式:一行,包含两个整数a 和n。-1000≤a≤1000,1≤n≤100。 输出格式:一个整数,即乘方结果。题目保证最终结果的绝对值不超过1000000。 ·100· 输入样例:2 3 输出样例:8 案例05-01-05Fibonacci数列 Fibonacci数列的通项公式为:fn = 1 (n=1,2) fn-1+fn-2 (n>{ 2) ,编程读入整数n(2< n≤40),输出Fibonacci数列的前n 项。 案例代码05-01-05.c #include int main(){ long int f1,f2,f3,n; int i; scanf("%ld",&n); f1=1; f2=1; printf("%ld,%ld", f1, f2); for(i=3;i<=n;i++ ){ f3 = f1 + f2; f1 = f2; f2 = f3; printf(",%ld", f3); } return 0; } 执行程序,输入20,输出: 1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765 案例拓展计算e的近似值 本题要求:编写程序,输入一个较小的实数deta,利用e=1+1 1!+1 2!+1 3!+…+ 1 n! 计算e的近似值,直到最后一项的绝对值小于deta时为止,输出此时e的近似值。 5.2 循环控制语句 ●1.break语句 break语句的一般形式是: break; 功能说明: (1)在循环体内,当程序执行到break语句时,会立即跳出循环结构,即提前结束循 ·101· 环体。 (2)break语句通常出现在某个if语句的分支中,以实现有条件地结束循环。 (3)break语句只能用于switch结构内部或循环结构内部。 ●2.continue语句 continue语句的一般形式是: continue; 功能说明: (1)在循环体内,当程序执行到continue语句时,会立即结束本次循环(跳过循环体, continue语句后面的部分不执行),接着执行下一次循环。 (2)continue语句通常出现在某个if语句的分支中。 (3)continue语句只能用于循环结构的内部。 案例05-02-01 输出从1加到n 的和(应用break语句) 案例代码05-02-01-A.c #include int main(){ int i,s,n; i=1; s=0; scanf("%d",&n); while(1){ s=s+i; i=i+1; if(i>n) break; } printf("%d",s); return 0; } 执行程序,输入1000,输出: S=500500 案例代码05-02-01-B.c #include int main(){ int i,s,n; scanf("%d",&n); for(i=1,s=0; ;i++) { ·102· if(i>n) break; s=s+i; } printf("%d",s); return 0; } 案例拓展输出最大公约数(应用break语句) 编程输入正整数m 和n,输出它们的最大公约数,要求在循环中应用break语句。 案例05-02-02 输出ASCII码 输入一串字符(以#字符结束),依次输出每个字符及其ASCII码(不包括结束符#)。 案例代码05-02-02.c #include int main(){ char c; int i=1; do{ scanf("%c",&c); if(c=='#') break; printf("%c-%d\n",c,c); }while(1); return 0; } 执行程序,输入: A23# 输出: A-65 2-50 3-51 案例拓展输出数字和 输入一串字符(以#字符结束),输出这串字符中所有数字字符的和。 输入样例:ABC123DE4FG# 输出样例:10 案例05-02-03 输出不能被2、3、5、7和13整除的数 编程输入整数a 和b,输出a、b 之间(包括a、b 本身)的不能被2、3、5、7和13整除 的数。 ·103·