c语言程序设计技术课程总结(一起学C程序设计第五课)(1)

C语言循环结构

注意,请认真学习完《C程序设计(第五版)》第五章后再阅读本文会有更大的收获。

通过之前的学习我们知道程序所处理的是数据,而日常的数据都存储在数据库里,一般它们有着相同的数据结构,在批量处理这些数据的时候通常就会使用循环控制语句。对于输入数据类型和结构一致、处理逻辑一致的程序一般都可以采用循环控制语句来实现,不仅简化了代码结构,还使得后续代码扩展和维护更方便。

while循环

书本上讲了while和do...while两种循环结构,通过了解其特性得知其主要差别在于do...while不管条件满足与否都会先执行一次循环体,所以,在日后的使用中不推荐使用do...while循环,因为常规的逻辑基本上都是只有满足条件才去执行,即使遇到可以使用do...while的情形,我们也用while去代替它以使整个项目的代码风格保持一致。

for循环

c语言程序设计技术课程总结(一起学C程序设计第五课)(2)

for循环

书本最开始举例求和就向我们展示了for循环,这次终于见识了庐山真面目。在使用过程中我们不要省略掉任何一个表达式,一味地追求简洁反而会“适得其反”。

嵌套

不仅仅是循环之间可以互相嵌套,我们上一课学习的if语句也可以参与进来和while、for等一起形成复杂的多重嵌套程序,一般在循环体内常用if语句去做判断处理。

c语言程序设计技术课程总结(一起学C程序设计第五课)(3)

嵌套循环

跳出循环

常规跳出

这里指的是代码执行循环体直到不能满足循环条件的时候,程序会自动跳出循环,比如我们求1~100的和,当数字自增到101的时候会自然跳出循环。

手动跳出

在循环体处理数据时有差别对待,或者循环体执行过程中产生了不符合预期的结果,这时候我们要手动跳出循环——coutinue或者break。

情形1,在处理数据1~100的循环体中,要求对偶数进行一些计算,而忽略奇数。那我们判断当前数是奇数的时候就可以用continue来跳出当前的循环而继续进行下一次循环。

情形2,在处理数据1~100的循环体中,要求找出5个可以被3整除的数字即可。那当我们找到第五个满足条件的数字之后就不用再执行下去了,此时用break来跳出整个循环。

死循环

如果一个循环控制程序里不设置终止条件,或者循环体有问题导致不能触发跳出循环的语句,这时候就是我们通常说的“死循环”。

我们在编程的过程中要避免死循环的出现,除非是写那些需要一直运行着的脚本程序。

实战编程

输入两个正整数m和n,求其最大公约数和最小公倍数。

这是一道数学题,先搞清楚两个及其以上正整数最大公约数和最小公倍数的定义,然后再来想清楚算法去解题。

最大公约数:从m和n中取出任意一个数字比如m,然后从1开始找m的约数x,如果x也是n的约数则x就是m和n的公约数;直到循环数自增到m,整个循环过程中找出符合条件的公约数会越来越大,那么最后一次赋值给x的公约数则为最大公约数(因为每次赋值会覆盖上一次的公约数的值)。这里无论m和n谁大谁小都不会影响程序的结果,如果提前判断大小关系,从小数来找公约数会减少循环次数,感兴趣的同学可以自己改进程序。

最小公倍数:先找到m和n中的最小数,然后从1开始相乘找最小数的倍数,一旦同时能被m和n整除,那么这个数就是m和n的最小公倍数。

void fun4() { int m, n; printf("输入两个正整数:\n"); scanf_s("%d%d", &m, &n); int x = 1; for (int i = 1; i <= m; i ) { if (m % i == 0 && n % i == 0) { x = i; } } printf("最大公约数是:%d\n", x); int min = m < n ? m : n; int i = 1; while (1) { int num = min * i; if (num % m == 0 && num % n == 0) { printf("最小公倍数是:%d\n", num); break; } i ; } }

PS:找最大公约数还有一种算法:先找到m和n之中的最小数,然后从大到小循环这个最小数去找公约数,找到的第一个公约数就是最大公约数,这个算法感兴趣的去尝试一下吧~

找最小公倍数也可以用另外一种算法:先找到m和n之中的最大数,然后让最大数自增加,注意不是相乘,这样去判断能否都被m和n整除,一旦符合条件即可得到最小公倍数。

求之值,其中a是一个数字,n表示a的位数,n由键盘输入。例如:2 22 222 2222 22222 (此时n=5)

这道题的思路分为二:一是循环构建n个数,二是每个数再循环生成,要用到嵌套循环。构建数字的算法是解题核心,参考下面代码:

void fun5() { int a = 3, n; printf("输入n:\n"); scanf_s("%d", &n); int sum = 0; for (int i = 1; i <= n; i ) { int num = 0; for (int j = 1; j <= i; j ) { num = a * pow(10, j - 1); } printf("%d\t", num); sum = num; } printf("\n"); printf("sum is %d\n", sum); }

本题和“水仙花数”有相似之处,可以用三层循环构造三位数去判断是否符合“水仙花数”。

PS:代码里用到pow()函数要在文件开头包含math.h头文件:#include <math.h>。

一个数如果恰好等于它的各个因子之和,这个数就称为“完数”。例如,6的因子为1,2,3,而6=1 2 3,因此6是“完数”。编程找出1000之内的所有完数,并按下面的格式输出其因子:

6 its factors are 1,2,3

这个题目还是要用循环嵌套来解,先循环1000以内数字,然后再循环分解每个数字的因子,参考如下:

void fun9() { for (int num = 1; num < 1000; num ) { int tmp_sum = 0; for (int i = 1; i < num; i ) { if (num % i == 0) { tmp_sum = i; } } if (num == tmp_sum) { printf("%d 是完数\n", num); } } }

PS:本示例代码并没有输出各个因子,在判断是完数之后再重复上面的那个循环去输出因子,同学们自己练习吧~

猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第二天早上又将第一天剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第 10 天早上想再吃时,发现只剩下一个桃子了。编写程序求猴子第一天摘了多少个桃子。

又是数学问题。本题的关键是算清楚一个公式,前一天的桃子数记为before,后一天的桃子数记为after,根据题目得到after = before / 2 - 1,进而推导出 before = (after 1) * 2,这样我们从最后一天开始往前推导就得出了第一天的桃子数量了,代码参考:

void fun12() { int before, after = 1, days = 10; for (int i = 1; i < days; i ) { before = 2 * (after 1); after = before; printf("第%d天的桃子数:%d\n", days - i, before); } printf("总共桃子个数:%d\n", before); }

总结

初学者对循环体可能有下面几个迷惑点:

  1. 初始、终止条件设置
  2. 自增变量控制
  3. 跳出循环的时机

很多人一开始会纠结从0开始还是从1开始,在99终止还是在100终止这两点,其实只要你写代码去运行看结果,多改几遍代码看看不同的条件对应什么结果,自然就能熟练掌握了。跳出循环的时机主要看算法的设计是怎样的,不同的题目有多重算法,解题的时候也要多去尝试,多锻炼自己的解题思路,为今后学习算法做好铺垫。

强调一点,由于初学者没有实际的项目经验,所以书本上的练习题几乎都是以数学题的形式出现,这个就考验我们的数学功底了,这点在之前的文章中有提过。

学完if语句和本节课的循环语句,就可以写出来很多程序了,大家有空多多练习吧,现阶段还是算法到编程转换的关键时期,趁机会多锻炼自己的编程思维~

往期文章

一起学《C程序设计》第四课——if语句、switch语句及实战练习

一起学《C程序设计》第三课——数据结构、运算符、表达式和语句

一起学《C程序设计》第二课——算法

一起学《C程序设计》第一课——C语言概述和学习前的准备、意识

C程序设计(谭浩强)——第五版和第三版对比

,