CC语言通关
第05课 · 要写代码
教材对照
第05课配套 · 纯代码

第05课 · 要写代码

while、do…while、for、循环嵌套、break/continue、经典算法

26 段代码每行都有注释边敲边想
教材依据第5章《循环结构程序设计》书页 p.110–138
本课覆盖:教材第5章正文 + 书末习题(p.137–138)。标「教材 p.X」= 教材段落总结;「例题」= 教材例题;「习题」= 书末题目;「本课补充」= 非教材原文。
在全书对照表中查看 →

本文件是第 05 课的代码手册:每行代码后面都跟 // 注释。先照着敲一遍,再合上书自己默写。


一、知识点代码

1. while 基本写法(1~100 求和)

c
// ============ while 基本写法 ============
#include <stdio.h>                      // 引入标准输入输出库
int main()                              // 主函数,程序入口
{                                       // 主函数开始
    int i = 1, sum = 0;                 // i 循环变量,初值 1;sum 累加器,初值 0
    while (i <= 100)                    // 当 i 不超过 100 时重复
    {                                   // 循环体开始
        sum = sum + i;                  // 把当前 i 累加到 sum
        i++;                            // i 加 1,让循环趋于结束
    }                                   // 循环体结束
    printf("sum=%d\n", sum);            // 输出结果
    return 0;                           // 程序正常结束
}                                       // 主函数结束

2. do…while 基本写法

c
// ============ do…while 基本写法 ============
#include <stdio.h>                      // 引入标准输入输出库
int main()                              // 主函数
{                                       // 主函数开始
    int i = 1, sum = 0;                 // i 初值 1,sum 初值 0
    do                                  // do 表示先做一次
    {                                   // 循环体开始
        sum = sum + i;                  // 累加当前 i
        i++;                            // i 加 1
    } while (i <= 100);                 // 做完再判断;分号不能少
    printf("sum=%d\n", sum);            // 输出结果
    return 0;                           // 正常结束
}                                       // 主函数结束

3. for 基本写法

c
// ============ for 基本写法 ============
#include <stdio.h>                      // 引入标准输入输出库
int main()                              // 主函数
{                                       // 主函数开始
    int i, sum = 0;                     // i 只声明,初值放到 for 里
    for (i = 1; i <= 100; i++)          // 初值;条件;每圈结束 i 加 1
        sum = sum + i;                  // 循环体只有一条语句
    printf("sum=%d\n", sum);            // 循环结束后输出
    return 0;                           // 正常结束
}                                       // 主函数结束

4. 循环的嵌套(4×5 矩阵)

c
// ============ 循环的嵌套 ============
#include <stdio.h>                      // 引入标准输入输出库
int main()                              // 主函数
{                                       // 主函数开始
    int i, j;                           // i 控制行,j 控制列
    for (i = 1; i <= 4; i++)            // 外循环:4 行
    {                                   // 外循环体开始
        for (j = 1; j <= 5; j++)        // 内循环:每行 5 列,j 每次从 1 开始
            printf("%4d", i * j);       // 输出 i 与 j 的乘积,占 4 列
        printf("\n");                   // 一行输出完换行
    }                                   // 外循环体结束
    return 0;                           // 正常结束
}                                       // 主函数结束

5. break 提前终止循环

c
// ============ break 提前终止 ============
#include <stdio.h>                      // 引入标准输入输出库
int main()                              // 主函数
{                                       // 主函数开始
    int i;                              // 循环变量
    for (i = 1; i <= 100; i++)          // 本来要数到 100
    {                                   // 循环体开始
        if (i % 7 == 0)                 // 找到第一个能被 7 整除的数
            break;                      // 立刻跳出整个循环
    }                                   // 循环体结束
    printf("第一个能被 7 整除的数是 %d\n", i);  // 输出 break 时的 i
    return 0;                           // 正常结束
}                                       // 主函数结束

6. continue 结束本次循环

c
// ============ continue 结束本次循环 ============
#include <stdio.h>                      // 引入标准输入输出库
int main()                              // 主函数
{                                       // 主函数开始
    int i;                              // 循环变量
    for (i = 1; i <= 10; i++)           // i 从 1 到 10
    {                                   // 循环体开始
        if (i % 3 == 0)                 // i 是 3 的倍数
            continue;                   // 跳过本轮剩下语句,直接执行 i++
        printf("%d ", i);               // 只有非 3 的倍数才输出
    }                                   // 循环体结束
    printf("\n");                       // 输出完换行
    return 0;                           // 正常结束
}                                       // 主函数结束

二、课后题 · 代码题

第 3 题:最大公约数和最小公倍数

c
// ============ 第 3 题:gcd 与 lcm ============
#include <stdio.h>                      // 引入标准输入输出库
int main()                              // 主函数
{                                       // 主函数开始
    int m, n, a, b, t, gcd, lcm;        // m、n 输入,a、b 副本,t 余数
    printf("请输入两个正整数 m n: ");   // 提示输入
    scanf("%d %d", &m, &n);             // 读入两个正整数
    a = m;                              // 备份 m,后面还要算 lcm
    b = n;                              // 备份 n
    while (b != 0)                      // 辗转相除:b 不为 0 就继续
    {                                   // 循环体开始
        t = a % b;                      // 求余数
        a = b;                          // 除数变被除数
        b = t;                          // 余数变除数
    }                                   // 循环结束,此时 a 是最大公约数
    gcd = a;                            // 保存最大公约数
    lcm = m / gcd * n;                  // 先除后乘,防止溢出
    printf("最大公约数=%d 最小公倍数=%d\n", gcd, lcm);  // 输出两个结果
    return 0;                           // 正常结束
}                                       // 主函数结束

第 6 题:1! + 2! + … + 20!

c
// ============ 第 6 题:阶乘和 ============
#include <stdio.h>                      // 引入标准输入输出库
int main()                              // 主函数
{                                       // 主函数开始
    int i;                              // 循环变量
    double term = 1, sum = 0;           // term 当前阶乘,sum 累加和
    for (i = 1; i <= 20; i++)           // 从 1 乘到 20
    {                                   // 循环体开始
        term = term * i;                // 利用上一项算下一项
        sum = sum + term;               // 累加当前阶乘
    }                                   // 循环体结束
    printf("1!+2!+...+20!=%.0f\n", sum); // 输出整数形式的结果
    return 0;                           // 正常结束
}                                       // 主函数结束

第 8 题:水仙花数

c
// ============ 第 8 题:水仙花数 ============
#include <stdio.h>                      // 引入标准输入输出库
int main()                              // 主函数
{                                       // 主函数开始
    int n, a, b, c;                     // n 三位数,a/b/c 百/十/个位
    for (n = 100; n <= 999; n++)        // 遍历所有三位数
    {                                   // 循环体开始
        a = n / 100;                    // 百位
        b = n / 10 % 10;                // 十位
        c = n % 10;                     // 个位
        if (a*a*a + b*b*b + c*c*c == n) // 各位立方和等于本身
            printf("%d ", n);           // 输出这个水仙花数
    }                                   // 循环体结束
    printf("\n");                       // 输出完换行
    return 0;                           // 正常结束
}                                       // 主函数结束

第 9 题:完数

c
// ============ 第 9 题:完数 ============
#include <stdio.h>                      // 引入标准输入输出库
int main()                              // 主函数
{                                       // 主函数开始
    int i, j, s;                        // i 待判定数,j 因子,s 因子和
    for (i = 2; i < 1000; i++)          // 找 1000 以内的完数
    {                                   // 外层循环体开始
        s = 0;                          // 每个 i 开始前,因子和清零
        for (j = 1; j < i; j++)         // 枚举所有可能的真因子
            if (i % j == 0)             // j 能整除 i
                s = s + j;              // 把 j 累加到因子和
        if (s == i)                     // 因子和等于本身
        {                               // 是完数,开始输出
            printf("%d its factors are 1", i);   // 先输出第一个因子 1
            for (j = 2; j < i; j++)     // 再输出其余因子
                if (i % j == 0)         // j 是因子
                    printf(",%d", j);   // 用逗号接在后面输出
            printf("\n");               // 一个完数输出完换行
        }                               // 输出结束
    }                                   // 外层循环结束
    return 0;                           // 正常结束
}                                       // 主函数结束

第 10 题:分数序列前 20 项和

c
// ============ 第 10 题:分数序列 ============
#include <stdio.h>                      // 引入标准输入输出库
int main()                              // 主函数
{                                       // 主函数开始
    int i;                              // 循环变量
    double a = 2, b = 1, t, sum = 0;    // a 分子,b 分母,t 临时变量
    for (i = 1; i <= 20; i++)           // 求前 20 项
    {                                   // 循环体开始
        sum = sum + a / b;              // 累加当前分数
        t = a;                          // 先保存旧分子
        a = a + b;                      // 新分子 = 旧分子 + 旧分母
        b = t;                          // 新分母 = 旧分子
    }                                   // 循环体结束
    printf("sum=%.6f\n", sum);          // 输出前 20 项之和
    return 0;                           // 正常结束
}                                       // 主函数结束

第 11 题:球落地

c
// ============ 第 11 题:球落地 ============
#include <stdio.h>                      // 引入标准输入输出库
int main()                              // 主函数
{                                       // 主函数开始
    double h = 100, s = 100;            // h 当前反弹高度,s 总路程
    int i;                              // 循环变量,代表第几次落地
    for (i = 2; i <= 10; i++)           // 从第 2 次落地算到第 10 次
    {                                   // 循环体开始
        h = h / 2;                      // 每次反弹高度减半
        s = s + 2 * h;                  // 一次反弹加一次下落,共 2h
    }                                   // 循环体结束
    printf("第10次落地共经过 %.6f 米\n", s);      // 输出总路程
    printf("第10次反弹高度 %.8f 米\n", h / 2);    // 第 10 次反弹还要再减半
    return 0;                           // 正常结束
}                                       // 主函数结束

第 12 题:猴子吃桃

c
// ============ 第 12 题:猴子吃桃 ============
#include <stdio.h>                      // 引入标准输入输出库
int main()                              // 主函数
{                                       // 主函数开始
    int day, x = 1;                     // x 当天桃子数,第 10 天剩 1 个
    for (day = 9; day >= 1; day--)      // 从第 9 天倒推到第 1 天
        x = (x + 1) * 2;                // 倒推公式:前一天 = (今天+1)*2
    printf("第1天共摘了 %d 个桃子\n", x);  // 输出第 1 天的桃子数
    return 0;                           // 正常结束
}                                       // 主函数结束

第 16 题:输出菱形

c
// ============ 第 16 题:菱形 ============
#include <stdio.h>                      // 引入标准输入输出库
int main()                              // 主函数
{                                       // 主函数开始
    int i, j;                           // i 控制行,j 控制空格/星号
    for (i = 1; i <= 4; i++)            // 上半部分 4 行
    {                                   // 上半循环体开始
        for (j = 1; j <= 4 - i; j++)    // 先打 4-i 个空格
            printf(" ");                // 输出一个空格
        for (j = 1; j <= 2 * i - 1; j++)// 再打 2i-1 个星号
            printf("*");                // 输出一个星号
        printf("\n");                   // 一行结束换行
    }                                   // 上半循环体结束
    for (i = 3; i >= 1; i--)            // 下半部分 3 行,倒着来
    {                                   // 下半循环体开始
        for (j = 1; j <= 4 - i; j++)    // 空格数同样是 4-i
            printf(" ");                // 输出一个空格
        for (j = 1; j <= 2 * i - 1; j++)// 星号数同样是 2i-1
            printf("*");                // 输出一个星号
        printf("\n");                   // 一行结束换行
    }                                   // 下半循环体结束
    return 0;                           // 正常结束
}                                       // 主函数结束

第 17 题:乒乓球比赛名单

c
// ============ 第 17 题:乒乓球名单 ============
#include <stdio.h>                      // 引入标准输入输出库
int main()                              // 主函数
{                                       // 主函数开始
    char a, b, c;                       // a/b/c 分别是 A/B/C 的对手
    for (a = 'X'; a <= 'Z'; a++)        // 枚举 A 的对手
        for (b = 'X'; b <= 'Z'; b++)    // 枚举 B 的对手
            if (a != b)                 // A、B 的对手不能相同
                for (c = 'X'; c <= 'Z'; c++)          // 枚举 C 的对手
                    if (c != a && c != b && a != 'X' && c != 'X' && c != 'Z')  // 全部约束
                        printf("A-%c B-%c C-%c\n", a, b, c);                    // 输出一组解
    return 0;                           // 正常结束
}                                       // 主函数结束

三、我出的题 · 随课练习

🔮 猜输出

猜输出 1

c
// ============ 猜输出 1 ============
#include <stdio.h>                      // 引入标准输入输出库
int main()                              // 主函数
{                                       // 主函数开始
    int i;                              // 循环变量
    for (i = 1; i <= 5; i++)            // i 从 1 走到 5
    {                                   // 循环体开始
        if (i == 3)                     // 当 i 等于 3
            continue;                   // 结束本次循环
        printf("%d ", i);               // 输出 i
    }                                   // 循环体结束
    return 0;                           // 正常结束
}                                       // 主函数结束

猜输出 2

c
// ============ 猜输出 2 ============
#include <stdio.h>                      // 引入标准输入输出库
int main()                              // 主函数
{                                       // 主函数开始
    int i = 5, sum = 0;                 // i 初值 5,sum 初值 0
    do                                  // 先执行一次
    {                                   // 循环体开始
        sum = sum + i;                  // 累加 i
        i++;                            // i 加 1
    } while (i < 5);                    // 再判断条件
    printf("%d %d\n", sum, i);          // 输出 sum 和 i
    return 0;                           // 正常结束
}                                       // 主函数结束

猜输出 3

c
// ============ 猜输出 3 ============
#include <stdio.h>                      // 引入标准输入输出库
int main()                              // 主函数
{                                       // 主函数开始
    int i, j;                           // i 外层,j 内层
    for (i = 1; i <= 3; i++)            // 外层 3 次
    {                                   // 外层体开始
        for (j = 1; j <= 3; j++)        // 内层 3 次
        {                               // 内层体开始
            if (j == 2)                 // j 到 2 时
                break;                  // 跳出内层
            printf("%d%d ", i, j);      // 输出 i 和 j 拼在一起
        }                               // 内层体结束
    }                                   // 外层体结束
    return 0;                           // 正常结束
}                                       // 主函数结束

猜输出 4

c
// ============ 猜输出 4 ============
#include <stdio.h>                      // 引入标准输入输出库
int main()                              // 主函数
{                                       // 主函数开始
    int i = 0, s = 0;                   // i 初值 0,s 初值 0
    while (i < 5)                       // i 小于 5 就继续
    {                                   // 循环体开始
        i++;                            // 先把 i 加 1
        if (i == 3)                     // i 等于 3 时
            continue;                   // 跳过本轮剩下的语句
        s = s + i;                      // 把 i 累加到 s
    }                                   // 循环体结束
    printf("%d\n", s);                  // 输出 s
    return 0;                           // 正常结束
}                                       // 主函数结束

🛠 变式题

变式 1(照猫画虎):把 while 循环改写成 for 循环,补全横线。

c
// 变式 1:while 改 for
int i = 1, sum = 0;                     // i 循环变量,sum 累加器
while (i <= 100)                        // 原写法:当 i 不超过 100
{
    sum = sum + i;                      // 累加
    i++;                                // i 加 1
}
for (____; ____; ____)                  // 请补全三个表达式
    sum = sum + i;                      // 循环体

变式 2(改需求):求 1~100 中所有偶数的和,补全判断条件。

c
// 变式 2:偶数和
int i = 1, sum = 0;                     // 初值
for (i = 1; i <= 100; i++)              // 遍历 1~100
    if (____)                           // 补全:怎样判断 i 是偶数
        sum = sum + i;                  // 是偶数才累加

变式 3(改需求):密码最多试 3 次,补全 do…while 的条件。

c
// 变式 3:密码最多试 3 次
int tries = 0, ok = 0, pw;              // tries 已试次数,ok 是否正确
do
{
    scanf("%d", &pw);                   // 读入一次密码
    tries++;                            // 试错次数加 1
    if (pw == 123456)                   // 密码正确
        ok = 1;                         // 标记成功
} while (____);                         // 补全:没成功且次数不到 3 次就继续

变式 4(补全):输出九九乘法表下三角。

c
// 变式 4:九九乘法表
int i, j;                               // i 控制行,j 控制列
for (i = 1; i <= 9; i++)                // 共 9 行
{
    for (j = 1; ____; j++)              // 补全:内层上界与 i 有关
        printf("%d*%d=%-3d", j, i, ____);   // 补全:输出 j*i,左对齐占 3 列
    ____;                               // 补全:每行结束要做什么
}

🐛 改错题

改错 1:这个程序想求 1~100 的和,找出错误并改正。

c
// ❌ 错误示例(故意)
#include <stdio.h>
int main()
{
    int i = 1, sum = 0;
    while (i <= 100)
    {
        sum = sum + i;      // 只累加,没有让 i 变化
        // 错误:缺少 i++;  i 永远是 1,条件永远为真 → 死循环
        // 改正:在这一行后面补上 i++;
    }
    printf("sum=%d\n", sum);
    return 0;
}

改错 2:这个 for 语句有语法错误,找出并改正。

c
// ❌ 错误示例(故意)
for (i = 1, i <= 100, i++)   // 错误:三个表达式之间必须用分号,不能用逗号
    sum = sum + i;           // 改正:for (i = 1; i <= 100; i++)

改错 3:这个程序想输出 1~5 中除 3 以外的数,找出错误并说明原因。

c
// ❌ 错误示例(故意)
#include <stdio.h>
int main()
{
    int i = 1;
    while (i <= 5)
    {
        if (i == 3)
            continue;       // 错误:continue 跳过了后面的 i++,i 永远停在 3
        printf("%d ", i);
        i++;                // i==3 时这一行永远执行不到 → 死循环
    }
    return 0;
}
// 改正一:把 i++ 移到 if (i == 3) 之前
// 改正二:改用 for (i = 1; i <= 5; i++),i++ 写在表达式 3 里

四、加练题

(暂无。想加练就说"再出几道 XX 题",我出的题会标上日期追加在这里。)