C语言中的随机数生成

13
for(i = 0; i < n; i++){
        srand(time(NULL));
        printf("%d ", time(NULL));
        for(j = 0; j < (n-1); j++){
            a[i][j] = rand();
        }
    }
我尝试生成随机数,但它们都是一样的... 我尝试使用 srand(i * time(NULL))。不管怎样... 我该怎么办?
数组声明:
int** a;
int i;
printf("Enter array size: ");
scanf("%d", &n);

a = (int**)calloc(n, sizeof(int));
for(i = 0; i < n; i++)
    a[i] = (int*)calloc(n-1, sizeof(int));

2
你的第一个 calloc 调用应该是 sizeof(int *),但你似乎在一个简单指针和整数大小相同的主机上工作(这对大多数架构都是正确的)。 - mpez0
你在回答被给出后基本上修改了你的问题,这样一来这些答案就不再符合问题的要求,从而失去了有效性。请不要这样做。 - Aconcagua
10个回答

21

在循环外调用srand()。你每次迭代都会重新播种。

srand()播种随机数生成器,因此您根据输入得到不同的随机数序列。循环运行非常快,因此对time(NULL)的调用始终返回相同的值。您每次迭代都重置为相同的随机序列。通常情况下,在程序中只调用一次srand()


同意,通常情况下您不需要多次初始化随机数生成器。 - bta
@bta:确实,你不应该需要多次使用rand()进行种子生成。重新对“适当”的随机数生成器进行种子生成是另一回事,我指的是任何用于安全目的的生成器。 - Steve Jessop

6
不要在每次循环中调用srand() - 在循环之前只需执行一次即可。

4

常见问题解答 13.1513.20 将会引起兴趣。我有意创建一个新的标签来回答这些问题。


也许可以创建一个名为“srand()如何影响随机数生成器状态?”的单个问题,并在出现其他微妙变化时将其标记为重复;-) - Steve Jessop
是的,有一个 CW 版本。但那样我们就会重复所有 comp.lang.*.faqs,不是吗? - dirkgently
1
是的,但是SO不可避免地会包含无数个FAQ的重复(根据F的定义),所以无论你做什么,都会重复comp.lang.*.faq。除非问题被无情地标记为重复,即使它们在主题上有所变化,它们最终也会比现有的FAQ提供更少的信息(假设FAQ很好地涵盖了它)。那些在SO上也是F的CW版本的FAQ可以被标记为这样,并链接到语言FAQ和任何其他相关资源,并且可以用最通用的方式来表达问题,以确保它们捕获最多的重复。或者其他方法。 - Steve Jessop
我也一直在思考这个问题。我们把这个讨论移到元数据区吧? - dirkgently

3

srand是一种“种子”随机数生成器的函数。如果您不知道,在计算机中产生的随机数并不是真正的随机数。实际上,计算机只有一个看似随机的数字列表,并且您使用srand告诉它在该列表中从哪里开始,每次调用rand()返回列表中的下一个项目。

srand(time(NULL))的原因是为了让随机数以某个不同于每次运行程序时相同的点开始(除非程序同时启动)。

所以你在这里做的就是反复告诉程序在相同的点重新开始随机数列表(因为每次循环时间都相同)。将srand调用移到循环外部,您将获得正确的结果。


3

alt text


2
srand(time(NULL)); 

for(i = 0; i < n; i++){         
        printf("%d ", time(NULL)); 
        for(j = 0; j < (n-1); j++){ 
            a[i,j] = rand(); 
        } 
    } 

在循环外调用srand函数一次。


1

在进入循环之前,您需要调用srand()函数。 srand()函数使用给定的种子初始化随机数生成器,并为该种子生成唯一的随机数序列。

由于您的循环执行非常快,因此每次调用time(NULL)函数都会产生相同的时间(以秒为单位),因此您在每个循环迭代中都使用相同的种子初始化随机数生成器。


0
srand(time(NULL));
for(i = 0; i < n; i++){
    for(j = 0; j < (n-1); j++){
        a[i,j] = rand();
    }
}

不要紧。数字是相同的...


这个 a[i,j] 语法是什么?你可能想要 a[i][j],尽管除非 j 是一个普通数组而不是像你打算的二维数组,否则你应该会得到编译器错误。 - indiv

0
int** a;
int i;
printf("Enter array size: ");
scanf("%d", &n);
if( n < 1 ){
    printf("Size should be > 0\n\n");
    return NULL;
}
a = (int**)calloc(n, sizeof(int));
for(i = 0; i < n; i++)
    a[i] = (int*)calloc(n-1, sizeof(int));

这是我的数组...


1
首先,您应该编辑您的帖子以添加这个新信息。这个网站不像一个论坛。其次,我坚持我的观点,认为您的二维数组语法是错误的,当访问一个项目时,您应该使用a[i][j]。这里有一个多维数组教程:http://www.functionx.com/cpp/Lesson12.htm - indiv

0
Sergey,你使用a[i,j]版本并没有出现错误信息,这是因为这是一个完全有效的表达式。逗号运算符从左到右评估子表达式并返回最后一个表达式的值。因此,写a[i,j]a[j]相同。在打印中收到的是指向矩阵中第j个向量的指针的值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接