ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

《C程序设计(第五版)》第5章 循环结构程序设计:知识要点、案例分析与课后习题解析

《C程序设计(第五版)》第5章 循环结构程序设计:知识要点、案例分析与课后习题解析 一、章节概述循环结构是 C 语言三种基本结构顺序、选择、循环中最能体现程序设计“自动化与复用”思想的部分。实际编程中大量重复性工作都依赖循环完成例如累加求和、遍历数组、迭代求解方程、打印图形等。《C程序设计第五版》第 5 章围绕循环结构展开主要讲解while语句、do…while语句、for语句三种循环结构循环嵌套的设计方法break与continue在循环控制中的作用用循环解决典型数值计算与图形输出问题。本章是整个 C 语言学习的分水岭掌握好循环后续数组、函数、指针等章节才能顺利展开。二、知识要点详解2.1 while 语句while属于“当型循环”即先判断条件条件为真时执行循环体否则退出。while(表达式){循环体语句;}执行流程计算“表达式”的值若为真非 0执行循环体然后回到第 1 步若为假0退出循环。需要特别注意的是循环体内必须包含能使循环趋向结束的操作否则会成为“死循环”。2.2 do…while 语句do…while属于“直到型循环”先执行一次循环体再判断条件。do{循环体语句;}while(表达式);它与while的最大区别在于无论条件是否成立循环体至少执行一次。2.3 for 语句for语句是 C 语言中最灵活、使用频率最高的循环结构for(表达式1;表达式2;表达式3){循环体语句;}表达式 1循环变量初始化只在开始时执行一次表达式 2循环条件每次执行前判断表达式 3循环变量调整每次循环体执行完后执行。for语句等价于下面的while语句表达式1;while(表达式2){循环体语句;表达式3;}三个表达式均可省略但分号不能省略例如for ( ; ; )表示无限循环。2.4 循环嵌套一个循环体内又包含另一个完整的循环结构称为循环嵌套。外层循环执行一次内层循环要完成一轮完整循环。for(i1;i3;i){for(j1;j3;j){printf(i%d, j%d\n,i,j);}}嵌套循环常用于处理二维问题如打印矩形、三角形、乘法口诀表等。设计时要抓住“外层控行、内层控列”的规律。2.5 break 与 continuebreak提前终止整个循环跳出当前循环体执行循环之后的语句在嵌套循环中只跳出所在的那一层循环。continue结束本次循环跳过循环体中剩余语句直接进入下一次循环条件判断。两者区别可以用下面代码体会for(i1;i5;i){if(i3)continue;/* i3 时跳过 printf */if(i5)break;/* i5 时提前结束循环 */printf(%d ,i);}/* 输出结果1 2 4 */2.6 三种循环的比较与选择循环次数明确时首选for循环次数不明确、需先判断后执行时选while至少需执行一次循环体时选do…while。三种循环可以相互转换但for结构最紧凑、可读性最好。三、案例分析案例 1累加求和求1 2 3 … 100的和。#includestdio.hintmain(void){inti,sum0;/* sum 必须初始化为 0 */for(i1;i100;i){sumi;}printf(sum %d\n,sum);return0;}易错点累加器sum必须赋初值 0否则其初值是不确定的内存残留值。案例 2判断素数输入一个正整数判断它是否为素数。#includestdio.h#includemath.hintmain(void){intn,i,k;intflag1;/* 标记变量假设是素数 */printf(请输入一个正整数);scanf(%d,n);k(int)sqrt((double)n);/* 只需判断到 √n */for(i2;ik;i){if(n%i0){/* 找到因子不是素数 */flag0;break;}}if(flagn1)printf(%d 是素数\n,n);elseprintf(%d 不是素数\n,n);return0;}优化思想只需判断到√n可把时间复杂度从O(n)降到O(√n)。案例 3求最大公约数与最小公倍数辗转相除法#includestdio.hintmain(void){intm,n,a,b,r,lcm;printf(请输入两个正整数);scanf(%d %d,m,n);am;bn;while(b!0){/* 辗转相除余数为 0 时结束 */ra%b;ab;br;}lcmm*n/a;/* 最小公倍数 两数乘积 / 最大公约数 */printf(最大公约数%d\n,a);printf(最小公倍数%d\n,lcm);return0;}案例 4求水仙花数输出所有三位水仙花数各位数字立方和等于该数本身。#includestdio.hintmain(void){intn,g,s,b;for(n100;n999;n){gn%10;/* 个位 */sn/10%10;/* 十位 */bn/100;/* 百位 */if(g*g*gs*s*sb*b*bn)printf(%d\n,n);}return0;}/* 输出153 370 371 407 */要点用整除/与取余%分离出各位数字是循环与数值分解结合的典型题型。四、课后习题精选解析习题 1输出以下图案菱形* *** ***** ******* ***** *** *思路把菱形拆成“上三角 下三角”两部分。空格数逐行递减、星号数以奇数列形式递增。设上半部分共 4 行含中间行则第 i 行空格数为4 - i星号数为2 * i - 1。#includestdio.hintmain(void){inti,j,n4;/* 上半部分含中间行 */for(i1;in;i){for(j1;jn-i;j)/* 打印空格 */printf( );for(j1;j2*i-1;j)/* 打印星号 */printf(*);printf(\n);}/* 下半部分 */for(in-1;i1;i--){for(j1;jn-i;j)printf( );for(j1;j2*i-1;j)printf(*);printf(\n);}return0;}习题 2输出九九乘法表#includestdio.hintmain(void){inti,j;for(i1;i9;i){/* 行 */for(j1;ji;j)/* 列j i 形成下三角 */printf(%d*%d%-2d ,j,i,i*j);printf(\n);}return0;}要点内层循环条件j i是关键它保证了每一行的列数逐行增加。习题 3求 1! 2! 3! … n! 之和#includestdio.hintmain(void){intn,i;longterm1,sum0;printf(请输入 n);scanf(%d,n);for(i1;in;i){term*i;/* 每次在上一个阶乘基础上乘 i避免重复计算 */sumterm;}printf(1!2!...%d! %ld\n,n,sum);return0;}优化思想term复用上一次的阶乘结果时间复杂度为O(n)。若每项都重新用内层循环求阶乘则退化为O(n²)。习题 4求 Sn a aa aaa …如 2 22 222 2222#includestdio.hintmain(void){inta,n,i,term0,sum0;printf(请输入 a 和 n);scanf(%d %d,a,n);for(i1;in;i){termterm*10a;/* 递推生成下一项 */sumterm;}printf(Sn %d\n,sum);return0;}递归思想第 i 项 第 i−1 项 × 10 a循环中不必重新生成整个项。习题 5猴子吃桃问题猴子第一天摘下若干个桃子当即吃了一半还不过瘾又多吃了一个以后每天早上都吃了前一天剩下的一半零一个。到第 10 天早上想再吃时只剩 1 个桃子。求第一天共摘了多少个桃子。#includestdio.hintmain(void){intday,peach1;/* 第 10 天早上剩 1 个 */for(day9;day1;day--){/* 从第 9 天倒推到第 1 天 */peach(peach1)*2;/* 逆推公式 */}printf(第一天共摘了 %d 个桃子\n,peach);return0;}/* 输出第一天共摘了 1534 个桃子 */逆推思想第 n 天剩 x 个则第 n−1 天剩(x 1) * 2个用倒序循环实现。五、常见错误与调试建议循环变量未初始化如int i, sum;后直接sum isum值是内存残留值。分号误用导致空循环for (i 1; i 10; i);末尾分号使循环体为空后面的语句只执行一次。循环条件写错导致死循环如for (i 1; i 10; i--)i永远减小条件恒成立。误写成if (i 10)是赋值而非判断条件永远为真。break/continue作用范围混淆二者只作用于当前所在的那一层循环。调试建议在循环内插入printf打印循环变量和关键中间值逐步观察循环演变过程出现死循环时优先检查循环变量是否朝终止方向变化。六、本章小结循环结构是 C 程序设计的核心内容。学习本章应牢牢掌握三种循环语句的语法格式、执行流程及适用场景循环嵌套的“外层控行、内层控列”设计方法break与continue的精确语义累加、累乘、数值分解、递推、逆推等经典循环算法。建议读者独立完成教材课后习题并养成“先画流程图、再写代码、最后验证边界条件”的编程习惯这样才能真正把循环结构融会贯通。
返回列表