srand() 是什么?
srand() 是 "seed random" 的缩写,它的全称是 Seed the Random Number Generator。

它的作用是初始化(或称为“播种”)C 语言标准库中的伪随机数生成器,它必须与 rand() 函数配合使用。
rand(): 生成一个伪随机整数,在程序第一次调用rand()之前,这个生成器需要一个初始值,这个初始值就被称为“种子”(seed)。srand(): 用来设置这个“种子”。
为什么需要 srand()?—— 核心问题
如果你不调用 srand(),直接使用 rand(),会发生什么?
C 标准规定,rand() 在程序中第一次被调用时,没有被 srand() 初始化,rand() 会自动使用 1 作为默认的种子。
这会导致什么问题?

每次运行程序,都会得到完全相同的“随机数”序列。
看这个例子:
#include <stdio.h>
#include <stdlib.h> // 包含 rand() 和 srand() 的头文件
int main() {
printf("不使用 srand() 的三次运行结果:\n");
// 第一次运行
printf("第一次运行: %d, %d, %d\n", rand(), rand(), rand());
// 第二次运行
printf("第二次运行: %d, %d, %d\n", rand(), rand(), rand());
// 第三次运行
printf("第三次运行: %d, %d, %d\n", rand(), rand(), rand());
return 0;
}
运行结果(每次运行都一样):
不使用 srand() 的三次运行结果:
第一次运行: 41, 18467, 6334
第二次运行: 41, 18467, 6334
第三次运行: 41, 18467, 6334
可以看到,三次运行的输出完全一致,这在很多场景下(如游戏、模拟、加密等)是完全没有用处的。

如何正确使用 srand()?
为了得到不同的随机数序列,我们需要在每次程序运行时,给 srand() 一个不同的种子。
最常用的方法:使用当前时间作为种子。
C 语言提供了一个函数 time(),它可以返回自某个固定时间点(称为“纪元”,Epoch)以来经过的秒数,这个值在每次程序运行时几乎都是不同的。
使用 time() 的步骤:
- 包含
<stdlib.h>和<time.h>头文件。 - 在调用
rand()之前,调用srand((unsigned int)time(NULL))。
代码示例:
#include <stdio.h>
#include <stdlib.h> // rand(), srand()
#include <time.h> // time()
int main() {
// 1. 使用当前时间作为随机数生成器的种子
// 只需要播种一次,通常在程序开始时进行
srand((unsigned int)time(NULL));
printf("使用 srand(time(NULL)) 的三次运行结果:\n");
// 第一次运行
printf("第一次运行: %d, %d, %d\n", rand(), rand(), rand());
// 第二次运行
printf("第二次运行: %d, %d, %d\n", rand(), rand(), rand());
// 第三次运行
printf("第三次运行: %d, %d, %d\n", rand(), rand(), rand());
return 0;
}
可能的运行结果(每次运行都不同):
使用 srand(time(NULL)) 的三次运行结果:
第一次运行: 1580899500, 1498707664, 1403622589
第二次运行: 1580899501, 1498707665, 1403622590
第三次运行: 1580899502, 1498707666, 1403622591
(注意:你的实际输出会根据你运行程序的具体时间而变化)
srand() 的最佳实践和注意事项
1 只调用一次 srand()
一个常见的错误是在循环中重复调用 srand()。
// 错误示范
for (int i = 0; i < 10; i++) {
srand((unsigned int)time(NULL)); // 错误!
printf("%d ", rand() % 100);
}
为什么这是错误的?
time() 函数的精度是秒,如果这个循环在1秒内执行完成,time(NULL) 会返回相同的值,那么每次 srand() 都会用同一个种子来初始化生成器,导致你得到的是完全相同的随机数。
正确做法: 只在程序开始时调用一次 srand()。
// 正确示范
srand((unsigned int)time(NULL)); // 只在开始时调用一次
for (int i = 0; i < 10; i++) {
printf("%d ", rand() % 100);
}
2 生成特定范围的随机数
rand() 函数生成的随机数的范围是 0 到 RAND_MAX(一个在 <stdlib.h> 中定义的宏,通常是 32767 或更大)。
如果你需要一个不同范围的随机数,可以使用取模运算符 。
公式:rand() % N 会生成一个 [0, N-1] 范围内的整数。
生成一个 1 到 10 之间的随机数:
int random_number = (rand() % 10) + 1; // 结果在 1 到 10 之间
注意: 这种简单的取模方法有一个小问题。RAND_MAX 不是 N 的整数倍,那么序列中较小的数字出现的概率会比较大的数字略微高一点,对于大多数应用场景,这点偏差可以忽略不计,如果需要完美的均匀分布,需要更复杂的算法。
| 函数 | 作用 | 使用场景 |
|---|---|---|
rand() |
生成一个伪随机整数。 | 需要随机数时。 |
srand(seed) |
初始化伪随机数生成器。 | 必须在第一次调用 rand() 之前使用,以避免每次运行都得到相同的序列。 |
time(NULL) |
获取当前日历时间(秒)。 | 作为 srand() 的种子,是获取不同种子的最常用方法。 |
核心要点:
rand()默认种子是 1,导致每次运行结果相同。srand()用于设置种子,改变rand()的行为。- 使用
time(NULL)作为种子,可以确保每次运行程序时种子都不同。 srand()只需调用一次,通常在main函数的开头。- 使用
rand() % N来生成特定范围的随机数。
掌握了 srand() 和 rand() 的用法,你就可以在 C 程序中实现各种需要随机性的功能了。
