Генерировать случайное целое число в пределах диапазона (бесконечный цикл)

У меня проблемы с этим кодом, потому что когда я запускаю его, я получаю бесконечный цикл с генератором случайных чисел. Я пытаюсь присвоить массиву 99 чисел от 1 до 9, а затем выполнить некоторые простые математические операции.

#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);
}

person user2425899    schedule 27.05.2013    source источник
comment
Почему rand() % 6, если вам нужно число от 1 до 9. Должно быть rand() % 9 + 1...   -  person ShuklaSannidhya    schedule 27.05.2013
comment
Следите за смещение по модулю.   -  person Carl Norum    schedule 27.05.2013
comment
Массив frequency должен быть локальным для функции mode. Вы не используете его где-либо еще. Нет смысла объявлять его в main и передавать в mode. Вместо этого объявите его локальным для mode.   -  person ShuklaSannidhya    schedule 27.05.2013
comment
Кстати, вы забыли #include <time.h> для time().   -  person Jens    schedule 27.05.2013


Ответы (2)


Массивы 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++) {

to

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

Обратите внимание, что все ваши другие функции имеют аналогичные ошибки. Все for циклы должны заменить свои <= условия выхода на <

person simonc    schedule 27.05.2013
comment
Так почему же это приводит к бесконечному циклу? - person ShuklaSannidhya; 27.05.2013
comment
@ShuklaSannidhya Я обновил свой ответ. Дайте мне знать, если теперь стало понятнее. - person simonc; 27.05.2013

Вы пишете за конец своих массивов при доступе к array[SIZE]. Любой объявленный массив

type_t array[SIZE];

не имеет элемента array[SIZE]. Таким образом, все петли должны быть от 0 до ‹ SIZE, а не ‹= SIZE. В компьютерной литературе это известно как ошибка смещения на единицу. Не ты первый и не последний, если тебя это утешит :-)

Технически это вызывает неопределенное поведение, одним из способов которого является бесконечный цикл. Но посмотрите мой комментарий ниже, чтобы узнать, что здесь происходит на самом деле.

person Jens    schedule 27.05.2013
comment
Любая причина, по которой это приводит к бесконечному циклу? - person ShuklaSannidhya; 27.05.2013
comment
Очень вероятно, потому что в некоторых функциях (mean(), median(), mode()), где у вас есть a[] в качестве последнего аргумента, первая объявленная локальная переменная является переменной цикла i или j. Запись после a[] затем затирает переменную цикла. - person Jens; 27.05.2013
comment
Это не единственная проблема. Даже исправление по одному не остановит бесконечный цикл. В коде много проблем. - person P.P; 27.05.2013
comment
@KingsIndian Здесь он перестает быть бесконечным, но печатает 6406162 звездочки, так что да, есть еще как минимум одна ошибка. - person Jens; 27.05.2013