19.7 随机数生成
在 C 语言中,我们可以使用标准库 <stdlib.h> 中的两个函数 rand() 和 srand() 来生成随机数。
rand() 函数
rand() 函数用于生成一个随机整数,范围在 0 到 RAND_MAX 之间。RAND_MAX 是一个宏,值至少为 32767。
基本用法:
#include <stdlib.h>
int random_number = rand();2
3
srand() 函数
srand() 函数用于设置随机数生成器的种子。如果不设置种子,程序每次运行时会生成相同的随机数序列。应该只在程序开始时调用一次 srand(),而不是在循环中重复调用。
基本用法:
#include <stdlib.h>
#include <time.h>
srand(time(NULL)); // 使用当前时间作为种子2
3
4
生成指定范围的随机数
要生成指定范围内的随机数,可以使用取模运算符:
// 生成 0 到 99 之间的随机数
int random_0_to_99 = rand() % 100;
// 生成 1 到 100 之间的随机数
int random_1_to_100 = rand() % 100 + 1;
// 生成 a 到 b 之间的随机数
int random_a_to_b = rand() % (b - a + 1) + a;2
3
4
5
6
7
8
生成浮点随机数
如果需要生成浮点数随机数,可以将 rand() 的结果除以 RAND_MAX:
double random_float = (double)rand() / RAND_MAX; // 生成 0 到 1 之间的随机浮点数
double random_float_range = (double)rand() / RAND_MAX * (b - a) + a; // 生成 a 到 b 之间的随机浮点数2
3
完整示例
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
// 设置随机数种子
srand((unsigned)time(NULL));
// 输入范围
int a, b;
if (scanf("%d%d", &a, &b) != 2) {
return 1;
}
// 生成并打印 5 个整数随机数
for (int i = 0; i < 5; i++) {
printf("随机数 %d: %d\n", i + 1, a + rand() % (b - a + 1));
}
// 生成并打印一个浮点随机数
double random_float = (double)rand() / RAND_MAX * (b - a) + a;
printf("随机浮点数:%.2f\n", random_float);
return 0;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
例如输入范围 1 10,某一次运行可能得到:
1 10 随机数 1: 7 随机数 2: 2 随机数 3: 10 随机数 4: 4 随机数 5: 8 随机浮点数:4.63
种子来自当前时间,因此每次运行得到的数列可能不同;五个整数都应位于闭区间 [1, 10],最后一个数应位于 [1.0, 10.0]。
猜数游戏
我们来写一个小示例,演示随机数生成的应用。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
// 设置随机数种子
srand((unsigned)time(NULL));
// 生成一个随机数
int secretNumber = rand() % 100 + 1; // 生成 1 到 100 之间的随机数
int guess;
do {
printf("猜一个 1 到 100 之间的数:");
scanf("%d", &guess);
if (guess < secretNumber) {
printf("太小了!\n");
} else if (guess > secretNumber) {
printf("太大了!\n");
} else {
printf("猜对了!\n");
}
} while (guess != secretNumber);
return 0;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
假设本次生成的答案是 42,一次可能的交互过程是:
猜一个 1 到 100 之间的数:50 太大了! 猜一个 1 到 100 之间的数:25 太小了! 猜一个 1 到 100 之间的数:42 猜对了!
答案由当前时间初始化的伪随机序列决定,因此实际猜测过程不会固定。
习题
“投飞镖”可以近似
“投针”可以近似
(1) [M3.2] 证明上式。
(2) [2.3] 设计程序,输入间距 d 和投掷次数,估算
编写一个猜数小游戏:随机生成一个 1 到 100 的整数,玩家需要猜出这个整数。每次猜测后,程序会提示玩家猜测的数是太大还是太小。玩家可以根据提示继续猜测,直到猜中为止。