Static storage duration variables are initialised before any code starts running and they must be initialised with an expression calculable at compile time.
That means no using variables that can't be determined until run-time to initialise them. If you removed the static
, the error would disappear but then you're going to re-seed the random number generator every time you call it.
You really should initialise the random seed once before asking for the first random number (as in srand()/rand()
from the C standard library), and then use your random function to cycle through the values in the sequence. That could be done with something like:
int rand4 (int numLimit) {
static int randSeed, needsInit = 1;
if (needsInit) { // This bit only done once.
randSeed = time(0);
needsInit = 0;
}
randSeed = (randSeed * 32719 + 3) % 32749;
return (randSeed % numLimit) + 1;
}
A typical implementation of srand()/rand()
is along the lines of:
// RAND_MAX assumed to be 32767.
static unsigned long int next = 1;
void srand(unsigned int seed) { next = seed; }
int rand(void) {
next = next * 1103515245 + 12345;
return (unsigned int)(next/65536) % 32768;
}
in its own source file so that the next
seed is hidden from view. This follows the expected behaviour that calling rand()
without first calling srand()
is the same as if you had called srand (1)
.
And, based on your comment that you need a certain number of calls to generate all the numbers from 1 to 52, it sounds like you're using this to generate a randomised deck of cards. If that's the case, there's a better way to do it than generating a random number and throwing away those you've already seen.
That solution deteriorates quickly as the size of the remaining deck gets smaller and smaller. For an O(1) time and space solution, use the Fisher-Yates shuffle.
The basic algorithm is to use an unsorted list and simply swap the final element with a randomly chosen one, reducing the list size by one:
dim n[N] // gives n[0] through n[N-1]
for each i in 0..N-1: // initialise them to their indexes
n[i] = i // (use i+1 for 1-10 instead of 0-9).
nsize = N // starting pool size
do N times:
i = rnd(nsize) // give a number between 0 and nsize-1
print n[i]
nsize = nsize - 1 // these two lines effectively remove the used number
n[i] = n[nsize]
The numbers generated by that are:
<------ n[] ------>
0 1 2 3 4 5 6 7 8 9 nsize rnd(nsize) output
------------------- ----- ---------- ------
0 1 2 3 4 5 6 7 8 9 10 4 4
0 1 2 3 9 5 6 7 8 9 7 7
0 1 2 3 9 5 6 8 8 2 2
0 1 8 3 9 5 6 7 6 6
0 1 8 3 9 5 6 0 0
5 1 8 3 9 5 2 8
5 1 9 3 4 1 1
5 3 9 3 0 5
9 3 2 1 3
9 1 0 9