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


当前回答

对于c, STL不存在,你必须调用rand,或者更好的是,随机。它们在标准库头文件stdlib.h中声明。rand是POSIX, random是BSD规范函数。

rand和random之间的区别是random返回一个更有用的32位随机数,而rand通常返回一个16位数。BSD手册显示rand的较低位是循环的和可预测的,因此rand对于较小的数字可能是无用的。

其他回答

<stdlib.h>中的rand()函数返回一个介于0和RAND_MAX之间的伪随机整数。你可以使用srand(unsigned int seed)来设置种子。

通常的做法是将%操作符与rand()结合使用以获得不同的范围(但请记住,这在一定程度上破坏了一致性)。例如:

/* random int between 0 and 19 */
int r = rand() % 20;

如果你真的在乎一致性,你可以这样做:

/* Returns an integer in the range [0, n).
 *
 * Uses rand(), and so is affected-by/affects the same seed.
 */
int randint(int n) {
  if ((n - 1) == RAND_MAX) {
    return rand();
  } else {
    // Supporting larger values for n would requires an even more
    // elaborate implementation that combines multiple calls to rand()
    assert (n <= RAND_MAX)

    // Chop off all of the values that would cause skew...
    int end = RAND_MAX / n; // truncate skew
    assert (end > 0);
    end *= n;

    // ... and ignore results from rand() that fall above that limit.
    // (Worst case the loop condition should succeed 50% of the time,
    // so we can expect to bail out of this loop pretty quickly.)
    int r;
    while ((r = rand()) >= end);

    return r % n;
  }
}
#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]);
}

对于Linux C应用程序:

这是我根据上面的答案重新编写的代码,它遵循我的C代码实践并返回任意大小的随机缓冲区(具有适当的返回代码等)。确保在程序开始时调用urandom_open()一次。

int gUrandomFd = -1;

int urandom_open(void)
{
    if (gUrandomFd == -1) {
        gUrandomFd = open("/dev/urandom", O_RDONLY);
    }

    if (gUrandomFd == -1) {
        fprintf(stderr, "Error opening /dev/urandom: errno [%d], strerrer [%s]\n",
                  errno, strerror(errno));
        return -1;
    } else {
        return 0;
    }
}


void urandom_close(void)
{
    close(gUrandomFd);
    gUrandomFd = -1;
}


//
// This link essentially validates the merits of /dev/urandom:
// http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/
//
int getRandomBuffer(uint8_t *buf, int size)
{
    int ret = 0; // Return value

    if (gUrandomFd == -1) {
        fprintf(stderr, "Urandom (/dev/urandom) file not open\n");
        return -1;
    }

    ret = read(gUrandomFd, buf, size);

    if (ret != size) {
        fprintf(stderr, "Only read [%d] bytes, expected [%d]\n",
                 ret, size);
        return -1;
    } else {
        return 0;
    }
}

FWIW,答案是肯定的,有一个stdlib.h函数叫rand;此函数主要针对速度和分布进行调优,而不是针对不可预测性。几乎所有语言和框架的内置随机函数都默认使用这个函数。还有“加密”随机数生成器,它们的可预测性要低得多,但运行速度要慢得多。在任何类型的与安全相关的应用程序中都应该使用它们。

我的极简解决方案应该适用于范围内的随机数[min, max)。在调用函数之前使用srand(time(NULL))。

int range_rand(int min_num, int max_num) {
    if (min_num >= max_num) {
        fprintf(stderr, "min_num is greater or equal than max_num!\n"); 
    }
    return min_num + (rand() % (max_num - min_num));
}