大家都知道如何用 C++ <stdlib.h> 中的 rand 配合随机数种子来生成伪随机数。本文介绍另一种不需要每次通过系统时间来设置伪随机序列起始位置的方法(仅仅针对 Window XP 以及之后的操作系统),那就是使用同样在 <stdlib.h> 中的 rand_s 函数。
有的人说,一看这个函数的名字就知道了,不就是带 CRT 安全增强版的 rand 函数嘛!的确,这个函数是附带 CRT 安全增强的,不过和其它带 CRT 安全增强的函数有所不同——即便你在程序中仍然使用 rand ,编译器也不会有安全警告,因为在 XP 之前的操作系统只能用 rand() 函数。这主要是因为 rand_s 使用的是操作系统来生成加密安全的伪随机数,而不是像 rand 那样使用 srand 生成的种子。所以,使用 rand_s 生成随机数的话就不需要每次都去调用 srand 了。
现在来看看这个函数的声明:
errno_t rand_s( unsigned int* randomValue );
函数的参数是一个整型的指针,指向一个用于接收随机数的整数类型。啥?为啥不直接返回随机数?我个人的猜测是因为 rand_s 直接把这个指针传递给了操作系统用于生成随机数的 API 函数 RtlGenRandom (大家知道 API 函数都是用缓冲区来接收数据),算是写代码的人偷了一个懒吧!
函数成功的话,返回值是 0;否则的话返回错误代码。
生成的随机数范围是 0-UINT_MAX。
而最重要的是:
如果想使用这个函数,必须在 <stdlib.h> 这个头文件被包含之前定义一个宏:_CRT_RAND_S,也就是如下:
#define _CRT_RAND_S
#include <stdio.h>
如果没有这样做,在编译的时候就会提示找不到 rand_s 这个标识符!
这也就衍生了一个比较容易被忽略的问题,而这个问题在 MSDN 中并没有提示——
如果你的程序包含了一个“包含 <stdlib.h> 的头文件”,那么即便你在之后写上面那两行也是没用的,因为在宏被定义前 <stdlib.h> 就已经被包含了。这个问题最有可能在使用了预编译头的 MFC 程序中出现——很多人没有意识到 MFC 的那两个头文件(<afxwin.h>、<afxext.h>)已经包含了 <stdlib.h>,所以在预编译头后面写上这两句是没有作用的。正确的做法应该是在 MFC 的头文件被包含之前(预编译头中)定义 _CRT_RAND_S 这个宏。
下面就用这个函数来实现一个在 min-max 范围中(不包括 max)生成随机数的过程:
unsigned randInt(int min, int max)
{
unsigned u;
rand_s(&u);
return (unsigned)((double)u / ((__int64)UINT_MAX + 1) * (max - min) + min);
}
基本上和以前用 rand 的算法相同,只不过这次 rand_s 生成的数上限是 32 位整数的最大值,想要 + 1 的话只能使用 62 位整数。
以上来自:http://kevin-hust.iteye.com/blog/744284
分享到:
相关推荐
在OPENCV平台下实现车牌识别的一套程序 简单有效 可以试试 用C++写的
基于MFC的打印技术源码,程序基于visual c++ 软件。
兄弟7055_7060D_MFC7360_7470D_7860DN维修手册-ASC.pdf
mfc资源大全包含MFC编程各个方面的源码
mfc控件使用大全,内含详细的使用方法和属性
科学计算器。使用mfc,加减乘以,带括号。绝对值。。以及各种公式运算。。有界面
MFC下的opengl框架。有几篇电子文档。很有参考价值
MFC界面编程很好的例子,十分实用 可以参考的文档。
MFC+SQL的一个车行管理系统,包括用户管理,进货,出售,管理货物等功能
VC++编的诊断软件,含MFC界面编程,能编译运行。
一个VISUALC++MFC的学习文档 包括了各种MFC案例
实现MFC中的自定义地图点绘制,适用于地震传输系统地图
MFC教程_ 内存分配方式和调试机制,一个不错的教程
MFC编程中非常经典的例程,内容详细,简单易懂,是初学者必看的资料。
MFC对话框打开一幅图片并在picture显示和图片保存,完整的教程
用MFC编写的COM程序,包括客户端测试程序。
一个很好的关于MFC的界面编程的小程序哦,欢迎大家下载
MFC简明教程 MFC简明教程
vega的MFC编程。简单示例。方便初学者学习
科室_班级_MFC 科室_班级_MFC 科室_班级_MFC 科室_班级_MFC