C语言中rand函数如何正确使用?

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

核心要点

  1. rand() 的作用:生成一个伪随机整数。
  2. 伪随机:这意味着数字看起来是随机的,但实际上是由一个确定的算法生成的,只要起始点(种子)相同,生成的序列就是相同的。
  3. 需要包含的头文件<stdlib.h>
  4. 函数原型int rand(void);
  5. 返回值范围0RAND_MAX 之间的整数。RAND_MAX 也是一个在 <stdlib.h> 中定义的宏,它的值通常是 32767 (即 INT_MAX)。

基本用法

生成一个随机数

最简单的用法就是直接调用 rand() 函数。

c语言中rand函数怎么用
(图片来源网络,侵删)
#include <stdio.h>
#include <stdlib.h> // 必须包含这个头文件
int main() {
    int random_number = rand(); // 生成一个随机数
    printf("生成的随机数是: %d\n", random_number);
    printf("RAND_MAX 的值是: %d\n", RAND_MAX);
    return 0;
}

⚠️ 重要问题:运行上面的代码,你会发现每次运行程序,输出的随机数都是一样的!

生成的随机数是: 41
RAND_MAX 的值是: 32767

再次运行:

生成的随机数是: 41
RAND_MAX 的值是: 32767

这是因为 rand() 函数需要一个“种子”来启动它的随机序列,如果种子不变,序列就不变,默认情况下,种子是固定的(通常是1)。


设置随机种子 (使用 srand())

为了解决上面的问题,我们需要在调用 rand() 之前使用 srand() 函数来设置种子。

c语言中rand函数怎么用
(图片来源网络,侵删)
  • 头文件<stdlib.h>
  • 函数原型void srand(unsigned int seed);
  • 作用:为 rand() 函数设置一个新的起始点(种子)。

最佳实践:使用当前时间作为种子

最常用的方法是使用当前时间作为种子,因为时间每时每刻都在变化,这样就能保证每次运行程序时种子都不同。

在 C 语言中,我们可以用 <time.h> 头文件中的 time() 函数来获取当前时间。

#include <stdio.h>
#include <stdlib.h> // rand, srand
#include <time.h>   // time
int main() {
    // 1. 使用当前时间作为随机种子
    // time(NULL) 返回自1970年1月1日以来的秒数
    // (unsigned int) 是为了类型匹配,因为 srand 接受 unsigned int
    srand((unsigned int)time(NULL));
    // 2. 现在调用 rand() 就会生成不同的随机数
    int random_number = rand();
    printf("生成的随机数是: %d\n", random_number);
    return 0;
}

每次运行程序,你都会得到不同的结果:

c语言中rand函数怎么用
(图片来源网络,侵删)
生成的随机数是: 16807

再次运行:

生成的随机数是: 25812

⚠️ 常见错误:

不要在循环里每次都调用 srand() 这是一个新手常犯的错误,如果在循环里重复设置种子,而两次调用的时间戳可能非常接近(比如在同一毫秒内),那么种子可能是一样的,导致你得到一串“伪随机”的相同数字。

// 错误示范!
for (int i = 0; i < 10; i++) {
    srand((unsigned int)time(NULL)); // 错误!每次循环都重置种子
    printf("%d ", rand());
}

正确做法: 只需要在程序开始调用一次 srand() 即可。


生成特定范围的随机数

rand() 生成的是 0RAND_MAX 的数,但通常我们需要的是特定范围的,1100,或者 50200

方法:使用取模运算符 和偏移量

公式为: a + rand() % b

  • a 是范围的下限(包含)。
  • b 是范围的长度(上限 - 下限 + 1)。

示例1:生成 1 到 100 的随机数

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
    srand((unsigned int)time(NULL));
    // 生成 1 到 100 的随机数
    // 范围长度 = 100 - 1 + 1 = 100
    int number = 1 + rand() % 100;
    printf("1到100之间的随机数是: %d\n", number);
    return 0;
}

示例2:生成 50 到 200 的随机数

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
    srand((unsigned int)time(NULL));
    // 生成 50 到 200 的随机数
    // 下限 a = 50
    // 范围长度 b = 200 - 50 + 1 = 151
    int number = 50 + rand() % 151;
    printf("50到200之间的随机数是: %d\n", number);
    return 0;
}

⚠️ 关于取模运算的注意事项

使用 rand() % N 会导致一个常见的分布不均问题。RAND_MAX 不是 N 的整数倍,那么前面的几个数字(0 到 RAND_MAX % N - 1)出现的概率会比其他数字稍高。

RAND_MAX 是 32767,你想生成 1 到 10 的数 (rand() % 10),因为 32767 不是 10 的整数倍(32767 / 10 = 3276 余 7),所以数字 0, 1, 2, 3, 4, 5, 6 出现的概率会比 7, 8, 9 稍微高一点。

对于大多数普通应用(如游戏、简单模拟),这个微小的偏差可以忽略不计,但如果需要高质量的、均匀分布的随机数,应该使用更高级的方法,比如下面要说的 rand() / RAND_MAX 的方法。


生成浮点数随机数 (0.0 到 1.0)

要生成浮点数随机数,可以利用 rand() 返回的整数和 RAND_MAX

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <float.h> // 为了 DBL_EPSILON,不过这里不是必须的
int main() {
    srand((unsigned int)time(NULL));
    // 将 rand() 的结果转换成 double,然后除以 RAND_MAX
    // 这样得到的结果在 [0.0, 1.0] 区间内
    double random_double = (double)rand() / RAND_MAX;
    printf("0.0到1.0之间的随机浮点数是: %f\n", random_double);
    // 生成 a 到 b 之间的随机浮点数
    double a = 2.5;
    double b = 5.5;
    double random_range = a + (double)rand() / RAND_MAX * (b - a);
    printf("%.2f到%.2f之间的随机浮点数是: %f\n", a, b, random_range);
    return 0;
}

这个方法比取模运算更能保证浮点数分布的均匀性。


完整示例代码

下面是一个综合示例,展示了如何生成不同类型的随机数。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <limits.h>
void generate_random_numbers() {
    // 1. 生成一个简单的随机整数
    int simple_random = rand();
    printf("一个简单的随机整数: %d\n", simple_random);
    // 2. 生成 1 到 10 的随机整数
    int dice_roll = 1 + rand() % 10;
    printf("掷骰子结果 (1-10): %d\n", dice_roll);
    // 3. 生成 100 到 200 的随机整数
    int range_random = 100 + rand() % 101; // 200 - 100 + 1 = 101
    printf("100到200之间的随机数: %d\n", range_random);
    // 4. 生成 0.0 到 1.0 的随机浮点数
    double unit_random = (double)rand() / RAND_MAX;
    printf("0.0到1.0之间的随机浮点数: %f\n", unit_random);
    // 5. 生成 -10.0 到 10.0 的随机浮点数
    double range_float = -10.0 + (double)rand() / RAND_MAX * 20.0; // 10 - (-10) = 20
    printf("-10.0到10.0之间的随机浮点数: %f\n", range_float);
}
int main() {
    // 只需要设置一次种子
    // 使用当前时间作为种子,确保每次运行结果不同
    srand((unsigned int)time(NULL));
    printf("--- 生成一组随机数 ---\n");
    generate_random_numbers();
    printf("\n--- 再生成一组 ---\n");
    generate_random_numbers();
    return 0;
}
任务 代码 说明
包含头文件 #include <stdlib.h> rand()srand() 所需
设置种子 srand((unsigned int)time(NULL)); 程序开始时调用一次,确保随机性
生成随机整数 rand() 生成 0RAND_MAX 的整数
生成 [a, b] 范围的整数 a + rand() % (b - a + 1) 最常用的方法,注意分布不均问题
生成 [0.0, 1.0] 的浮点数 (double)rand() / RAND_MAX 高质量的均匀分布
生成 [a, b] 范围的浮点数 a + (double)rand() / RAND_MAX * (b - a) 推荐的浮点数生成方法

希望这个详细的解释能帮助你完全理解 C 语言中 rand() 函数的用法!

-- 展开阅读全文 --
头像
Linux下C语言小游戏如何实现?
« 上一篇 03-04
dede音乐播放器插件如何安装使用?
下一篇 » 03-04

相关文章

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

目录[+]