【C】揭秘rand()函数;
原文地址:http://www.cnblogs.com/ngnetboy/archive/2012/11/23/2784078.html

1 #include<stdio.h>
2 #include<stdlib.h>
3 int main(void)
4 {
5 int j;
6 for(j=0;j<5;j++)
7 {
8 printf("rand():%d\n",rand());
9 }
10 }

linux下gcc每次运行结果如下:

windows vc6.0每次运行结果如下:(本人windows系统为64位机)

(由于编译器的不同,可能显示的结果也不同吧!)
rand()函数不是随机的吗?怎么每次运行的结果都是一样的?其实计算机也不像人们想象的那么智能,它也是按照人们的思想来随机出数的。本人在linux下查找头文件没有找到rand()函数的定义,上网查了一下也没找到,说是被封装到库中了。若是有大牛们看到这篇文章,请帮帮小弟解决心中的疑问吧!
那么如何用rand()函数获取你想要的取值范围呢?其实rand()函数的取值范围在0~RAND_MAX之间;
那么什么是RAND_MAX呢?
linux下的RAND_MAX值为2147483647(二进制32位)
windows下的RAND_MAX值为32767(二进制16位)
由此可见RAND_MAX是根据编译器对int型分配的空间而定的;这种说法应该也是错的,因为我在windows下的vc中打印sizeof(int)的值之后竟然显示4,也就是说int在vc中的存储空间应该是32位,所以我认为是vc编译器对rand()函数的定义做了修改,使RAND_MAX的值更小,方便了开发者的取值;(下面会介绍为什么编译器这样做)
我们知道了rand()函数的取值范围后,如何取得你想要的数值范围呢?我们取0~10的值好了。正常的思路如下,10*rand()/(RAND_MAX+1)+1(用10乘以rand()取得的随机数,然后除以RAND_MAX,再加1),应该是这样的了。代码如下:

1 #include<stdio.h>
2 #include<stdlib.h>
3 int main(void)
4 {
5 int i;
6 for(i=0;i<3;i++)
7 {
8 d=rand();
9 c=1 + (10*d/(RAND_MAX));
10 printf("1 + (10*rand()/(RAND_MAX+1)):%d\n",c);
11 }
12
13 }

运行结果如下:

好像也达到我们的效果了。但是如果把这段代码放到linux下用gcc编译又是什么样的结果呢?
同样的代码,我们来看看结果

这是怎么回事?为什么同样的代码,到了另一个编译器后就不一样了?
还记得我们刚才分别在这两个编译器中求的RAND_MAX的值吗?对,vc中是32767,而gcc中是2147483647。这时候你该问了跟这个有关系吗?我可以十分肯定的告诉你,相当的有关系。我们来写个小程序验证我的猜想吧!代码如下:

1 #include<stdio.h>
2 #include<stdlib.h>
3 int main(void)
4 {
5 int i,a,d;
6 for(i=0;i<5;i++)
7 {
8 d=rand();
9 a=d*10;
10 printf("%d",sizeof(int));
11 printf("rand()*10:%d\n",a);
12 }
13 }

运行结果如下:

你看出有什么不一样了吗?对,这就是vc为什么对rand()函数的RAND_MAX的值进行修改了。在gcc中rand()的取值范围是0~32位的二进制数,如果拿这个随机数乘以10的话,很可能会发生数值溢出,也就是说gcc中int的值最大就取到2147483647,如果乘以10的话,只能接着往后排列了,-2147483647、-2147483646、-2147483645········一直到取得的那个值。所以会得到一些负数。
到了这里我想你应该知道解决的办法了吧~!没错,就是用一个double类型的数来接收rand()*10,我们没办法改变RAND_MAX的值,我们可以用更大的数来表示rand()*10。
这下应该可以了吧,我们修改一下代码看看效果:

1 #include<stdio.h>
2 #include<stdlib.h>
3 int main(void)
4 {
5 int i,a,d;
6 for(i=0;i<5;i++)
7 {
8 printf("(int)(10.0*rand()/(RAND_MAX+1.0)):%d\n",1+(int)(10.0*d/(RAND_MAX+1.0)));
9 }
10 }

运行结果如下:

对,这就是我们想要的结果了!
PS——函数会随着编译器的不同而效果不同,但是它终究逃不过开发者的眼睛,注意细节。
附加:
取0-1之间的浮点型值:

1 #include <stdio.h>
2 #include<stdlib.h>
3 #include<time.h>
4
5 int main(void)
6 {
7 int i;
8 float a;
9 srand((unsigned)time(NULL));
10 for(i=0;i<10;i++)
11 {
12 printf("%.1f\n",rand()/(RAND_MAX+0.1));
13 }
14 }

srand()函数是设置随机数的种子,由前面的推论可知rand()函数只是一个伪随机函数,srand()函数就是为rand()函数设置种子;time()函数是获取当前的时间,因此第九行代码就是为rand()函数设置一个根据系统时间变化的随机种子,这样代码在每次运行的时候的结果都不会一样了!
【C】揭秘rand()函数;的更多相关文章
- srand()以及rand()函数用法
srand()就是给rand()提供种子seed 如果srand每次输入的数值是一样的,那么每次运行产生的随机数也是一样的, srand(n) for(10) rand()也就是说,以一个固定的数值作 ...
- MySQL使用rand函数实现随机数[转]
如何写一个语句能一下更新几百条MYSQL数据! 需要测试MYSQL数据库,里面有一个上万条数据的数据库,如何写一个PHP文件一下每次更新几百条信息,我都是写一个循环一次更新一条信息,这样我知道用WHI ...
- Matlab中Rand()函数用法
一.理论准备 matlab函数randn:产生均值为0,方差 σ^2 = 1,标准差σ = 1的正态分布的随机数或矩阵的函数. 用法:Y = randn(n),返回一个n*n的随机项的矩阵.如果n不是 ...
- 关于 rand() 函数返回值的值域的疑问
<C语言参考手册>中关于 rand() 函数有如下描述. (1)rand() 函数的原型 int rand(void); (2)连续调用 rand 将返回 0 到 int 类型的最大可表示 ...
- C random C ++rand函数应用
random函数不是ANSI C标准,不能在gcc,vc等编译器下编译通过.但在C语言中int random(num)能够这样使用,它返回的是0至num-1的一个随机数. 可改用C++下的rand函数 ...
- RAND函数和SRAND函数
首先我们要对rand&srand有个总体的看法:srand初始化随机种子,rand产生随机数,下面将详细说明. rand(产生随机数) 表头文件: #include<stdlib.h&g ...
- C语言中生产随机数 rand()函数
参考资料:C语言中产生随机数 一:如果你只要产生随机数而不需要设定范围的话,你只要用rand()就可以了:rand()会返回一随机数值, 范围在0至RAND_MAX 间.RAND_MAX定义在stdl ...
- 关于rand()函数 转载于其他人
C++中的rand()函数 分类: 编程语言/ C#/ 文章 C++中产生随机数种子对于初学者一直都很困惑.大家知道,在C中有专门的srand(N)函数可以轻松实现这一功能,然而在C++中则要复杂一些 ...
- mysql的rand函数
项目中需要动态随机生成一些固定位数的随机数,如8位,5位等. 之前看到的写法是这样 ROUND(ROUND(RAND(),5)*100000) 这样写不太准确,有几率出现4位的情况,Rand() 函数 ...
随机推荐
- Jquery+ajax模板
$.ajax({ url:'', type:'POST', //GET async:true, //或false,是否异步 data:{ name ...
- centos将uwsgi添加为系统服务
如果退出ssh 链接, 都会导致uwsgi进程关闭 这时, 我们需要进行管理软件管理uwsgi进行的运行, centos系统中我们采用 systemd, 让我们的项目变为系统服务 第一步: 首先 vi ...
- JAVA中final关键字的作用
一.final关键字的功能概述 final关键字可以用来修饰引用.方法和类. 1.用来修饰一个引用 如果引用为基本数据类型,则该引用为常量,该值无法修改: 如果引用为引用数据类型,比如对象.数组,则该 ...
- 对象和Map转化gongju
package czc.superzig.modular.utils; import java.lang.reflect.Field; import java.util.HashMap; import ...
- python爬虫(七) mozillacookiejar
MozillaCookiejar 保存百度得Cookiejar信息: from urllib import request from urllib import parse from http.coo ...
- 将图片转化为base64编码字符串
pom依赖 <dependency> <groupId>org.ops4j.base</groupId> <artifactId>ops4j-base- ...
- SRS源码—— Thread笔记
SRS源码中的Thread是一层套一层,最终的Thread类是在 srs_app_thread.cpp 的 SrsThread 类 这里我们暂且先放下协程的概念,把它当线程来看,其逻辑如下: 1. 在 ...
- mysql 获取刚插入行id汇总
mysql 获取刚插入行id汇总 我们在写数据库程序的时候,经常会需要获取某个表中的最大序号数, 一般情况下获取刚插入的数据的id,使用select max(id) from table 是可以的.但 ...
- 微信小程序中,如何点击链接跳转到外部网页
跳转到内部链接 这个我们应该都知道,通过wx.navigateTo,wx.redirectTo,wx.swtichTab等小程序内部的方法,可以直接跳转到小程序内部已经注册的(就是在app.json中 ...
- 深入 Laravel 资料
深入 Laravel 核心 Learning_Laravel_Kernel laravel 源码详解