用VC的rand和srand产生规定范围内的数,例如1-30, 20-50。

本文介绍了如何使用 C 语言实现一个简单的随机数生成器,并通过实例展示了其在不同范围内的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#define getrandom( min, max ) ((rand() % (int)(((max) + 1) - (min))) + (min))

//先初始化
srand((unsigned)time(NULL));


1-30:
int nNumber = getrandom(1, 30);

20-50:
int nNumber = getrandom(20, 50);

<think>我们正在讨论C语言中srandrand生成随机数的问题。用户发现使用srand后,rand生成的随机数总是固定,想了解原因。根据引用,我们知道rand生成的是伪随机数,它是通过一个算法基于种子(seed)计算出来的。如果种子相同,那么计算出来的随机数序列就会相同。通常,在使用rand()之前,我们会用srand(seed)来设置随机数种子。如果每次程序运行时都使用相同的种子,那么rand()产生随机数序列就会相同。常见的情况是,用户可能没有正确地设置种子,比如:1.没有调用srand,那么系统默认种子为1(根据引用[2][4]),所以每次运行程序都会产生相同的序列。2.虽然调用了srand,但是种子是固定的,比如srand(1),那么每次运行程序种子都是1,因此序列相同。为了解决这个问题,通常的做法是使用当前时间作为种子,因为时间每时每刻都在变化。例如:srand((unsignedint)time(NULL));这样,每次运行程序时,种子都不同(除非在同一秒内多次运行,但通常程序运行间隔至少一秒,所以时间不同)。但是,如果用户在使用srand(time(NULL))后,仍然发现随机数序列在短时间内多次运行程序时相同,那可能是因为time(NULL)返回的时间是以秒为单位的,如果在同一秒内多次运行程序,那么种子相同,序列也就相同。另外,根据引用[5]的示例,正确的做法是在程序开始时调用一次srand,而不是在每次调用rand之前都调用srand。因为如果在一个循环中每次调用rand之前都调用srand,而且种子相同(比如用time(NULL),在同一秒内多次调用,种子相同),那么每次rand()返回的序列的第一个可能相同(因为种子重置了)。总结原因:1.没有使用srand设置种子,或者设置的种子是固定值。2.虽然使用了时间作为种子,但在同一秒内多次运行程序,导致种子相同。3.错误地在每次调用rand之前都调用srand,并且种子变化不够快(如使用时间秒,而同一秒内多次调用)。因此,正确的做法是:在程序开始时(如main函开头)调用一次srand,使用当前时间作为种子(srand((unsignedint)time(NULL))),然后在整个程序运行期间,通过多次调用rand来获取随机数序列。注意:time函需要包含头文件<time.h>。下面是一个示例代码:```c#include<stdio.h>#include<stdlib.h>#include<time.h>intmain(){//设置随机数种子,使用当前时间srand((unsignedint)time(NULL));//生成10个随机数for(inti=0;i<10;i++){intrandom_num=rand()%100;//生成0到99的随机数printf("%d",random_num);}printf("\n");return0;}```这样,每次运行程序时,种子不同,生成的随机数序列也就不同(除非在同一秒内运行多次,但通常不会)。如果用户需要在同一秒内多次运行程序而得到不同的序列,可能需要更细粒度的种子,比如使用毫秒时间(但C标准库的time函只到秒,可以使用其他系统特定的函获取更高精度的时间)。不过一般情况下,用秒就足够了。所以,用户遇到rand生成的随机数总是固定的原因,很可能是因为没有设置种子(或者设置了固定种子)或者设置种子的方式不对(比如在循环中设置相同的种子)。</think>### C语言中使用srandrand生成的随机数始终固定的原因分析 在C语言中,`rand()`函生成的随机数始终固定,主要涉及以下原因: 1. **未正确初始化随机种子** `rand()`本质是伪随机数生成器,其序列完全由种子(seed)决定。如果未调用`srand()`初始化,或初始化值固定,则每次程序启动时: ```c // 错误示例:种子固定 srand(123); // 每次启动都使用相同种子 printf("%d", rand()); // 永远输出相同值 ``` 根据引用[4]:*"rand() 函产生随机数是伪随机数,是根据一个值按照某个公式推算出来的"*[^4]。 2. **时间种子初始化位置错误** 即使使用`time(NULL)`,若在循环中重复初始化: ```c for(int i=0; i<10; i++) { srand((unsigned)time(NULL)); // 1秒内time()返回值相同 printf("%d ", rand()%100); // 输出10个相同字 } ``` 引用[5]指出:*"srand((int)time(0))应放在循环外"*[^5]。因`time()`精度为秒,1秒内多次调用返回相同值。 3. **开发环境特殊处理** 某些IDE(如旧版VC)在调试模式会固定随机种子以便问题复现。引用[2]提到:*"rand返回的是伪随机数,编译打印出来固定是41"*[^2]。 --- ### 正确使用方法 ```c #include <stdlib.h> #include <time.h> int main() { srand((unsigned int)time(NULL)); // 程序启动时初始化一次 for(int i=0; i<5; i++) { printf("随机数: %d\n", rand()%100); } return 0; } ``` **关键点**: - `srand()`只需调用一次,通常在`main()`开头 - 使用`time(NULL)`获取系统时间作为种子 - 包含头文件`<time.h>``<stdlib.h>` --- ### 扩展说明 1. **随机数范围控制** 生成[a,b]区间随机数:`rand()%(b-a+1)+a` ```c int dice = rand()%6 + 1; // 1~6的骰子 ``` 2. **更高精度需求** 需毫秒级随机种子时,可用平台相关函: ```c #include <sys/time.h> struct timeval tv; gettimeofday(&tv, NULL); srand(tv.tv_usec); // 使用微秒部分 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值