Указатель NULL
- это тот, который указывает на никуда. Когда вы разыскиваете указатель p
, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p
является нулевым указателем, местоположение, хранящееся в p
, является nowhere
, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception
.
В общем, это потому, что что-то не было правильно инициализировано.
Здесь есть пара проблем, связанных с тем, как работает оператор по модулю. a % b
фактически дает вам остаток, когда вы делите a на b. Итак, давайте предположим, что мы вычисляем числа по модулю 4. Давайте также предположим, что RAND_MAX = 6, потому что я действительно не хочу иметь 32768+ строк в моей таблице.
a | a % 4
------------
0 | 0
1 | 1
2 | 2
3 | 3
4 | 0
5 | 1
6 | 2
Итак, если вы используете свой подход для генерации случайных чисел от 1 до 4, у вас есть две проблемы. Во-первых, простой: вы генерируете числа от 0 до 3, а не от 1 до 4. Результат оператора по модулю всегда будет между 0 и модулем.
Другая проблема более тонкая. Если RAND_MAX не делится равномерно на модуль, вы не получите одинаковую вероятность каждого числа. В нашем примере есть 2 способа сделать 0-2, но только 3. Таким образом, 3 будет происходить в ~ 14,3% времени, а каждое другое число будет происходить в ~ 28,6% времени. Чтобы получить равномерное распределение, вам нужно найти способ справиться со случаями, когда RAND_MAX не делится равномерно.
Вы можете найти соответствующий код на SO. Например, приведенный ниже код rand_int()
основан на коде для целых чисел в ответе на . Верна ли эта реализация на С тасования Фишера-Йейтса? (и, в частности, ответ от [ 116] Роланд Иллиг ):
static size_t rand_int(size_t n)
{
size_t limit = RAND_MAX - RAND_MAX % n;
size_t rnd;
while ((rnd = rand()) >= limit)
;
return rnd % n;
}
Идея состоит в том, что вы вычисляете и игнорируете большие значения, возвращаемые rand()
, которые приведут к смещенным результатам. Когда возвращается одно из больших значений, вы игнорируете его и пробуете следующее значение. Для этого редко потребуется более двух звонков на rand()
.
Вы также можете найти некоторые внешние ссылки в массиве Shuffle в C .