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

第02课 · 要写代码

算法与数据结构、5 个特性、流程图、N-S 图、伪代码、结构化设计

21 段代码每行都有注释边敲边想
教材依据第2章《算法——程序的灵魂》书页 p.15–36
本课覆盖:教材第2章正文 + 书末习题(p.35–36)。标「教材 p.X」= 教材段落总结;「例题」= 教材例题;「习题」= 书末题目;「本课补充」= 非教材原文。
在全书对照表中查看 →

本章是"纸上谈兵"章,C 代码只作对照用:让你看到"算法描述"和"C 程序"是一一对应的。
while、int、% 这些语法第 3~5 章才正式讲,今天不要求你会写,只要求你看得懂它在对应算法的哪一句。

一、知识点代码

c
// ============ 1. 教材例 2.18:求 5!(算法 → C 代码的标本)============
#include <stdio.h>          // 包含标准输入输出头文件,这样才能用 printf
int main()                  // 主函数,程序入口
{
    int i, t;               // 声明两个整型变量:i 当乘数,t 当"累乘的筐"
    t = 1;                  // 对应伪代码 "1 => t":筐里先放 1(乘法从 1 开始,加法才会从 0 开始)
    i = 2;                  // 对应 "2 => i":乘数从 2 开始
    while (i <= 5)          // 对应 "while i <= 5":只要 i 不大于 5 就一直循环
    {
        t = t * i;          // 对应 "t * i => t":把 i 乘进筐里,结果仍放回 t
        i = i + 1;          // 对应 "i + 1 => i":乘数加 1,准备下一轮
    }                       // 循环体结束,回到 while 再判断
    printf("%d\n", t);      // 对应 "print t":输出筐里的结果,%d 表示按整数输出
    return 0;               // 程序正常结束
}
c
// ============ 2. 同一个算法的另一种写法(复习第 3 章会讲的 += )============
#include <stdio.h>
int main()
{
    int i, t;
    t = 1;                  // 初值 1
    i = 2;                  // 从 2 开始乘
    while (i <= 5)
    {
        t *= i;             // 等价于 t = t * i; 读作"t 乘等 i"
        i++;                // 等价于 i = i + 1; 读作"i 自增 1"
    }
    printf("%d\n", t);      // 输出 120
    return 0;
}
c
// ============ 3. 求 1+2+3+…+100(累加三件套)============
#include <stdio.h>
int main()
{
    int i, sum;             // i 是加数,sum 是累加的筐
    sum = 0;                // 加法从 0 开始(和累乘从 1 开始不同)
    i = 1;                  // 从 1 开始加
    while (i <= 100)        // 加到 100 为止
    {
        sum = sum + i;      // 把 i 累加进筐里
        i = i + 1;          // 加数加 1
    }
    printf("%d\n", sum);    // 输出 5050
    return 0;
}
c
// ============ 4. 交换两个数(三只杯子法,对应习题 4(1))============
#include <stdio.h>
int main()
{
    int a, b, t;            // t 是"第三个空瓶",用来临时存放
    a = 10;                 // 假设 A 瓶里是醋
    b = 20;                 // 假设 B 瓶里是酱油
    t = a;                  // 第一步:把 A 倒进空瓶 t
    a = b;                  // 第二步:把 B 倒进 A
    b = t;                  // 第三步:把 t 倒进 B
    printf("a=%d b=%d\n", a, b);  // 输出 a=20 b=10
    return 0;
}
c
// ============ 5. 三个数按从大到小输出(对应习题 4(3))============
#include <stdio.h>
int main()
{
    int a, b, c, t;         // t 还是那个临时瓶
    a = 3; b = 1; c = 2;    // 故意给一组乱序的数
    if (a < b) { t = a; a = b; b = t; }   // 若 a<b,交换,让 a 变成较大的
    if (a < c) { t = a; a = c; c = t; }   // 再和 c 比,保证 a 是最大的
    if (b < c) { t = b; b = c; c = t; }   // 最后让 b、c 也有序
    printf("%d %d %d\n", a, b, c);        // 输出 3 2 1
    return 0;
}
c
// ============ 6. 判断一个数能否同时被 3 和 5 整除(对应习题 4(5))============
#include <stdio.h>
int main()
{
    int n;
    n = 77;                 // 题目里给定的数
    if (n % 3 == 0 && n % 5 == 0)   // % 是取余数;两个条件都为真才算"能"
        printf("能同时被 3 和 5 整除\n");
    else                            // 只要有一个不满足,就走到 else
        printf("不能同时被 3 和 5 整除\n");
    return 0;
}
c
// ============ 7. 求两个数的最大公约数(辗转相除,对应习题 4(7))============
#include <stdio.h>
int main()
{
    int m, n, r;
    m = 12;                 // 第一个数
    n = 8;                  // 第二个数
    r = m % n;              // 先求一次余数
    while (r != 0)          // 余数不为 0 就继续
    {
        m = n;              // 把除数变成新的被除数
        n = r;              // 把余数变成新的除数
        r = m % n;          // 再求新的余数
    }
    printf("%d\n", n);      // 余数为 0 时,n 就是最大公约数
    return 0;
}
c
// ============ 8. 判断闰年(对应习题 8(1))============
#include <stdio.h>
int main()
{
    int year;
    year = 2000;            // 要判断的年份
    if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
        printf("%d 是闰年\n", year);   // 两个条件满足其一即为闰年
    else
        printf("%d 不是闰年\n", year);
    return 0;
}

二、课后题 · 代码题

第 2 章的课后题都是"画图 / 写伪代码",真正的 C 代码题从第 3 章才开始。
这里把本章最典型的算法提前翻成 C,供你对照"算法 → 代码"的翻译过程。

c
// ===== 习题 4(2):输入 10 个数,输出其中最大的一个 =====
#include <stdio.h>
int main()
{
    int max, x, i;
    scanf("%d", &max);      // 先读第 1 个数,把它当作"当前最大值"
    for (i = 2; i <= 10; i++)   // 还有 9 个数要读
    {
        scanf("%d", &x);    // 读入第 i 个数
        if (x > max)        // 如果它比当前最大值还大
            max = x;        // 就让它当新的最大值
    }
    printf("最大值是 %d\n", max);
    return 0;
}
c
// ===== 习题 4(6):输出 100~200 之间的素数 =====
#include <stdio.h>
int main()
{
    int n, i, is_prime;
    for (n = 100; n <= 200; n++)    // 外层循环:n 从 100 走到 200
    {
        is_prime = 1;               // 先假设 n 是素数(1 表示"是")
        for (i = 2; i * i <= n; i++)    // 内层循环:用 2 到 √n 去试除
        {
            if (n % i == 0)         // 只要有一个除得尽
            {
                is_prime = 0;       // n 就不是素数
                break;              // 不用再试了,直接跳出内层循环
            }
        }
        if (is_prime == 1)          // 一轮试完都没除尽
            printf("%d ", n);       // 输出这个素数
    }
    printf("\n");
    return 0;
}

三、我出的题 · 随课练习

🔮 猜输出

c
// ===== 猜输出①:i 从 3 开始(原题是 2)=====
#include <stdio.h>
int main()
{
    int i, t;
    t = 1;
    i = 3;                  // ← 改了这一处
    while (i <= 5)
    {
        t = t * i;
        i = i + 1;
    }
    printf("%d\n", t);
    return 0;
}
c
// ===== 猜输出②:条件改成 i <= 6 =====
#include <stdio.h>
int main()
{
    int i, t;
    t = 1;
    i = 2;
    while (i <= 6)          // ← 改了这一处
    {
        t = t * i;
        i = i + 1;
    }
    printf("%d\n", t);
    return 0;
}
c
// ===== 猜输出③:条件改成 i < 5 =====
#include <stdio.h>
int main()
{
    int i, t;
    t = 1;
    i = 2;
    while (i < 5)           // ← 改了这一处
    {
        t = t * i;
        i = i + 1;
    }
    printf("%d\n", t);
    return 0;
}
c
// ===== 猜输出④:循环体两句顺序对调 =====
#include <stdio.h>
int main()
{
    int i, t;
    t = 1;
    i = 2;
    while (i <= 5)
    {
        i = i + 1;          // ← 先加
        t = t * i;          // ← 后乘
    }
    printf("%d\n", t);
    return 0;
}

🛠 变式题(自己写完整代码/步骤)

c
// ===== 变式题1:求 1×3×5×7×9(奇数的累乘)=====
// 要求:把 5! 的程序改一改,让它只乘奇数
#include <stdio.h>
int main()
{
    int i, t;
    // 在这里写你的代码


    printf("%d\n", t);      // 正确结果应该是 945
    return 0;
}
c
// ===== 变式题2:输入 10 个数,输出最小的一个 =====
// 要求:仿照"求最大值"的写法,把比较方向反过来
#include <stdio.h>
int main()
{
    // 在这里写你的代码


    return 0;
}
c
// ===== 变式题3:补全——求 1+2+…+100 =====
#include <stdio.h>
int main()
{
    int i, sum;
    sum = 0;
    i = 1;
    while (【 ① 】)          // ← 补全循环条件
    {
        【 ② 】               // ← 补全累加语句
        【 ③ 】               // ← 补全 i 的推进
    }
    printf("%d\n", sum);    // 应为 5050
    return 0;
}

🐛 改错题

c
// ===== 改错题1:这个程序能算出 120 吗?错在哪?=====
#include <stdio.h>
int main()
{
    int i, t;
    t = 1;
    i = 2;
    while (i <= 5)
    {
        t * i = t;          // ← 错:赋值号左边不能是表达式
        i = i + 1;
    }
    printf("%d\n", t);
    return 0;
}
c
// ===== 改错题2:这个循环体实际执行了几件事?=====
#include <stdio.h>
int main()
{
    int i, t;
    t = 1;
    i = 2;
    while (i <= 5)
        t = t * i;          // ← 注意:循环体没有花括号
        i = i + 1;          // ← 这一行到底在不在循环里?
    printf("%d\n", t);
    return 0;
}

提示:不写 {} 时,while 只管紧跟着的那一条语句。想想 i 会不会一直加、循环会不会停。

c
// ===== 改错题3:求 1+…+100,但结果算出来是 5051?=====
#include <stdio.h>
int main()
{
    int i, sum;
    sum = 1;                // ← 累加初值写错了
    i = 1;
    while (i <= 100)
    {
        sum = sum + i;
        i = i + 1;
    }
    printf("%d\n", sum);
    return 0;
}

四、加练题

c
// (暂无。你喊"再出几道 XX 题",我出的代码会追加在这里)