本章是"纸上谈兵"章,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 题",我出的代码会追加在这里)