[MFC] rand_s 的用法

大家都知道如何用 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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值