C语言rand函数如何生成随机数?

99ANYc3cd6
预计阅读时长 17 分钟
位置: 首页 C语言 正文

第一部分:理解 rand() 函数

rand() 是 C 标准库 <stdlib.h> 中的一个函数,用于生成一个伪随机整数。

c语言randcomputer
(图片来源网络,侵删)

基本用法

rand() 函数不接受任何参数,它返回一个 int 类型的值,这个值的范围通常是 0 到 RAND_MAX 之间

RAND_MAX 是在 <stdlib.h> 中定义的一个宏,它代表了 rand() 函数能返回的最大值,在不同的系统中,RAND_MAX 的值可能不同,但至少是 32767。

最简单的例子:

#include <stdio.h>
#include <stdlib.h> // 包含 rand() 和 RAND_MAX
int main() {
    // 生成并打印一个随机数
    int random_number = rand();
    printf("一个随机数: %d\n", random_number);
    // 打印 RAND_MAX 的值
    printf("RAND_MAX 的值是: %d\n", RAND_MAX);
    return 0;
}

问题: 如果你运行上面的代码几次,你会发现它每次输出的“随机数”都是一样的! 这是因为 rand() 使用一个种子来生成序列,如果种子不变,序列就不变。

c语言randcomputer
(图片来源网络,侵删)

设置随机种子:srand()

为了让 rand() 每次运行程序时都产生不同的序列,我们需要在调用 rand() 之前,用 srand() 函数来设置一个不同的种子。

srand(seed) 函数接受一个 unsigned int 类型的参数作为种子。

如何获得一个变化的种子? 最好的方法是使用当前的时间,因为时间总是在变化的,C 标准库 <time.h> 中的 time(NULL) 函数可以返回自某个固定时间点(称为“纪元”)以来的秒数。

正确的用法:

c语言randcomputer
(图片来源网络,侵删)
#include <stdio.h>
#include <stdlib.h> // rand(), srand(), RAND_MAX
#include <time.h>   // time()
int main() {
    // 1. 设置随机种子
    // 只需要在程序开始时设置一次即可
    // time(NULL) 返回当前时间,将其作为种子
    srand(time(NULL));
    // 2. 生成随机数
    int random_number = rand();
    printf("使用时间种子后的随机数: %d\n", random_number);
    return 0;
}

每次运行这个程序,你都会得到不同的随机数。


第二部分:生成特定范围的随机数

rand() 生成的是 0 到 RAND_MAX 的数,但我们通常需要的是特定范围的,1 到 100。

生成 [0, N-1] 范围内的随机数

使用取模运算符 。

// 生成一个 0 到 99 之间的随机数
int number = rand() % 100;

原理: rand() % N 的结果总是在 0N-1 之间。

生成 [1, N] 范围内的随机数

[0, N-1] 的基础上加 1。

// 生成一个 1 到 100 之间的随机数
int number = (rand() % 100) + 1;

生成 [M, N] 范围内的随机数

通用公式:rand() % (N - M + 1) + M

解释:

  • N - M + 1 计算出这个范围的总数(10 到 20,总数是 11)。
  • rand() % (N - M + 1) 生成 [0, 总数-1] 的数。
  • + M 将这个范围平移到 [M, N]

例子:生成 50 到 100 之间的随机数

int min = 50;
int max = 100;
int range = max - min + 1; // 100 - 50 + 1 = 51
int number = (rand() % range) + min; // 结果在 0~50 之间,加上 50 后就是 50~100

第三部分:实践案例 - “猜数字”游戏

这个案例完美地诠释了如何让“计算机”来生成一个数字,然后让用户来猜,这里的“计算机”就是我们的随机数生成器。

游戏规则:

  1. 计算机随机生成一个 1 到 100 之间的整数。
  2. 用户输入一个猜测的数字。
  3. 计算机告诉用户是“猜大了”、“猜小了”还是“猜对了”。
  4. 如果猜错,继续猜测,直到猜对为止。

完整代码:

#include <stdio.h>
#include <stdlib.h> // rand(), srand()
#include <time.h>   // time()
int main() {
    int secret_number, guess, attempts = 0;
    // 1. 计算机生成秘密数字
    // 设置随机种子,确保每次游戏数字都不同
    srand(time(NULL)); 
    // 生成 1 到 100 之间的随机数
    secret_number = (rand() % 100) + 1;
    printf("欢迎来到猜数字游戏!\n");
    printf("我已经想好了一个 1 到 100 之间的整数,\n");
    // 2. 循环,让用户进行猜测
    do {
        printf("请输入你的猜测: ");
        scanf("%d", &guess);
        attempts++; // 增加猜测次数
        if (guess > secret_number) {
            printf("猜大了!\n");
        } else if (guess < secret_number) {
            printf("猜小了!\n");
        } else {
            printf("恭喜你!猜对了!\n");
            printf("你总共猜了 %d 次,\n", attempts);
        }
    } while (guess != secret_number); // 直到猜对才退出循环
    return 0;
}

代码解析:

  • srand(time(NULL));:这是游戏的关键,它确保了计算机每次“想”的数字都是不同的。
  • secret_number = (rand() % 100) + 1;:这就是计算机的核心,它生成了 1 到 100 的随机数。
  • do-while 循环:让用户可以一直猜,直到猜对为止。
  • scanf("%d", &guess);:获取用户的输入。
  • if-else if-else 结构:计算机根据用户的猜测给出反馈。

第四部分:进阶 - 提升随机数质量

rand() 函数生成的随机数在统计上可能不够“随机”,对于一些简单的游戏或程序来说足够了,但对于科学计算、密码学等需要高质量随机数的场景,它就不够用了。

更好的随机数生成器:C++11 <random> (C语言中不常用)

如果你使用的是 C++,强烈推荐使用 <random> 库中的 std::mt19937 等现代随机数引擎,它们产生的随机数质量远高于 rand()

C11 标准中的 rand_r()

在 C11 标准中,引入了 rand_r(),它是一个可重入的版本,比 rand() 更安全,可以在多线程环境中使用,它需要一个指向种子的指针。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
    unsigned int seed = time(NULL);
    // rand_r 接受一个指向种子的指针
    printf("使用 rand_r 生成的随机数: %d\n", rand_r(&seed));
    return 0;
}

函数/概念 作用 头文件 示例
rand() 生成一个伪随机整数 <stdlib.h> int r = rand();
RAND_MAX rand() 能返回的最大值 <stdlib.h> printf("%d", RAND_MAX);
srand(seed) 设置 rand() 的随机种子 <stdlib.h> srand(time(NULL));
time(NULL) 获取当前时间,常用于 srand 的种子 <time.h> srand(time(NULL));
rand() % N 生成 [0, N-1] 范围的随机数 <stdlib.h> int dice = rand() % 6; // 0-5
(rand() % N) + 1 生成 [1, N] 范围的随机数 <stdlib.h> int num = (rand() % 100) + 1; // 1-100

核心要点:

  1. 必须用 srand(time(NULL)) 来初始化随机种子,否则每次运行结果都一样。
  2. 只在程序开始时调用一次 srand()
  3. 使用 取模 加减法 来控制随机数的范围。
  4. “计算机”生成随机数的过程,就是调用 rand() 函数并根据需求处理其返回值的过程。
-- 展开阅读全文 --
头像
织梦search.php漏洞如何修复?
« 上一篇 01-03
宝宝泡育儿dede5.31模板
下一篇 » 01-03

相关文章

取消
微信二维码
支付宝二维码

目录[+]