I understand that rand() function generates the same number(s) each you run it if you don\'t change the seed number. That\'s where srand() comes in. Time is always changing
You don't see a link because (luckily!) whoever designed rand() decided to keep that an implementation detail, in the same way as you don't see what's inside a FILE from stdio; the downside is that they decided to make that state a global (but hidden) variable rather than a parameter to the generator.
Contrast that to the deprecated rand_r(): the state is an unsigned integer (assumed to be >= 32 bits), which means that even it's forbidden to use any better generator whose state is greater than that, simply because there is no room to store it!
By keeping the internal state hidden, instead, one is free to pick whatever algorithm works best (speed, period, ...) and use it behind the scenes, as long as you guarantee that calling rand without initialization is the same as calling srand with seed==1.
Paxdiablo showed you the example from the C standard; see eg http://en.wikipedia.org/wiki/Multiply-with-carry for an example using a different generator that you could hide behind rand/srand.
Just to be extra-extra clear: had rand_r been designed properly, there would be an opaque type, say rand_t (which could be an integer, a structure, an array, ...), which you would pass to rand_r and to some hypotetical srand_r, as in
rand_t state;
srand_r(&state, 1);
n = rand_r(&state);
The rand function is exactly like this, except that there's only one state variable.