【问题标题】:Generate random integer within a range (Infinite loop)生成范围内的随机整数(无限循环)
【发布时间】:2013-05-27 17:45:53
【问题描述】:

我遇到了这段代码的问题,因为当我运行它时,我得到一个带有数字随机生成器的无限循环。我要做的是分配一个数组,从 1 到 9 的 99 个数字,然后进行一些简单的数学运算。

#include <stdio.h>
#include <stdlib.h>
#define SIZE 99
void mean(const int a[]);
void median( int a[]);
void mode(int freq[] , const int a[]);

int main (void) {
   int response[SIZE];
   int frequency [10];
   int i;
   srand(time(NULL));
   for (i = 0; i<= SIZE ; i++) {
      response[i] = (rand() % 6) +1 ;
      printf("%d", response[i]);
   }
   mean(response);
   median( response);
   mode(frequency , response);

return 0;
}


void mean(const int a[]){
   int j , total = 0;
   float mean;
   printf("********\n%6s\n********\n\nThe mean is the average value of the data\nitems.", "Mean");
   printf("The mean is equal to the total of\n all the data items");
   printf("divided by the number\n of data items (%d):", SIZE);
   for( j = 0 ; j <= SIZE ; j++){
      total += a[j];
   }
   mean = (float) total / SIZE;
   printf("The mean value for\nthis run is %d / %d = %f", total, SIZE, mean);
}

void median( int a[]){
   int i, j, n, median, hold;
   n=1;
   hold = 0;
   printf("********\n%7s\n********\n\nThe unsorted array of responses is\n", "Median");
   for (i=0;i<=SIZE;i++){
      if ((i/10) <= n){
         printf("%d", a[i]);
      }
      else{
         printf("\n");
         n++;
      }
   }
   printf("The sorted array is\n");
   for(i=0;i<=SIZE;i++){
      for(j=0;j<=SIZE-1;j++){
         if (a[j]>a[(j+1)]){
            hold = a[j];
            a[j] = a[ (j + 1)];
            a[ (j + 1)] = hold;
         }
      }
   if ((i/10) <= n){
         printf("%d", a[i]);
      }
      else{
         printf("\n");
         n++;
      }
   }
   median = a[SIZE/2];
   printf("The median is element %d of\nthe stored %d element array.\n", SIZE/2 , SIZE);
   printf("For this run the median is %d", median);
}

void mode ( int freq [] , const int a[]){
   int j, o, mode , i, rating;
   printf("********\n%6s\n********\n\n%10s%12s%12s", "Mode" ,"Response" ,"Frequency", "Histogram");
   for(j=0; j<= SIZE ; j++){
      ++freq[a[j]];
   }
   for (i=0 ; i <= 10 ; i++){
      printf("%10d%12d            ", i, freq[i]);
      for (o=0; o<=freq[i];o++){
         printf("*");
      }
      printf("\n");
      if (freq[i] > freq[i+1]){
         mode = freq[i];
         rating = i;
      }
   }
   printf("The mode is the most frequent value.\n");
   printf("For this run the mode is %d which occured %d times", rating ,mode);
}

【问题讨论】:

  • 当你想要一个介于 1 和 9 之间的数字时,为什么要 rand() % 6。它应该是 rand() % 9 + 1...
  • 提防modulo bias
  • frequency 数组应该是 mode 函数的本地数组。您不会在其他任何地方使用它。在 main 中声明它并将其传递给 mode 是没有意义的。相反,将其声明为 mode 的本地。
  • 顺便说一句,你忘了#include &lt;time.h&gt; for time()。

标签: c loops random


【解决方案1】:

C 数组是从零开始的,因此有效的索引

int response[SIZE];

是 [0..SIZE-1]。您的循环写入response[SIZE],这超出了分配给response 的内存末尾。这会导致未定义的行为。

如果您遇到无限循环,听起来好像response[SIZE] 的地址与循环计数器i 的地址相同。 (rand() % 6) +1 将在 [1..6] 范围内,因此退出前循环的最终迭代将始终将 i 重置为较低的值。

您可以通过更改循环以更快地退出一次迭代来解决此问题。即改变

for (i = 0; i<= SIZE ; i++) {

for (i = 0; i< SIZE ; i++) {

请注意,您的其他功能都有类似的错误。所有for 循环都应将其&lt;= 退出条件替换为&lt;

【讨论】:

  • 那为什么会导致无限循环呢?
  • @ShuklaSannidhya 我已经更新了我的答案。如果现在更清楚,请告诉我。
【解决方案2】:

当您访问 array[SIZE] 时,您会写超出数组的末尾。 任何声明的数组

type_t array[SIZE];

没有元素array[SIZE]。所以所有循环必须从 0 到 SIZE,而不是 SIZE。 这在计算机文献中被称为off-by-one error。你不是第一个也不会是最后一个,如果有什么安慰的话:-)

从技术上讲,这会调用未定义的行为,其中一种方法是无限循环。但是,请参阅下面的评论,对这里真正发生的事情进行疯狂的猜测。

【讨论】:

  • 有什么原因导致无限循环。?
  • 很可能是因为在某些函数(mean()、median()、mode())中,您将a[] 作为最后一个参数,第一个声明的局部变量是循环变量ij。写过去 a[] 会破坏循环变量。
  • 这不是唯一的问题。即使一个接一个地修复也不会停止无限循环。代码有很多问题。
  • @KingsIndian 它在这里不再是无限的,但会打印 6406162 个星号,所以是的,至少还有一个错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-24
  • 2014-08-11
  • 1970-01-01
  • 2010-09-22
相关资源
最近更新 更多