Appearance
第9章 数学函数
🎯 本章学习目标
学完本章,你将能够:
- ✅ 掌握 abs/fabs 绝对值函数的用法
- ✅ 掌握 sqrt 平方根函数及返回值类型
- ✅ 学会使用 max/min 函数比较大小
- ✅ 了解 pow/ceil/floor 等扩展数学函数
- ✅ 理解 rand() 与 srand() 的关系
- ✅ 掌握生成指定范围随机整数的万能公式
- ✅ 记住 srand(time(0)) 的作用和使用位置
- ✅ 能用随机数模拟掷骰子、猜数字等问题
- ✅ 掌握用 sqrt 优化质数判断的方法
- ✅ 学会计算两点间距离(勾股定理+sqrt)
- ✅ 理解伪随机数的概念
🗺️ 本章知识图谱
数学函数
├── 绝对值
│ ├── abs(x):整数绝对值(<cstdlib>)
│ └── fabs(x):浮点绝对值(<cmath>)
├── 平方根
│ ├── sqrt(x):算术平方根
│ ├── 返回值是 double
│ └── 负数开方得 nan
├── 最值
│ ├── max(a,b) / min(a,b)
│ ├── max({a,b,c}) 初始化列表(C++11)
│ └── 头文件 <algorithm>
├── 扩展函数(了解)
│ ├── pow(a,b):幂运算 a^b
│ ├── ceil(x):向上取整(朝正方向)
│ └── floor(x):向下取整(朝负方向)
├── 随机数 ⭐⭐⭐⭐⭐
│ ├── rand():返回 0~RAND_MAX 的整数
│ ├── RAND_MAX:至少32767
│ ├── srand(seed):设置随机种子
│ ├── srand(time(0)):用时间播种(每次不同)
│ ├── 伪随机:种子相同,序列相同
│ └── 万能公式:rand()%(b-a+1) + a → [a, b]
└── 经典应用
├── 三数求最大最小
├── 质数判断优化(试除到sqrt(n))
├── 掷骰子模拟(rand%6+1)
├── 猜数字游戏
└── 两点间距离(sqrt+平方)📖 引言
前面各章里,我们学会了让计算机"存数据"(存储与网络)、"说话"(程序设计语言)、"看图思考"(流程图)、"认字符"(ASCII 编码)、"变身"(数据类型转换),还掌握了"做判断"(多层分支)和"绕圈子"(多层循环)。本章要给二级知识体系补上最后一块拼图——数学函数。
别被"函数"两个字吓到,本章的函数都是"拿来即用"的工具:求绝对值、开平方、比大小、抛骰子……几行代码就能让程序拥有数学超能力。其中随机数是本章绝对的重头戏,掷骰子、猜数字、抽奖模拟,编程题里反复出现。
一、绝对值函数:abs 与 fabs
绝对值就是"去掉负号":|-5| = 5,|-3.14| = 3.14。两种语言的用法如下:
| 功能 | C++ 写法 | 需要的头文件 |
|---|---|---|
| 整数取绝对值 | abs(x) | <cstdlib> |
| 浮点数取绝对值 | fabs(x) | <cmath> |
🔥 高频考点:
abs主要用于整数,fabs专门用于浮点数 这是二级选择题的常客。记忆口诀:"整数 abs,浮点 fabs"——fabs 里的f就是 float(浮点)的意思。不过C++对abs做了重载,浮点数传入abs也能编译通过;考试中整数用abs、浮点用fabs是最规范的写法。
C++ 示例:
cpp
#include <iostream>
#include <cstdlib> // abs(int)
#include <cmath> // fabs(double)
using namespace std;
int main() {
int a = -5;
double b = -3.14;
cout << abs(a) << endl; // 5:整数取绝对值用 abs
cout << fabs(b) << endl; // 3.14:浮点数取绝对值用 fabs
cout << abs(-10) << endl; // 10:正数的绝对值是它本身
cout << fabs(2.5) << endl; // 2.5
return 0;
}⚠️ 易错点:C++ 中
abs()和fabs()的返回值类型不同——abs(-5)返回int,fabs(-3.14)返回double。做整数除法/取模运算时混用浮点数结果,可能引发类型隐患,考试中要看清题目变量的类型。
二、平方根函数:sqrt
平方根函数用于求算术平方根,如 √16 = 4。
| 功能 | 写法 | 头文件 | 返回值 |
|---|---|---|---|
| 平方根 | sqrt(x) | <cmath> | double(如 sqrt(16) 得到 4.0) |
| C++ 示例: |
cpp
#include <iostream>
#include <cmath>
using namespace std;
int main() {
cout << sqrt(16) << endl; // 4(返回值其实是 double 类型的 4.0)
cout << sqrt(2) << endl; // 1.41421
cout << sqrt(25) << endl; // 5
cout << sqrt(-1) << endl; // nan:对负数开平方,结果为 nan(Not a Number)
return 0;
}🔥 高频考点:
sqrt()的返回值是浮点数! 即使sqrt(16)数学上等于 4,程序里得到的也是4.0(double/float),不是整数 4。
⚠️ **易错点:负数开平方
- C++:
sqrt(-1)不报错,返回nan(Not a Number,非数)
三、最大值与最小值:max / min
比较大小是编程中最常见的需求之一。
| 函数 | 两个数比较 | 多个数比较 | 头文件 |
|---|---|---|---|
max / min | max(a, b) / min(a, b) | max({a, b, c})(C++11 初始化列表) | <algorithm> |
C++ 示例:
cpp
#include <iostream>
#include <algorithm> // max、min 都在这个头文件里
using namespace std;
int main() {
cout << max(3, 7) << endl; // 7
cout << min(3, 7) << endl; // 3
// C++11 起支持初始化列表,一次比较任意多个数
cout << max({3, 7, 5, 9}) << endl; // 9
cout << min({3, 7, 5, 9}) << endl; // 3
// 老式写法(嵌套调用,效果相同)
cout << max(3, max(7, 5)) << endl; // 7
return 0;
}⚠️ 易错点:① C++ 用
max/min必须#include <algorithm>,忘了头文件会编译报错;② C++ 初始化列表的花括号{ }不能写成圆括号;
四、幂运算与取整:pow、ceil、floor(了解)
这三个函数考纲要求"了解",在编程题中偶尔登场,顺手记住不吃亏:
| 功能 | C++(<cmath>) | 示例 |
|---|---|---|
| 幂运算 aᵇ | pow(a, b) | pow(2,10) = 1024 |
| 向上取整 | ceil(x) | ceil(3.2) = 4 |
| 向下取整 | floor(x) | floor(3.8) = 3 |
C++ 示例:
cpp
#include <iostream>
#include <cmath>
using namespace std;
int main() {
cout << pow(2, 10) << endl; // 1024:幂运算,返回 double
cout << ceil(3.2) << endl; // 4:向上取整(朝 +∞ 方向)
cout << floor(3.8) << endl; // 3:向下取整(朝 -∞ 方向)
cout << ceil(-3.2) << endl; // -3:负数"向上"是朝正方向,-3 比 -3.2 大
cout << floor(-3.2) << endl; // -4:负数"向下"是朝负方向,-4 比 -3.2 小
return 0;
}⚠️ 易错点:负数取整最容易错!
ceil(-3.2)是 -3 不是 -4,floor(-3.2)是 -4 不是 -3。记住"ceil 朝数轴正方向(大)取,floor 朝数轴负方向(小)取",画个数轴一看便知。
五、随机数函数(重点🔥)
随机数是本章的头号重点:掷骰子、猜数字、抽奖、模拟实验……编程题超爱考。但计算机其实生成不了"真正的随机数",它产生的是伪随机数——由一个"种子(seed)"按固定公式推算出来的序列。种子相同,序列就相同。
rand() 与 srand()
| 要素 | 说明 |
|---|---|
rand() | 返回一个 0 ~ RAND_MAX 之间的伪随机整数 |
RAND_MAX | rand() 能返回的最大值,**C++标准规定至少为 32767;**在GESP常用的Dev-C++环境中,RAND_MAX 的值就是32767 。但在某些Linux或64位环境下,RAND_MAX 可能更大(如2147483647)。 |
srand(seed) | 播种:设置随机序列的起点。种子相同,后续 rand() 序列完全相同 |
srand(time(0)) | 用系统当前时间当种子(<ctime> 头文件),每次运行种子不同,结果才不同 |
| 头文件 | rand/srand 在 <cstdlib>,time(0) 在 <ctime> |
生成指定范围随机整数的万能公式:
| 想要的范围 | 表达式 |
|---|---|
[0, b] | rand() % (b + 1) |
[a, b](通用) | rand() % (b - a + 1) + a |
骰子点数 [1, 6] | rand() % 6 + 1 |
两位数 [10, 99] | rand() % 90 + 10 |
[1, 100] | rand() % 100 + 1 |
C++ 示例:
cpp
#include <iostream>
#include <cstdlib> // rand()、srand()、RAND_MAX
#include <ctime> // time(0)
using namespace std;
int main() {
// 1. RAND_MAX:rand() 能返回的最大值,多数环境下是 32767
cout << RAND_MAX << endl; // 32767
// 2. 不播种直接调用 rand():每次运行程序,输出的三个数都完全一样!
cout << rand() << " " << rand() << " " << rand() << endl;
// 3. 用系统时间播种:每次运行得到不同的随机序列
srand(time(0));
// 4. 用万能公式生成指定范围的随机整数
cout << rand() % 6 + 1 << endl; // 骰子点数:1~6
cout << rand() % 100 + 1 << endl; // 1~100
cout << rand() % 90 + 10 << endl; // 两位数:10~99
cout << rand() % 11 << endl; // 0~10
return 0;
}
// 说明:第 2 行不播种的输出每次运行都相同(具体数值因编译器而异);
// 播种 srand(time(0)) 之后,每次运行结果都不同。🔥 高频考点(必考):
- 不播种,每次运行结果都相同! 题目问"为什么程序每次运行输出的随机数都一样",答案就是缺少
srand(time(0))。- 范围公式
rand() % (b - a + 1) + a中,取模的数是"个数"(b-a+1),加的数是"起点" a,几乎每次考试都考。srand(time(0))整个程序只调用一次,放在main()开头即可,千万不要放在循环里(time(0) 精确到秒,循环一圈远不到 1 秒,会播下相同的种子)。
六、数学函数一览表 ⭐
考前必看的一张总表:
| 功能 | C++ |
|---|---|
| 整数绝对值 | abs(x)(<cstdlib>) |
| 浮点绝对值 | fabs(x)(<cmath>) |
| 平方根 | sqrt(x)(<cmath>) |
| 幂运算 | pow(a, b)(<cmath>) |
| 向上取整 | ceil(x) |
| 向下取整 | floor(x) |
| 最大值 | max(a, b) / max({a,b,c})(<algorithm>) |
| 最小值 | min(a, b) / min({a,b,c})(<algorithm>) |
| 随机整数 | rand()(<cstdlib>) |
| 播种 | srand(time(0))(<ctime>) |
生成 [a,b] 随机整数 | rand() % (b-a+1) + a |
[0,1) 随机浮点数 | (double)rand() / RAND_MAX |
| 对负数开平方 | 返回 nan |
七、经典例题精讲
例题 1:三数求最大最小
题目: 输入三个整数,输出其中的最大值和最小值。
思路: 直接调用 max/min 函数。C++ 用初始化列表 max({a,b,c})。
cpp
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int a, b, c;
cin >> a >> b >> c;
cout << max({a, b, c}) << endl; // C++11 初始化列表,一次比三个
cout << min({a, b, c}) << endl;
return 0;
}
// 输入:3 9 5
// 输出:
// 9
// 3例题 2:用 sqrt 判断质数
题目: 输入一个正整数 n,判断它是不是质数(质数:大于 1,且只能被 1 和自身整除的数),是输出 Yes,否则输出 No。
思路(关键优化): 如果 n 能被某个数整除,那么因数一定成对出现(如 18 = 2×9 = 3×6),所以只需检查 2 ~ √n 之间有没有因数就够了。这就是 sqrt 在算法题里最经典的用途。
cpp
#include <iostream>
#include <cmath>
using namespace std;
int main() {
int n;
cin >> n;
bool prime = true;
if (n < 2) prime = false; // 0 和 1 不是质数
for (int i = 2; i <= sqrt(n); i++) { // 只需试除到 sqrt(n)
if (n % i == 0) {
prime = false;
break; // 找到一个因数,立刻判定不是质数
}
}
cout << (prime ? "Yes" : "No") << endl;
return 0;
}
// 输入:17 输出:Yes(17 是质数)
// 输入:18 输出:No(18 = 2 × 9)
// 输入:1 输出:No🔥 高频考点:质数判断题的两个得分点:① 小于 2 的数不是质数;② 循环只需到
sqrt(n)(写成i <= sqrt(n)或i * i <= n均可),既考了数学函数,又考了循环优化。
例题 3:掷骰子模拟
题目: 模拟掷骰子 n 次,统计 1~6 每个点数各出现了多少次。
思路: 用数组做计数器,下标 1~6 对应六个点数。
📚 拓展 · 三级内容提示: 本例用数组
int cnt[7]做计数器,数组属于 GESP 三级内容。二级若尚未学数组,用 6 个独立计数器变量(c1、c2…c6)配switch或if也能实现同样功能,思路完全一致,看懂计数思想即可。
cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main() {
srand(time(0)); // 播种!放在循环外面,整个程序只播一次
int n;
cin >> n;
int cnt[7] = {0}; // cnt[1]~cnt[6] 分别统计六个点数,cnt[0] 闲置
for (int i = 0; i < n; i++) {
int point = rand() % 6 + 1; // 生成 1~6 的骰子点数
cnt[point]++; // 对应点数计数 +1
}
for (int p = 1; p <= 6; p++) {
cout << p << "点:" << cnt[p] << "次" << endl;
}
return 0;
}
// 输入:6000
// 输出(每次运行结果不同,每个点数大约 1000 次):
// 1点:987次
// 2点:1012次
// 3点:995次
// 4点:1003次
// 5点:998次
// 6点:1005次例题 4:猜数字游戏
题目: 程序随机生成一个 1~100 的整数,玩家反复输入猜测,程序提示"太大了"或"太小了",猜对时输出猜测次数。
思路: 随机数 + 循环 + 分支的综合应用,是二级编程题的经典原型。
cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main() {
srand(time(0));
int target = rand() % 100 + 1; // 随机答案:1~100
int guess, count = 0;
do {
cin >> guess;
count++;
if (guess > target)
cout << "太大了" << endl;
else if (guess < target)
cout << "太小了" << endl;
else
cout << "恭喜你,猜对了!共猜了 " << count << " 次" << endl;
} while (guess != target); // 没猜对就继续循环
return 0;
}
// 运行示例(假设本次随机答案为 42,每次运行答案不同):
// 50
// 太大了
// 25
// 太小了
// 42
// 恭喜你,猜对了!共猜了 3 次⚠️ 易错点:随机答案的生成一定要在循环外面(生成一次就固定),写进循环里会变成"每猜一次答案就变",游戏永远猜不对!
例题 5:两点间距离
题目: 输入平面上两个点的坐标 (x1, y1) 和 (x2, y2),输出两点之间的距离,保留两位小数。
知识点: 距离公式 d = √[(x2−x1)² + (y2−y1)²],综合练习 sqrt 与输出格式控制。
cpp
#include <iostream>
#include <cmath>
#include <iomanip> // setprecision
using namespace std;
int main() {
double x1, y1, x2, y2;
cin >> x1 >> y1 >> x2 >> y2;
double dx = x2 - x1, dy = y2 - y1;
double dist = sqrt(dx * dx + dy * dy); // 勾股定理开平方
cout << fixed << setprecision(2) << dist << endl; // 保留两位小数
return 0;
}
// 输入:0 0 3 4
// 输出:5.00八、📝 实战练习
练习题 1(单选题)
题目: 在 C++ 中,要生成一个 [20, 50] 闭区间内的随机整数,正确的表达式是( )
A. rand() % 30 + 20 B. rand() % 31 + 20 C. rand() % 31 + 19 D. rand() % 50
🔑 点击查看答案与解析
答案: B
解析: 万能公式 rand() % (b - a + 1) + a。区间 [20, 50] 共有 50 − 20 + 1 = 31 个整数,起点是 20,所以是 rand() % 31 + 20。
- A:
% 30只产生 0~29,加 20 得到 [20, 49],取不到 50 ❌ - C:加 19 得到 [19, 49],范围全错 ❌
- D:得到 [0, 49] ❌
练习题 2(程序阅读题)
题目: 阅读以下 C++ 程序,写出运行结果:
cpp
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
int main() {
cout << abs(-8) << endl;
cout << fabs(-2.5) << endl;
cout << sqrt(16) << endl;
cout << max({4, 9, 6}) << endl;
cout << (int)ceil(3.1) << " " << (int)floor(3.9) << endl;
return 0;
}🔑 点击查看答案与解析
答案:
8
2.5
4
9
4 3解析:
abs(-8)= 8(整数绝对值)fabs(-2.5)= 2.5(浮点绝对值)sqrt(16)返回 double 型的 4.0,cout输出4max({4, 9, 6})= 9(初始化列表取最大)ceil(3.1)向上取整 = 4;floor(3.9)向下取整 = 3
练习题 3(编程题)
题目: 输入一个正整数 n(n ≥ 2),输出 2 ~ n 之间质数的个数。
🔑 点击查看答案与解析
参考代码(C++):
cpp
#include <iostream>
#include <cmath>
using namespace std;
int main() {
int n;
cin >> n;
int cnt = 0;
for (int x = 2; x <= n; x++) { // 逐个判断 2~n
bool prime = true;
for (int i = 2; i <= sqrt(x); i++) { // 试除到 sqrt(x)
if (x % i == 0) {
prime = false;
break;
}
}
if (prime) cnt++;
}
cout << cnt << endl;
return 0;
}
// 输入:20
// 输出:8(质数为 2,3,5,7,11,13,17,19)解析要点: ① 外层循环枚举候选数,内层循环试除判断;② 内层只到 sqrt(x) 是标准优化;
练习题 4(编程题)
题目: 随机生成 n 个 [1, 100] 之间的整数,输出这 n 个数,并输出其中的最大值、最小值和平均值。
🔑 点击查看答案与解析
参考代码(C++):
cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
using namespace std;
int main() {
srand(time(0)); // 播种一次,放在循环外
int n;
cin >> n;
int sum = 0, mx = 0, mn = 101;
for (int i = 0; i < n; i++) {
int x = rand() % 100 + 1; // 生成 1~100
cout << x << " ";
sum += x;
mx = max(mx, x); // 边生成边更新最大、最小
mn = min(mn, x);
}
cout << endl;
cout << "最大值:" << mx << " 最小值:" << mn << endl;
cout << "平均值:" << (double)sum / n << endl; // 注意转 double 避免整数除法
return 0;
}
// 输入:5
// 输出(每次运行结果不同):
// 73 12 88 45 29
// 最大值:88 最小值:12
// 平均值:49.4解析要点: ① 随机数 + max/min 的综合考法;② 求平均值时 C++ 要 (double)sum / n 防止整数整除丢小数;
练习题 5(单选题)
题目: 下列关于 C++ 随机数的说法,正确的是( )
① rand() 函数能生成真正的随机数 ② 不调用 srand() 时,每次运行程序 rand() 产生的序列相同 ③ srand(time(0)) 应该放在循环内部,每次生成随机数前都播一次种 ④ 要生成 [10, 50] 的随机整数,写法是 rand() % 41 + 10
A. ①② B. ②③ C. ②④ D. ③④
🔑 点击查看答案与解析
答案: C
解析:
- ① 错误 ❌:计算机生成的是伪随机数——由种子按固定公式推算出来的,不是真正的随机。种子相同,序列就相同;
- ② 正确 ✅:不调用 srand 时,默认种子固定(通常为 1),所以每次运行得到的随机数序列完全一样;
- ③ 错误 ❌:
srand(time(0))整个程序只调用一次就够了,放在 main 开头。放在循环里反而会因为 time(0) 精确到秒、循环太快而反复播下相同的种子,导致随机数重复; - ④ 正确 ✅:万能公式
rand() % (b-a+1) + a,50−10+1 = 41,所以是rand() % 41 + 10,得到 10~50。
选 C(②④)。
🔥 高频考点:srand 只调用一次、放在循环外——这是判断题和改错题的"钉子户"考点。万能公式也要记牢:模的是"个数"(b-a+1),加的是"起点"(a)。
练习题 6(判断题)
题目: 判断下列说法是否正确,正确的打 ✓,错误的打 ×。
① abs(-3.5) 的返回值是整数类型。( )
② sqrt(16) 的返回值是 double 类型的 4.0。( )
③ C++ 中 max(3, 5, 7) 可以直接比较三个数的大小。( )
④ ceil(-2.3) 的结果是 -2。( )
⑤ rand() % 10 生成的随机数范围是 1~10。( )
⑥ pow(2, 10) 的结果是 1024.0(double 类型)。( )
🔑 点击查看答案与解析
答案: ① × ② ✓ ③ × ④ ✓ ⑤ × ⑥ ✓
解析:
- ① ×:
abs()主要用于整数,浮点数应该用fabs()。虽然 C++ 对 abs 做了重载,但规范写法是整数用 abs、浮点用 fabs; - ② ✓:
sqrt()返回值永远是 double 类型,即使结果是整数(如 sqrt(16)=4.0); - ③ ×:
max(a, b)只能比较两个数。比较三个数要用max({a,b,c})(C++11 初始化列表,需要大括号)或max(a, max(b, c))(嵌套调用); - ④ ✓:ceil 是向上取整(朝正方向),-2 比 -2.3 大(在数轴上更靠右),所以 ceil(-2.3) = -2。floor(-2.3) 才是 -3;
- ⑤ ×:
rand() % 10的范围是 0~9(余数为 0 到 9),不是 1~10。想要 1~10 应该写rand() % 10 + 1; - ⑥ ✓:
pow(2, 10)计算 2¹⁰ = 1024,返回值为 double 类型的 1024.0。
💡 负数取整最容易搞混,画个数轴就清楚了:ceil 往右边(大的方向)靠,floor 往左边(小的方向)靠。
练习题 7(程序阅读题)
题目: 阅读以下 C++ 程序,写出 4 行输出:
cpp
#include <iostream>
#include <cmath>
using namespace std;
int main() {
double x = 3.6;
cout << (int)x << endl; // 行1
cout << floor(x) << endl; // 行2
cout << ceil(x) << endl; // 行3
cout << (int)ceil(x) + 1 << endl;// 行4
return 0;
}🔑 点击查看答案与解析
答案:
3
3
4
5解析:
- 行1:
(int)3.6强制类型转换,截断小数 → 3(截断不是四舍五入); - 行2:
floor(3.6)向下取整(朝 -∞ 方向)= 3; - 行3:
ceil(3.6)向上取整(朝 +∞ 方向)= 4; - 行4:
ceil(3.6) = 4.0,强转 int 得 4,再加 1 = 5。
🔥 易混淆三者对比:
- 强制转换
(int)x:截断小数(向零取整),正数与 floor 相同,负数与 ceil 相同;floor(x):向下取整(朝负方向);ceil(x):向上取整(朝正方向)。
练习题 8(单选题)
题目: 用随机数模拟"石头剪刀布"游戏。程序随机生成 0=石头、1=剪刀、2=布,玩家输入自己的选择(0/1/2),程序输出电脑出什么、谁赢了。
规则:石头赢剪刀、剪刀赢布、布赢石头;相同则平局。
输入样例1:
0输出样例1(假设电脑出1):
电脑出:剪刀
你赢了!输入样例2:
1输出样例2(假设电脑出1):
电脑出:剪刀
平局!🔑 点击查看答案与解析
参考代码(C++):
cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main() {
srand(time(0));
int player, computer;
cin >> player; // 玩家输入:0石头 1剪刀 2布
computer = rand() % 3; // 电脑随机:0~2
// 输出电脑出什么
if (computer == 0) cout << "电脑出:石头" << endl;
else if (computer == 1) cout << "电脑出:剪刀" << endl;
else cout << "电脑出:布" << endl;
// 判断胜负
if (player == computer) {
cout << "平局!" << endl;
} else if ((player == 0 && computer == 1) // 石头赢剪刀
|| (player == 1 && computer == 2) // 剪刀赢布
|| (player == 2 && computer == 0)) { // 布赢石头
cout << "你赢了!" << endl;
} else {
cout << "你输了!" << endl;
}
return 0;
}解析要点:
- 用
rand() % 3生成 0、1、2 三个随机数,分别代表石头、剪刀、布; - 胜负判断用逻辑或
||列出玩家赢的三种情况,其余情况就是玩家输; - 这是随机数 + 分支结构的经典综合应用,考试中常以"猜拳""掷骰子""抽奖"等形式出现。
🍎 生活比喻:srand(time(0)) 就像"洗牌"——只洗一次,然后一张张抽牌(rand())。如果你每抽一张都重新洗一次(srand放循环里),因为洗得太快,牌还没变化,抽出来的都是同一张。
九、📊 考点总结表
| 考点 | 重要程度 | 出题形式 |
|---|---|---|
C++ abs(int)与 fabs(double)的区别 | ⭐⭐⭐⭐ | 选择/判断 |
sqrt() 返回 double、负数开方返回 nan | ⭐⭐⭐⭐ | 选择/程序阅读 |
max/min 及 C++11 初始化列表 | ⭐⭐⭐ | 程序阅读/编程 |
pow/ceil/floor 及负数取整方向 | ⭐⭐⭐ | 选择/判断 |
rand()/srand()/RAND_MAX(32767) | ⭐⭐⭐⭐⭐ | 选择/判断(必考) |
[a,b] 随机整数公式 rand()%(b-a+1)+a | ⭐⭐⭐⭐⭐ | 选择/编程(必考) |
不播种每次结果相同、srand(time(0)) 只写一次 | ⭐⭐⭐⭐⭐ | 选择/判断 |
| 掷骰子、猜数字等随机模拟编程 | ⭐⭐⭐⭐⭐ | 编程大题 |
用 sqrt(n) 优化质数判断 | ⭐⭐⭐⭐ | 编程大题 |
⭐ 必背速记卡
┌─────────────────────────────────────────────────────┐
│ 1. 整数绝对值 abs(x),浮点绝对值 fabs(x) │
│ 2. sqrt(x) 返回 double,负数开方得 nan │
│ 3. max/min比大小,头文件algorithm │
│ 4. C++11初始化列表:max({a,b,c}) 比三个数 │
│ 5. pow(a,b)求幂,ceil向上取整,floor向下取整 │
│ 6. 负数取整看数轴:ceil朝右(大),floor朝左(小) │
│ 7. rand()返回0~RAND_MAX的伪随机整数 │
│ 8. RAND_MAX至少32767,Dev-C++中就是32767 │
│ 9. 不播种每次结果相同,种子相同序列相同 │
│ 10. srand(time(0))用时间播种,整个程序只调用一次 │
│ 11. srand放循环外,放循环里反而不随机 │
│ 12. [a,b]随机整数万能公式:rand()%(b-a+1) + a │
│ 13. 骰子点数:rand()%6+1(1~6) │
│ 14. 0~99:rand()%100,1~100:rand()%100+1 │
│ 15. 质数判断优化:只需试除到sqrt(n) │
└─────────────────────────────────────────────────────┘