C Random Numbers
Games, quizzes and simulations need numbers that look random. C's standard library makes them with rand from stdlib.h.
rand and srand
rand() returns a number from 0 to RAND_MAX (at least 32767). The numbers come from a formula that starts from a seed. With the same seed, the same sequence appears every time. srand(seed) sets the seed; seeding with the current time gives a different sequence on each run.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
srand((unsigned)time(NULL)); // once, at the start
for (int i = 0; i < 5; i++) {
printf("%d ", rand());
}
printf("\n");
return 0;
}Call srand once at the start of the program, not before every rand(): seeding again within the same second would repeat the same number.
A number in a range
rand() % n gives a number from 0 to n−1. Add the lowest value to shift the range: a dice roll from 1 to 6 is rand() % 6 + 1.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int rollDice(void) {
return rand() % 6 + 1;
}
int main(void) {
srand((unsigned)time(NULL));
int counts[7] = {0};
for (int i = 0; i < 6000; i++) {
counts[rollDice()]++;
}
for (int face = 1; face <= 6; face++) {
printf("%d: %d times\n", face, counts[face]);
}
return 0;
}Each face comes up about 1000 times. For a decimal between 0 and 1, use rand() / (RAND_MAX + 1.0).
The same sequence for testing
While testing a program, a fixed seed makes the "random" numbers repeat exactly, so a bug can be reproduced. Here the seed is 42, so this program prints the same result every time:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
srand(42);
int a = rand() % 100, b = rand() % 100;
srand(42);
int c = rand() % 100, d = rand() % 100;
printf("%s\n", (a == c && b == d) ? "same numbers again" : "different");
return 0;
}same numbers again
Shuffling
To shuffle an array fairly, go from the last element down and swap each one with a randomly chosen element at or before it (the Fisher–Yates shuffle):
for (int i = n - 1; i > 0; i--) {
int j = rand() % (i + 1);
int t = a[i]; a[i] = a[j]; a[j] = t;
}rand is fine for games and exercises, but not for passwords or security: its numbers can be predicted.
Practice exercises
- Write a number guessing game: the program picks 1 to 100, the user guesses, and the program says higher or lower.
- Simulate 10000 coin tosses and print how many were heads.
- Shuffle the numbers 1 to 10 with the Fisher–Yates loop and print them.