srand((unsigned)time(NULL))和rand的区别

本文深入解析C++中rand()函数的工作机制,包括其如何初始化种子、如何生成随机数以及如何确保每次程序运行时产生不同的随机数序列。通过示例代码展示了如何使用rand()和srand()函数来实现随机数生成,并讨论了在不同场景下种子初始化的重要性。

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

可以认为rand()在每次被调用的时候,它会查看:
1) 如果用户在此之前调用过srand(seed),给seed指定了一个值,那么它会自动调用
srand(seed)一次来初始化它的起始值。
2) 如果用户在此之前没有调用过srand(seed),它会自动调用srand(1)一次。


1) 如果希望rand()在每次程序运行时产生的值都不一样,必须给srand(seed)中的seed一个变值,这个变值必须在每次程序运行时都不一样(比如到目前为止流逝的时间)。
2) 否则,如果给seed指定的是一个定值,那么每次程序运行时rand()产生的值都会一样,虽然这个值会是[seed, RAND_MAX(0x7fff))之间的一个随机取得的值。
3) 如果在调用rand()之前没有调用过srand(seed),效果将和调用了srand(1)再调用rand()一样(1也是一个定值)。

stdlib.h头文件中有宏#define RAND_MAX 0x7fff 
rand()产生一个0到0x7ffff即0到32767之间的随机数 
rand()/(RAND_MAX+1.0)就等于一个0到1之间的小数了,因为rand()最大是32767最小是0,再除以32768就是一个0到1之间的小数(不能等于1),再乘以10就是一个0到10之间的数了(不等于10).最后再加1,就成了一个求1到10之间随机数的式子了.

srand函数是随机数发生器的初始化函数,原型: 
void srand(unsigned seed); 
它需要提供一个种子,如: 
srand(1); 
直接使用1来初始化种子。
不过常常使用系统时间来初始化,即使用 
time函数来获得系统时间,它的返回值为从 00:00:00 GMT, January 1, 1970 
到现在所持续的秒数,然后将time_t型数据转化为(unsigned)型在传给srand函数,即: 
srand((unsigned) time(&t)); 
还有一个经常用法,不需要定义time_t型t变量,即: 
srand((unsigned) time(NULL)); 
直接传入一个空指针,因为你的程序中往往并不需要经过参数获得的t数据。
srand((int)getpid()); 
使用程序的ID(getpid())来作为初始化种子,在同一个程序中这个种子是固定的 
随机输出十个0-100之间的整数 
#include <stdlib.h> 
#include <stdio.h> 
#include <time.h> 
void main( void ) 

int i,k;
srand( (unsigned)time( NULL ) ); 
for( i = 0; i < 10;i++ ) 

k=rand()%100; 
printf( " k=%d\n", k ); 

}

补充:

srand()放在哪里并不是问题所在,问题在于两次运行srand((unsigned)time(NULL))之间的时间间隔要足够大,要能让( unsigned )time( NULL )反映出不同的数值,这样种子才不同。 

把srand()放在main里,每次运行程序的时候,从程序结束到重新开始运行,至少都是过了几秒了,这时候种子是不同的,所以随机生成的数不一样。 

把srand()放在其它函数里,计算机代码的运行是很快的,在一秒内调用该函数的次数可能都上几十万次了,( unsigned )time( NULL )可能来不及产生不同的数值,种子是相同的,因此随机生成的数都是一样的。


原文地址:http://hi.baidu.com/shismbwb/item/2ca179f45e9dfe40922af23c

<think>嗯,用户问的是关于srand((unsigned int)time(NULL))的介绍。首先,我得回忆一下C语言中随机数生成的相关知识。srandrand函数是配套使用的,对吧?srand用来设置随机数种子,而rand根据这个种子生成伪随机数序列。 用户提供的代码中,srand的参数是(unsigned int)time(NULL)。这里可能需要解释为什么用time(NULL)time函数返回当前时间的秒数,作为种子的话,每次程序运行的时候种子都会不同,这样生成的随机数序列就不会重复。如果不用srand设置种子,或者每次用同样的种子,rand()会生成相同的序列,这在需要随机性的场合就不合适了。 不过,用户可能不太清楚类型转换的部分。time_t返回的类型可能是long或者其他类型,而srand需要unsigned int,所以这里显式转换(unsigned int)是为了避免编译器警告或者错误。需要说明一下这个类型转换的必要性。 另外,用户可能想知道为什么是time(NULL)NULL在这里作为参数传给time函数,表示不需要存储返回的时间值,直接获取当前时间。这部分可能需要简单解释一下time函数的用法。 还要注意,这个方法是基于系统时间的秒数,所以如果在同一秒内多次运行程序,种子会相同,导致随机数序列重复。这可能是个限制,但在大多数情况下已经够用了。如果是需要更高随机性的场景,可能需要其他方法,比如读取/dev/urandom或者使用更复杂的算法。 接下来需要组织回答的结构,先介绍srandrand的关系,然后解释time(NULL)的作用,接着说明类型转换的原因,最后提一下使用时的注意事项潜在问题。确保用中文,分步骤讲解,避免技术术语过于晦涩,让用户容易理解。 可能用户是刚开始学习C语言,遇到了随机数生成的代码,想了解这行代码的作用。所以需要从基础讲起,不用假设他们已经有深入的知识。同时,按照系统指令,数学公式要用$...$,但这个问题可能不太涉及数学表达式,所以可能用不上。但如果有提到伪随机数生成的算法,可能需要用公式,不过这里可能不需要。 总结回答的要点:srand的作用,种子的重要性,time(NULL)获取时间,类型转换的原因,使用场景注意事项。确保结构清晰,分点解释,帮助用户逐步理解。</think>我们来逐步解释 `srand((unsigned int)time(NULL))` 的作用原理: --- ### **1. 核心功能** - **`srand()`**:C语言中用于设置伪随机数生成器的种子值(seed)。 - **`rand()`**:根据种子生成伪随机数序列。 - **`time(NULL)`**:获取当前系统时间的秒数(从1970年1月1日算起)。 --- ### **2. 为什么需要 `srand((unsigned int)time(NULL))`?** - **问题**:如果直接调用 `rand()`,每次程序运行时生成的随机数序列**完全相同**(因为种子默认固定为1)。 - **解决**:通过 `srand(time(NULL))` 将种子设置为当前时间,使得每次程序运行时种子不同,从而生成不同的随机序列。 --- ### **3. 代码细节解析** ```c srand((unsigned int)time(NULL)); ``` - **`time(NULL)`**:返回当前时间的 `time_t` 类型值(通常是长整型)。 - **`(unsigned int)`**:强制类型转换,将 `time_t` 转换为 `srand()` 接受的 `unsigned int` 类型。 - **`NULL`**:表示不存储返回值,直接获取时间。 --- ### **4. 注意事项** - **重复问题**:若程序在**同一秒内多次运行**,种子可能相同,导致随机序列重复。 - **替代方案**:高安全性场景建议使用更复杂的随机源(如操作系统熵池 `/dev/urandom`)。 - **C++改进**:C++11后推荐使用 `<random>` 库(如 `std::mt19937`)。 --- ### **5. 示例代码** ```c #include <stdio.h> #include <stdlib.h> #include <time.h> int main() { // 设置随机种子 srand((unsigned int)time(NULL)); // 生成0-99的随机数 int num = rand() % 100; printf("随机数: %d\n", num); return 0; } ``` --- ### **总结** `(unsigned int)time(NULL)` 的作用是: 1. 用系统时间初始化随机种子 2. 确保每次程序运行的随机序列不同 3. 需注意精度不足的潜在问题 希望这个解释对您有帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值