Skip to content

第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 / minmax(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_MAXrand() 能返回的最大值,**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)) 之后,每次运行结果都不同。

🔥 高频考点(必考):

  1. 不播种,每次运行结果都相同! 题目问"为什么程序每次运行输出的随机数都一样",答案就是缺少 srand(time(0))。
  2. 范围公式 rand() % (b - a + 1) + a 中,取模的数是"个数"(b-a+1),加的数是"起点" a,几乎每次考试都考。
  3. 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 输出 4
  • max({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)                  │
└─────────────────────────────────────────────────────┘

百炼成钢,融会贯通