有没有一个函数生成一个随机int数在C?或者我必须使用第三方库?


当前回答

在我最近的应用程序中,我遇到了一个严重的伪随机数生成器问题:我多次通过Python脚本调用我的C程序,并使用以下代码作为种子:

srand(time(NULL))

然而,由于:

Rand将生成相同的伪随机序列,在srand中给出相同的种子(参见man srand); 如前所述,time函数每秒只会变化:如果应用程序在同一秒内运行多次,time每次都会返回相同的值。

我的程序生成了相同的数字序列。 你可以做三件事来解决这个问题:

mix time output with some other information changing on runs (in my application, the output name): srand(time(NULL) | getHashOfString(outputName)) I used djb2 as my hash function. Increase time resolution. On my platform, clock_gettime was available, so I use it: #include<time.h> struct timespec nanos; clock_gettime(CLOCK_MONOTONIC, &nanos) srand(nanos.tv_nsec); Use both methods together: #include<time.h> struct timespec nanos; clock_gettime(CLOCK_MONOTONIC, &nanos) srand(nanos.tv_nsec | getHashOfString(outputName));

选项3确保了你(据我所知)最好的种子随机性,但它可能只会在非常快速的应用中产生差异。 在我看来,选择2是一个安全的赌注。

其他回答

您可以使用悬浮指针的概念。

指向已删除(或释放)内存位置的指针称为悬浮指针。

它将在打印时显示随机值。

如果您需要比stdlib提供的质量更好的伪随机数,请检查Mersenne Twister。它也更快。示例实现有很多,例如这里。

尽管这里所有人都建议使用rand(),但除非迫不得已,否则您不会想要使用rand() !rand()生成的随机数通常非常糟糕。引用Linux手册页:

Linux C库中的rand()和srand()版本使用与random(3)和srandom(3)相同的随机数生成器,因此低阶位应该与高阶位一样随机。但是,在旧的rand()实现上,以及在不同系统上的当前实现上,低阶位比高阶位随机得多。当需要良好的随机性时,不要在旨在可移植的应用程序中使用此函数。(请使用random(3)。)

关于可移植性,random()也由POSIX标准定义了很长一段时间。rand()更老,它已经出现在第一个POSIX.1规范(IEEE Std 1003.1-1988)中,而random()首次出现在POSIX.1-2001 (IEEE Std 1003.1-2001)中,然而当前的POSIX标准已经是POSIX.1-2008 (IEEE Std 1003.1-2008),仅在一年前收到了更新(IEEE Std 1003.1-2008, 2016版)。所以我认为random()是非常可移植的。

POSIX.1-2001还引入了lrand48()和mrand48()函数,参见这里:

此函数族应使用线性同余算法和48位整数算术生成伪随机数。

一个很好的伪随机源是arc4random()函数,它在许多系统上都可用。不是任何官方标准的一部分,在1997年左右出现在BSD中,但你可以在Linux和macOS/iOS等系统上找到它。

#include <stdio.h>
#include <stdlib.h>

void main() 
{
    int visited[100];
    int randValue, a, b, vindex = 0;

    randValue = (rand() % 100) + 1;

    while (vindex < 100) {
        for (b = 0; b < vindex; b++) {
            if (visited[b] == randValue) {
                randValue = (rand() % 100) + 1;
                b = 0;
            }
        }

        visited[vindex++] = randValue;
    }

    for (a = 0; a < 100; a++)
        printf("%d ", visited[a]);
}

您希望使用rand()。注意(非常重要):确保为rand函数设置了种子。如果你不这样做,你的随机数就不是真正的随机。这是非常、非常、非常重要的。值得庆幸的是,您通常可以使用系统滴答计时器和日期的某种组合来获得良好的种子。