C语言:随机数
在实际编程中,我们经常需要生成随机数,例如,贪吃蛇游戏中在随机的位置出现食物,扑克牌游戏中随机发牌。
在C语言中,我们一般使用 <stdlib.h> 头文件中的 rand() 函数来生成随机数,它的用法为:
int rand (void);
void 表示不需要传递参数。
C语言中还有一个 random() 函数可以获取随机数,但是 random() 不是标准函数,不能在 VC/VS 等编译器通过,所以比较少用。
rand() 会随机生成一个位于 0 ~ RAND_MAX 之间的整数。
RAND_MAX 是 <stdlib.h> 头文件中的一个宏,它用来指明 rand() 所能返回的随机数的最大值。C语言标准并没有规定 RAND_MAX 的具体数值,只是规定它的值至少为 32767。在实际编程中,我们也不需要知道 RAND_MAX 的具体值,把它当做一个很大的数来对待即可。
下面是一个随机数生成的实例:
- #include <stdio.h>
- #include <stdlib.h>
- int main(){
- int a = rand();
- printf("%d\n",a);
- return 0;
- }
运行结果举例:
193
随机数的本质
多次运行上面的代码,你会发现每次产生的随机数都一样,这是怎么回事呢?为什么随机数并不随机呢?
实际上,rand() 函数产生的随机数是伪随机数,是根据一个数值按照某个公式推算出来的,这个数值我们称之为“种子”。种子和随机数之间的关系是一种正态分布,
种子在每次启动计算机时是随机的,但是一旦计算机启动以后它就不再变化了;也就是说,每次启动计算机以后,种子就是定值了,所以根据公式推算出来的结果(也就是生成的随机数)就是固定的。
重新播种
我们可以通过 srand() 函数来重新“播种”,这样种子就会发生改变。srand() 的用法为:
void srand (unsigned int seed);
它需要一个 unsigned int 类型的参数。在实际开发中,我们可以用时间作为参数,只要每次播种的时间不同,那么生成的种子就不同,最终的随机数也就不同。
使用 <time.h> 头文件中的 time() 函数即可得到当前的时间(精确到秒),就像下面这样:
srand((unsigned)time(NULL));
对上面的代码进行修改,生成随机数之前先进行播种:
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- int main() {
- int a;
- srand((unsigned)time(NULL));
- a = rand();
- printf("%d\n", a);
- return 0;
- }
多次运行程序,会发现每次生成的随机数都不一样了。但是,这些随机数会有逐渐增大或者逐渐减小的趋势,这是因为我们以时间为种子,时间是逐渐增大的,结合上面的正态分布图,很容易推断出随机数也会逐渐增大或者减小。
生成一定范围内的随机数
在实际开发中,我们往往需要一定范围内的随机数,过大或者过小都不符合要求,那么,如何产生一定范围的随机数呢?我们可以利用取模的方法:
int a = rand() % 10; //产生0~9的随机数,注意10会被整除
如果要规定上下限:
int a = rand() % 51 + 13; //产生13~63的随机数
分析:取模即取余,rand()%51+13我们可以看成两部分:rand()%51是产生 0~50 的随机数,后面+13保证 a 最小只能是 13,最大就是 50+13=63。
最后给出产生 13~63 范围内随机数的完整代码:
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- int main(){
- int a;
- srand((unsigned)time(NULL));
- a = rand() % 51 + 13;
- printf("%d\n",a);
- return 0;
- }
连续生成随机数
有时候我们需要一组随机数(多个随机数),该怎么生成呢?很容易想到的一种解决方案是使用循环,每次循环都重新播种,请看下面的代码:
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- int main() {
- int a, i;
- //使用for循环生成10个随机数
- for (i = 0; i < 10; i++) {
- srand((unsigned)time(NULL));
- a = rand();
- printf("%d ", a);
- }
- return 0;
- }
运行结果举例:
8 8 8 8 8 8 8 8 8 8
运行结果非常奇怪,每次循环我们都重新播种了呀,为什么生成的随机数都一样呢?
这是因为,for 循环运行速度非常快,在一秒之内就运行完成了,而 time() 函数得到的时间只能精确到秒,所以每次循环得到的时间都是一样的,这样一来,种子也就是一样的,随机数也就一样了。
C语言:随机数的更多相关文章
- 【C】漫谈C语言随机数
来说说C语言如何产生随机数. 有人会说这不简单?time() + srand() + rand() 3个函数不就OK了吗? 是的,不过,我们还是来看看原理比较好,也就是随机数是如何产生的. 这不无聊. ...
- C语言-随机数
C语言使用rand()函数产生随机数, 使用rand()函数之前要先使用srand(time(0)), 以当前时间作为种子, 否则产生的随机数将不会变化. #include <stdio.h&g ...
- 洗牌算法Fisher-Yates以及C语言随机数的产生
前些天在蘑菇街的面试中碰到一道洗牌的算法题,拿出来和大家分享一下! 原题是:54张有序的牌,如何无序的发给3个人? 这个题是运用经典的洗牌算法完成.首先介绍一种经典的洗牌算法--Fisher-Yate ...
- D语言-随机数游戏
由于不会D语言的随机数,干脆core.stdc.stdlib调用stdlib.h 这里mark一下,类型转换是cast(D语言类型) NULL不能用,要用null import std.stdio; ...
- 抽签小程序(C语言随机数)
最近班级里需要人员抽签参加活动,闲来无事用java的(Math.random()方法||java.util.Random())写了一个随机抽签的,所以我又了解了一下C语言的随机数获取. C语言的随机数 ...
- (转)c语言随机数srandom( )
转自:http://zhidao.baidu.com/question/334364810.html调用随机数函数 rand()() 的时候, 实际得到的这个随机数并不是绝对随机的,它是以一个初始值, ...
- c语言随机数
写得我自己都看不好了:大家都比较喜欢吃快餐,只需要尽快告诉读者怎么用起来就行了.不想听啰啰嗦嗦说一堆,然后例程还特别麻烦 so: 1.基本 int seed = time(0);//#include ...
- C语言随机数使用方法
随机数在编程中还是有所应用,最近从网上学习到这方面一点知识,想把它写下来.一.使用随机数所需要的头文件和函数: 头文件:cstdlib(C++ 的 standard libraray) ...
- c 语言 随机数选取6个数 一定范围内
种子来源 定时器/****************** 自动筛选种子 dat 目标种子 ************/ #define max 7 //随机生成最大的数为7 #define min 1 / ...
- Go 语言控制台输入&生成随机数
Go 语言控制台输入&生成随机数 1. 不同基础类型之间的转化对于不同的基础类型之间的转化,Go 提供了 strconv包.它实现了字符串与其他基本数据类型之间的转化.其中最常用的数值转化函数 ...
随机推荐
- mybatis的多参数传递,使用
1.mybatis的多参数使用 mapper 使用 通过@param注解,传递到xml中的参数名称指定 public interface RedisInstanceTypesMapper extend ...
- CUDA运行时 Runtime(四)
CUDA运行时 Runtime(四) 一. 图 图为CUDA中的工作提交提供了一种新的模型.图是一系列操作,如内核启动,由依赖项连接,依赖项与执行分开定义.这允许定义一次图形,然后重复启动.将 ...
- git stash的常用操作
列出stash的: git stash list移除stash: git stash drop stash@{0}查看stash: git stash sho ...
- Xshell6会话管理器无意中关闭,在哪里打开
一.进入查看 二.勾选则弹出,然后双击窗口即可
- 使用有道云笔记还是github写笔记的优缺点对比
有道云笔记的优点 在手机上编辑笔记,有道云的体验更好,建议:新建普通类型笔记而不是markdown笔记,因为md在手机上的编辑体验并不好 插入图片方便无需考虑图床 可以把笔记分享到社交平台(QQ,微信 ...
- 你应该这样去开发接口:Java多线程并行计算
所谓的高并发除了在架构上的高屋建瓴,还得需要开发人员在具体业务开发中注重自己的每一行代码.每一个细节,面子有的同时,更重要的还是要有里子. 面对性能,我们一定要有自己的工匠精神,不可以对任何一行代码妥 ...
- mybatis自定义打印执行时间并格式化sql插件
打印SQL的执行时间,我们可以实现mybatis官方我们提供的接口org.apache.ibatis.plugin.Interceptor,我们可以拦截的类有多个Executor,StatementH ...
- leetcode5698.基本计算器
给你一个整数数组 nums ,和两个整数 limit 与 goal .数组 nums 有一条重要属性:abs(nums[i]) <= limit . 返回使数组元素总和等于 goal 所需要向数 ...
- centos7安装JDK、CentOS
1.安装JDK 1.1查看系统是否已有自带的JDK rpm -qa |grep java rpm -qa |grep jdk rpm -qa |grep gcj 1.2卸载已有安装 如果没有输出信息, ...
- 自动按需引入组件用不了(Vant)
按照官网的自动按需引入之后,这样写是报错的,直接在vue页面中这样引用也是报错的. 正确的使用方法是这样的