第 8 讲 while:次数看运行情况的循环。
第 9 讲 for 和 break / continue:次数已知的循环,以及中途跳出。
猜数字游戏正好把它们全用上:反复让玩家猜(循环),
每次判断大了还是小了(条件),猜中就跳出(break)。
C++ 用 rand() 产生随机整数,它在 <cstdlib> 里。
但 rand() 其实是“伪随机”——不设置种子的话,每次运行都得到同一串数。
所以先用 srand(time(0)) 拿当前时间做种子(time() 在
<ctime> 里)。时间每秒都在变,每次运行的随机数就不一样了。
#include <iostream>
#include <cstdlib> // rand()、srand()
#include <ctime> // time()
int main() {
srand(time(0)); // 用当前时间做“种子”,每次运行都不一样
int answer = rand() % 100 + 1; // 1 ~ 100 之间的随机整数
std::cout << "(偷偷告诉你,答案是 " << answer << ")" << std::endl;
return 0;
} rand() % 100 取余,结果落在 0~99;再 + 1 就变成
1~100。想要 1~6 的骰子,就写 rand() % 6 + 1——
% 后面的数 = 范围大小,+ 后面的数 = 起点。
srand(time(0)) 写在 main 开头一次就够了。
如果放进循环里反复 srand,同一秒内种子相同,反而可能连续生成一样的数。
核心是一个循环,循环体里对这次的 guess 做三种判断:
偏大、偏小、正好。先用伪代码把骨架想清楚:
int answer = rand() % 100 + 1;
int guess;
while (??) { // 还没猜中、且次数没用完,就继续
std::cin >> guess;
if (guess > answer) {
std::cout << "大了" << std::endl;
} else if (guess < answer) {
std::cout << "小了" << std::endl;
} else {
// 猜中了,该怎么办?
}
} 两个待定的地方:循环什么时候停(猜中、或次数用完), 以及猜中那一支该做什么(记下“赢了”并跳出)。下面的完整代码给出一种答案。
for 顺手计数;
而“可能没到 7 次就猜中提前结束”,靠 break 解决。
两种工具各管一头,配合得正好。
#include <iostream>
#include <cstdlib>
#include <ctime>
int main() {
srand(time(0));
int answer = rand() % 100 + 1;
int maxTries = 7; // 最多猜 7 次
bool win = false; // 是否猜中的标记
std::cout << "我想好了一个 1~100 的数,你有 " << maxTries << " 次机会。" << std::endl;
for (int i = 1; i <= maxTries; i++) {
std::cout << "第 " << i << " 次猜,请输入:";
int guess;
std::cin >> guess;
if (guess > answer) {
std::cout << "大了" << std::endl;
} else if (guess < answer) {
std::cout << "小了" << std::endl;
} else {
std::cout << "恭喜!" << i << " 次就猜中了。" << std::endl;
win = true;
break; // 猜中了,提前结束循环
}
}
if (!win) {
std::cout << "次数用完了,答案是 " << answer << "。" << std::endl;
}
return 0;
} for (int i = 1; i <= maxTries; i++) 既计数(第几次猜),
又限定上限(最多 7 次),i 还能直接拿来报告“几次猜中”。
win 这个标记是关键:循环可能因两种原因结束——猜中 break,
或次数耗尽自然退出。循环外靠 if (!win) 区分这两种结局,决定要不要公布答案。
跑起来,照下面的剧本各玩一局,确认行为符合预期:
| 场景 | 期望表现 |
|---|---|
| 第一次就猜中 | 提示“1 次就猜中”,立刻结束 |
| 故意每次猜太大 | 每次都提示“大了” |
| 故意每次猜太小 | 每次都提示“小了” |
| 7 次都没猜中 | 公布答案,且答案确实是你没猜到的那个数 |
| 第 7 次刚好猜中 | 祝贺“7 次猜中”,不再公布答案 |
win 标记或 break 漏了——回头检查猜中那一支。
光提示“大了 / 小了”还能更贴心:维护一个当前可能区间 [low, high],
每次根据猜测结果收窄它,并提示玩家“答案在 low 到 high 之间”。
提示:初始 low = 1、high = 100;
猜大了就把 high 改成 guess - 1,猜小了就把 low 改成 guess + 1。
一局结束后问玩家是否再来(输入 y 继续、其它退出),用外层循环把整个游戏包起来,
每局重新生成答案。
for 还是 while?
回到第 9 讲那条挑选标准。
如果玩家输入了 0 或 200 这种不在 1~100 的数,提示“请猜 1~100 之间的数”,
并且这次不算进 7 次机会里。
提示:把第 8 讲的输入校验思路搬过来——非法输入时用 continue 跳过本轮,
但别让它消耗掉一次计数。想想计数该怎么改才不会被 continue 误伤。
| 讲次 | 核心内容 |
|---|---|
| 第 8 讲 | while、循环变量三动作、死循环 |
| 第 9 讲 | for、累加器、break / continue |
| 第 10 讲 | 随机数 + 循环 + 条件,做出完整小游戏 |
到这里,你的程序已经能判断、能重复,还能处理运行时才知道的输入—— 这正是大多数实用程序的骨架。
main 会越堆越乱。
下一模块学函数:把“生成答案”“判断一次猜测”这些步骤各自打包,
让代码像搭积木一样清清爽爽。