Случайные числа в C

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

person Sergey Gavruk    schedule 15.03.2010    source источник
comment
Ваш первый вызов calloc должен быть sizeof(int *), но вы, похоже, работаете на хосте, где простые указатели и целые числа имеют одинаковый размер (это верно для большинства архитектур).   -  person mpez0    schedule 16.03.2010
comment
По сути, вы отредактировали свой вопрос сразу после того, как были даны ответы, прямо таким образом, что эти ответы больше не соответствуют вопросу и таким образом были признаны недействительными. Пожалуйста, не делайте этого.   -  person Aconcagua    schedule 18.10.2018


Ответы (10)


Вызов srand() вне цикла. Вы повторно заполняете его каждую итерацию.

srand() запускает генератор случайных чисел, поэтому вы получаете различную последовательность случайных чисел в зависимости от ввода. Ваш цикл выполняется очень быстро, поэтому вызов time(NULL) всегда возвращает одно и то же значение. Вы сбрасываете одну и ту же случайную последовательность с каждой итерацией. Как правило, вызовите srand() только один раз в своей программе.

person Byron Whitlock    schedule 15.03.2010
comment
Согласитесь, вам (как правило) не нужно запускать генератор случайных чисел более одного раза. - person bta; 15.03.2010
comment
@bta: правда, вам не нужно заполнять rand() более одного раза. Другое дело — повторное заполнение генераторов случайных чисел, под которыми я подразумеваю все, что используется для обеспечения безопасности. - person Steve Jessop; 15.03.2010

Не вызывайте srand() каждый раз в цикле — просто сделайте это один раз заранее.

person Carl Norum    schedule 15.03.2010

Часто задаваемые вопросы от 13.15 до 13.20 будет представлять интерес. И у меня возникает соблазн создать новый тег для таких вопросов.

person dirkgently    schedule 15.03.2010
comment
Может быть, создать один вопрос под названием «Как srand() влияет на состояние генератора случайных чисел?» и отмечать его как дубликат каждый раз, когда появляется другое тонкое изменение ;-) - person Steve Jessop; 15.03.2010
comment
Да, CW-версия. Но тогда мы будем дублировать все comp.lang.*.faqs, не так ли? - person dirkgently; 15.03.2010
comment
Да, но SO неизбежно будет содержать множество дубликатов часто задаваемых вопросов (по определению F), поэтому будет дублировать comp.lang.*.faq, что бы вы ни делали. Если только вопросы не будут безжалостно помечены как дубликаты, то, даже если они немного изменят тему, они в конечном итоге будут содержать меньше информации, чем существующий FAQ (при условии, что FAQ хорошо освещает это). Версия часто задаваемых вопросов CW, которая также имеет F на SO, может быть помечена как таковая и содержать ссылку на часто задаваемые вопросы по языку и любые другие соответствующие ресурсы, а также может формулировать вопрос в наиболее общем виде, чтобы гарантировать, что они поймают больше всего дубликатов. Или что-то. - person Steve Jessop; 15.03.2010
comment
Что-то я тоже задумался. Переместить это обсуждение в мета? - person dirkgently; 15.03.2010

srand — это функция, которая «заполняет» генератор случайных чисел. Если вы не знаете, случайные числа в компьютерах на самом деле не случайны. По сути, у компьютера просто есть список чисел, которые кажутся случайными, и вы используете srand, чтобы сообщить ему, с чего начать в этом списке, при этом каждый вызов rand() возвращает следующий элемент в списке.

Причина, по которой вы пишете srand(time(NULL)), заключается в том, чтобы случайные числа начинались в какой-то момент, который не будет одинаковым при каждом запуске программы (если только программы не запускаются в одно и то же время).

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

person Peter Alexander    schedule 15.03.2010

альтернативный текст

person Community    schedule 16.03.2010

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 один раз вне цикла.

person JonH    schedule 15.03.2010

Вам нужно вызвать srand() перед входом в цикл. srand() инициализирует генератор случайных чисел с заданным начальным числом и генерирует уникальную последовательность случайных чисел для этого начального числа.

Ваш цикл выполняется очень быстро, поэтому каждый вызов time(NULL) дает одно и то же время (измеряемое в секундах), поэтому вы инициализируете генератор случайных чисел одним и тем же начальным числом на каждой итерации цикла.

person pajton    schedule 15.03.2010

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

Независимо от того. Номер тот же...

person Sergey Gavruk    schedule 15.03.2010
comment
Что это за синтаксис a[i,j]? Вероятно, вы хотите a[i][j], хотя вы должны получить ошибку компилятора, если только j не является простым массивом, а не двумерным массивом, как я уверен, вы намереваетесь. - person indiv; 15.03.2010

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

Вот мой массив...

person Sergey Gavruk    schedule 15.03.2010
comment
Во-первых, вы должны отредактировать свой пост, чтобы добавить эту новую информацию. Этот сайт не работает как форум. Во-вторых, я поддерживаю свое утверждение о том, что ваш синтаксис двумерного массива неверен, и вы должны делать a[i][j] при доступе к элементу. Вот руководство по работе с многомерными массивами: functionx.com/cpp/Lesson12.htm - person indiv; 15.03.2010

Сергей, вы не получили сообщение об ошибке с версией a[i,j] просто потому, что это совершенно правильное выражение. Оператор запятой оценивает подвыражения слева направо и возвращает значение последнего выражения. Таким образом, запись a[i,j] идентична записи a[j]. То, что вы получили в печати, было значением указателя на j-й вектор в вашей матрице.

person ysap    schedule 16.03.2010