本文件是第 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 题",我出的题会标上日期追加在这里。)