
🌈个人主页:聆风吟_
🔥系列专栏:C语言标准库
🔖少年有梦不应止于心动,更要付诸行动。
文章目录
- 📋前言
- [一. rand()函数:生成伪随机数](#一. rand()函数:生成伪随机数)
-
- [1.1 头文件](#1.1 头文件)
- [1.2 函数原型](#1.2 函数原型)
- [1.3 函数功能](#1.3 函数功能)
- [1.4 返回值](#1.4 返回值)
- [1.5 用法](#1.5 用法)
- [1.6 问题:为什么每次运行结果相同?](#1.6 问题:为什么每次运行结果相同?)
- [二. srand()函数:设置随机数种子](#二. srand()函数:设置随机数种子)
-
- [2.1 头文件](#2.1 头文件)
- [2.2 函数原型](#2.2 函数原型)
- [2.3 函数功能](#2.3 函数功能)
- [2.4 辅助函数time()说明](#2.4 辅助函数time()说明)
- [2.5 常用种子设置方法](#2.5 常用种子设置方法)
- [2.6 注意事项](#2.6 注意事项)
- 📝全文总结
📋前言
rand()函数是C/C++中用于生成伪随机数的标准库函数,其底层基于线性同余法实现,生成的随机数序列受 "种子(seed)" 控制。默认情况下,rand()的种子固定为 1,因此每次运行程序生成的随机数序列完全相同;配合srand()函数设置动态种子,可让随机数序列具备真正的 "随机性"。
一. rand()函数:生成伪随机数
1.1 头文件
cpp
// C标准库
#include <stdlib.h>
1.2 函数原型
cpp
int rand(void);
1.3 函数功能
rand()函数是用来生成一个伪随机数。
1.4 返回值
返回值是一个介于
0 ~ RAND_ MAX (32767)之间的伪随机整数。
RAND_MAX 值的查询方法:
RAND_MAX是标准库定义的宏,表示rand()函数能返回的最大值,大多数视线中默认值为 32767,不同编译器可能略有差异。
验证方法(VS编译器):
- 方法一:转到
RAND_MAX定义查看:

- 方法二:使用代码验证:
c
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("当前编译器的 RAND_MAX = %d\n", RAND_MAX);
return 0;
}
运行结果示例:
c
当前编译器的 RAND_MAX = 32767
1.5 用法
rand()默认生成的范围过大,实际开发中我们通常需要指定范围(如 1~100),核心技巧是取模运算 + 偏移量。
(1)原理说明:
- 取模运算
n % m的结果范围是0 ~ m-1; - 加上偏移量可调整起始值,例如
n % m + k可将范围调整为k ~ m+k-1。
(2)通用公式:
c
// 生成[min, max]范围内的随机整数
int random_num = rand() % (max - min + 1) + min;
// 公式拆解:
// 1. rand() % (max - min + 1) → 生成 0 ~ (max-min) 的整数
// 2. + min → 将范围偏移为 min ~ max
(3)更多示例:
c
#include <stdio.h>
#include <stdlib.h>
int main()
{
// 示例1:生成0-59的随机数
int b1 = rand() % 60;
// 示例2:生成1-60的随机数
int b2 = rand() % 60 + 1;
// 示例3:生成1994-2023的随机数
int b3 = rand() % 30 + 1994;
// 示例4:生成-10到10的随机数
int b4 = rand() % 21 - 10;
printf("b1 (0-59): %d\n", b1);
printf("b2 (1-60): %d\n", b2);
printf("b3 (1994-2023): %d\n", b3);
printf("b4 (-10-10): %d\n", b4);
return 0;
}
1.6 问题:为什么每次运行结果相同?
(1)问题现象:
直接运行下面的示例代码,你会发现:每次启动程序,生成的随机数序列完全相同。
c
#include <stdio.h>
#include <stdlib.h>
int main()
{
int ret = rand();
// 输出结果:每次运行都是相同的序列
printf("%d\n", ret);
return 0;
}

(2)原因分析:
这是因为rand()函数生成的伪随机数,由一个隐藏的全局种子变量(seed)控制。在调用rand()函数前,程序会先检查是否主动调用过srand(seed)为伪随机数生成器设置种子:
- 如果调用过,伪随机数生成器会以你设定的种子值作为初始值;
- 如果未主动调用
srand(seed),系统会在首次调用rand()时自动执行一次srand(1),即把全局种子变量的初始值固定为 1。 - 由于伪随机数是通过固定算法基于种子值生成的,只要种子值相同,每次调用
rand()产生的伪随机数序列就完全一致。
而我们的代码中没有主动调用srand设定种子,系统每次都会用默认的种子 1 初始化,因此每次运行程序得到的随机数结果都是相同的。
(3)解决方案:
若想让程序每次运行生成的随机数序列都不重复,核心是让每次初始化伪随机数生成器时使用的种子值唯一。我们可以将系统当前时间作为种子:
c
srand((unsigned int)time(NULL));
由于程序每次运行的时间戳必然不同,以此初始化的种子值也会唯一,基于固定算法生成的伪随机数序列自然就不会重复了。
二. srand()函数:设置随机数种子
2.1 头文件
cpp
#include <stdlib.h>
2.2 函数原型
cpp
void srand (unsigned int seed);
2.3 函数功能
srand()用于设置rand()函数的随机数生成器的种子值。通过提供不同的种子,可以生成不同的随机数序列。
2.4 辅助函数time()说明
(1)头文件和函数原型:
c
// 头文件
#include <time.h>
// 函数原型
// time_t 是整型别名(通常为 long/unsigned int),用于存储时间戳
time_t time(time_t *tloc);
(2)函数功能:
返回从 "1970 年 1 月 1 日 00:00:00" 到当前时间的秒数(时间戳);
(3)参数:
通常使用time(NULL)或time(0)获取当前时间。
2.5 常用种子设置方法
cpp
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
// 第一步:设置种子为当前系统时间(仅需调用1次,建议放在程序开头)
srand((unsigned int)time(NULL));
// 第二步:生成10个1~100的随机数
printf("生成10个1~100的随机数:\n");
for (int i = 0; i < 10; i++)
{
int random_num = rand() % 100 + 1;
printf("%d ", random_num);
}
printf("\n");
return 0;
}
代码剖析:
c
// 设置种子为当前系统时间
srand((unsigned int)time(NULL));
因为srand函数需要接受的是unsigned int类型的值,而time返回的是time_t类型的值,所以在传参的时候要使用强制类型转换。
运行结果示例(每次运行不同):

2.6 注意事项
-
srand()一般只需在程序的开头调用一次 ,无需在每次调用rand()前重复调用; -
若短时间内重复运行程序(如 1 秒内),时间戳相同,仍可能生成相同序列(可结合毫秒级时间优化,新手暂无需掌握);
-
rand()生成的是 "伪随机数",并非密码学安全的随机数(加密场景需用专用库)。
📝全文总结
本文关键要点回顾:
- rand()函数 :生成
0 ~ RAND_MAX之间的伪随机整数 - srand()函数:设置随机数种子,确保每次运行产生不同序列
- 范围控制:通过取模运算生成指定范围的随机数
- 常用模式 :
srand((unsigned int)time(NULL))配合rand()
cpp
// 标准使用模式
#include <stdlib.h>
#include <time.h>
int main()
{
// 1. 初始化种子(程序开始处调用一次)
srand((unsigned int)time(NULL));
// 2. 生成指定范围的随机数
int random_num = rand() % (max - min + 1) + min;
return 0;
}
今天的干货分享到这里就结束啦!如果觉得文章还可以的话,希望能给个三连支持一下,聆风吟的主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的最大动力!
