Random C语言是什么?如何入门?

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

这是一个在 C 语言编程中非常常见但又容易引起混淆的函数,我会从以下几个方面为你彻底讲清楚:

randomc语言
(图片来源网络,侵删)
  1. 核心概念:伪随机数
  2. random() 函数详解
  3. 更推荐的标准库函数:rand()srand()
  4. 如何生成指定范围的随机数
  5. 完整代码示例
  6. 总结与最佳实践

核心概念:伪随机数

你需要理解计算机生成的“随机数”并不是真正随机的,它们是通过一个确定的数学算法计算出来的序列,这个序列看起来是随机的,但其实是可预测的,我们称之为 伪随机数

这个算法从一个初始值开始,这个初始值被称为 “种子”,如果每次运行程序时都使用相同的种子,那么生成的伪随机数序列也会是完全相同的。

举个例子: 想象一个食谱(算法),它需要一个“起始食材”(种子),如果你每次都用 1 个鸡蛋作为起始食材,做出来的蛋糕(随机数序列)都会一模一样,只有换一个起始食材(2 个鸡蛋),做出来的蛋糕才会不同。


random() 函数详解

random() 函数是 C 语言的一个函数,但它 不属于标准 C 库,它源自早期的 BSD Unix 系统,因此在很多现代编译器(如 GCC 在 Linux 上)中,你需要包含 <stdlib.h> 并且可能需要额外的编译选项才能使用。

randomc语言
(图片来源网络,侵删)
  • 函数原型:

    long random(void);
  • 功能: 返回一个 long 类型的伪随机整数。

  • 范围: 返回的值范围在不同的系统上可能不同,但通常是 0RAND_MAX 之间。RAND_MAX 是一个在 <stdlib.h> 中定义的宏,它的值至少是 32767 (2^15 - 1)。

  • 关键问题:种子 random() 函数在程序启动时会自动初始化一个默认的种子。这意味着,如果你不手动设置种子,每次运行程序时,它生成的随机数序列都会是相同的!

    randomc语言
    (图片来源网络,侵删)
  • 设置种子:srandom() 为了解决种子问题,random() 函数通常与 srandom() 函数配对使用。

    • 函数原型: void srandom(unsigned int seed);
    • 功能: 用来设置 random() 函数的种子。
    • 最佳实践: 通常使用当前时间作为种子,因为每次运行程序时时间都不同,可以使用 time(0) 函数(需要包含 <time.h>)来获取当前时间。

更推荐的标准库函数:rand()srand()

由于 random() 不是标准 C 函数,为了保证你的代码具有良好的 可移植性(可以在任何支持 C 语言的编译器上编译和运行),强烈推荐使用标准 C 库提供的 rand()srand() 函数。

它们的工作方式与 random()srandom() 完全相同,但它们是 ANSI C 标准的一部分,因此更通用、更安全。

  • 函数原型:

    int rand(void);
    void srand(unsigned int seed);
  • 功能:

    • rand(): 生成一个 int 类型的伪随机整数。
    • srand(): 设置 rand() 函数的种子。
  • 范围: rand() 返回的值在 0RAND_MAX 之间。RAND_MAX 同样在 <stdlib.h> 中定义。

总结对比:

特性 random() / srandom() rand() / srand() 推荐度
标准性 非标准 (源自 BSD) 标准 C (ANSI C) ⭐⭐⭐⭐⭐ (强烈推荐)
可移植性 差,依赖操作系统 极佳,所有编译器都支持 ⭐⭐⭐⭐⭐ (强烈推荐)
返回类型 long int rand() 更常见
配套函数 srandom() srand() 功能相同

如何生成指定范围的随机数

无论是 random() 还是 rand(),它们默认生成的都是 0RAND_MAX 之间的数,我们通常需要的是某个特定范围内的随机数,1 到 100。

常用方法(取模法):

使用取模运算符 可以很方便地实现。

公式: random_number = (rand() % (max - min + 1)) + min;

  • rand() % N 会生成一个 0N-1 之间的数。
  • rand() % (max - min + 1) 会生成一个 0(max - min) 之间的数。
  • + min 将这个范围整体平移,最终得到 minmax 之间的数。

⚠️ 重要提醒:模运算的偏倚问题RAND_MAX 不是 (max - min + 1) 的整数倍时,这种方法会导致结果分布不均匀,如果 RAND_MAX 是 32767,你想生成 1 到 100 的数,1 到 67 出现的概率会比 68 到 100 稍微高一点。

对于大多数非高精度的应用场景,这种偏倚可以忽略不计,如果需要完美的均匀分布,需要更复杂的算法,但 rand() % range 是最简单、最常用的方法。


完整代码示例

下面我们用 标准、推荐的 rand()srand() 来写一个完整的例子。

目标:

  1. 初始化随机数种子(使用当前时间)。
  2. 生成并打印 10 个 1 到 100 范围内的随机整数。
  3. 生成并打印 5 个 0 到 9 范围内的随机整数。
#include <stdio.h>
#include <stdlib.h>  // 包含 rand(), srand(), RAND_MAX
#include <time.h>    // 包含 time()
int main() {
    // 1. 设置随机数种子
    // time(0) 返回自 1970 年 1 月 1 日以来的秒数。
    // 将其作为种子,确保每次运行程序时种子都不同。
    srand((unsigned int)time(0));
    printf("--- 生成 1 到 100 的随机数 ---\n");
    // 2. 生成 10 个 1 到 100 的随机数
    for (int i = 0; i < 10; i++) {
        // 使用公式: (rand() % (max - min + 1)) + min
        int random_num = (rand() % 100) + 1;
        printf("第 %d 个随机数: %d\n", i + 1, random_num);
    }
    printf("\n--- 生成 0 到 9 的随机数 ---\n");
    // 3. 生成 5 个 0 到 9 的随机数
    for (int i = 0; i < 5; i++) {
        // 使用公式: (rand() % (max - min + 1)) + min
        int random_num = (rand() % 10) + 0;
        // 也可以简化为: int random_num = rand() % 10;
        printf("第 %d 个随机数: %d\n", i + 1, random_num);
    }
    return 0;
}

如何编译和运行 (在 Linux/macOS 上使用 GCC):

gcc your_program_name.c -o random_test
./random_test

可能的一次运行结果:

--- 生成 1 到 100 的随机数 ---
第 1 个随机数: 42
第 2 个随机数: 18
第 3 个随机数: 77
第 4 个随机数: 53
第 5 个随机数: 91
第 6 个随机数: 4
第 7 个随机数: 66
第 8 个随机数: 29
第 9 个随机数: 50
第 10 个随机数: 33
--- 生成 0 到 9 的随机数 ---
第 1 个随机数: 7
第 2 个随机数: 0
第 3 个随机数: 9
第 4 个随机数: 2
第 5 个随机数: 5

再次运行,结果会完全不同。


总结与最佳实践

  1. 优先使用标准库:为了代码的可移植性,始终优先使用 rand()srand(),而不是 random()srandom()

  2. 必须设置种子rand() 默认使用固定的种子,导致每次运行结果相同。务必在程序开始时调用 srand((unsigned int)time(0)) 来设置基于时间的种子。

  3. 包含正确的头文件:使用 rand()srand() 时,记得包含 <stdlib.h>;使用 time(0) 时,记得包含 <time.h>

  4. 掌握生成范围的方法:牢记公式 (rand() % (max - min + 1)) + min 来生成指定范围的随机整数。

  5. 了解局限性rand() 生成的随机数质量(随机性)并不高,不适合用于加密、高精度的科学模拟等场景,如果需要高质量的随机数,可以考虑使用 C++ 的 <random> 库或 C11 标准引入的 arc4random 等更高级的随机数生成器,但对于游戏、简单的模拟、抽奖程序等,rand() 完全够用。

-- 展开阅读全文 --
头像
dede标签快速手册
« 上一篇 04-16
数据库上传到织梦要怎么操作?
下一篇 » 04-16

相关文章

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

目录[+]