Question
Is there a built-in way to generate a random integer in C, or do I need to use a third-party library?
If C provides a standard function for this, how is it typically used to produce integer values, including values within a specific range?
Short Answer
By the end of this page, you will understand how C generates pseudo-random integers using the standard library, how rand() and srand() work together, how to limit values to a range, and what common mistakes to avoid. You will also see when the standard approach is good enough and when stronger randomness is needed.
Concept
C includes a standard library function called rand() for generating pseudo-random integers. It is declared in stdlib.h.
#include <stdlib.h>
rand() does not produce truly random values. It produces a sequence of numbers that looks random, based on an internal starting value called a seed.
To choose that starting point, you usually call srand() once near the beginning of the program:
#include <stdlib.h>
#include <time.h>
srand(time(NULL));
Why this matters:
- If you never call
srand(), many C implementations will produce the same sequence every time your program runs. - If you seed with the current time, the sequence will usually differ from run to run.
- This is useful for games, simulations, simple shuffling, and basic test data.
Important limitation:
rand()is fine for simple use cases.- It is not suitable for security-sensitive tasks like passwords, tokens, or cryptographic keys.
The value returned by rand() is between 0 and RAND_MAX inclusive.
int n = rand();
If you want a number in a smaller range, a common beginner pattern is:
int n = rand() % 10; // 0 to 9
This works for many simple programs, but it can introduce slight bias in some cases because % does not always distribute values perfectly evenly across the target range.
Mental Model
Think of rand() like a machine that spits out numbered tickets.
- The machine always follows a fixed internal pattern.
- The seed is where the machine starts in that pattern.
- If you start from the same seed, you get the same ticket sequence.
- If you start from a different seed, you get a different-looking sequence.
So srand() chooses where to begin, and rand() gives you the next value each time you call it.
A useful way to remember it:
srand(...)= set the starting pointrand()= get the next pseudo-random number
Syntax and Examples
Basic syntax
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
srand(time(NULL));
int value = rand();
printf("Random value: %d\n", value);
return 0;
}
What this does
#include <stdlib.h>gives access torand()andsrand().#include <time.h>gives access totime().srand(time(NULL))seeds the generator once.rand()returns a pseudo-random integer.
Random integer in a range
To get a number from 0 to 9:
int n = rand() % 10;
To get a number from 1 to 10:
int n = (rand() % 10) + 1;
To get a number from min to max inclusive:
int n = (rand() % (max - min + 1)) + min;
Example:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int min = 5;
int max = 12;
srand(time(NULL));
int n = (rand() % (max - min + 1)) + min;
printf("Random number between %d and %d: %d\n", min, max, n);
return 0;
}
This produces one integer from 5 through 12.
Repeating random values
You can call rand() multiple times:
for (int i = 0; i < 5; i++) {
printf("%d\n", rand());
}
Each call returns the next value in the sequence.
Step by Step Execution
Consider this program:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
srand(time(NULL));
int n = (rand() % 6) + 1;
printf("Dice roll: %d\n", n);
return 0;
}
Here is what happens step by step:
-
The program includes the needed headers.
stdio.hforprintf()stdlib.hforrand()andsrand()time.hfortime()
-
srand(time(NULL));runs.time(NULL)returns the current time as a number.- That number is used as the seed.
- This helps produce a different sequence each time the program starts.
-
rand()is called.- Suppose it returns some large integer like
1804289383. - The exact value depends on the implementation and seed.
- Suppose it returns some large integer like
-
% 6is applied.1804289383 % 6gives a result from0to5.
-
+ 1shifts the range.- Now the final result is from
1to6.
- Now the final result is from
-
printf()prints the result.- Example output:
Dice roll: 4
- Example output:
So the expression:
(rand() % 6) + 1
means:
- get a pseudo-random integer
- shrink it into six possible values
- shift those values so they match dice faces
Real World Use Cases
rand() is commonly used in small or non-security-critical programs such as:
- Games: dice rolls, enemy behavior, random loot, spawning positions
- Simulations: coin flips, random events, simple Monte Carlo experiments
- Test data generation: creating sample scores, IDs, or mock sensor values
- Shuffling basic data: randomizing order in simple classroom exercises
- Simple command-line tools: picking a random item from a list
Examples:
- A quiz app picks a random question.
- A board game program simulates rolling two dice.
- A script generates random temperatures between
18and30.
For these uses, pseudo-randomness is usually acceptable.
For security-related tasks, such as:
- password generation
- session tokens
- API keys
- cryptographic secrets
rand() should not be used.
Real Codebase Usage
In real C codebases, developers often use rand() in a few predictable patterns.
Seed once at program startup
A common pattern is to seed the generator once in main():
int main(void) {
srand(time(NULL));
/* rest of program */
}
Calling srand() repeatedly is usually a mistake.
Helper function for a range
Developers often wrap the range logic in a helper function:
int random_in_range(int min, int max) {
return (rand() % (max - min + 1)) + min;
}
This makes code easier to read:
int hp = random_in_range(50, 100);
Validation with guard clauses
In real projects, functions often validate input first:
int random_in_range(int min, int max) {
if (min > max) {
return 0;
}
return (rand() % (max - min + 1)) + min;
}
Controlled seeding for testing
Sometimes developers intentionally use a fixed seed to make results repeatable during testing:
srand(12345);
This is helpful when you want the same sequence every run while debugging.
Better generators for stricter needs
In serious projects, teams may avoid rand() for quality or portability reasons and use platform-specific or library-based alternatives. But for beginner C and many small programs, rand() is the standard starting point.
Common Mistakes
1. Forgetting to include the right headers
Broken code:
int x = rand();
Fix:
#include <stdlib.h>
If you use time(), also include:
#include <time.h>
2. Never calling srand()
Broken idea:
int main(void) {
printf("%d\n", rand());
return 0;
}
This may produce the same sequence each run.
Fix:
srand(time(NULL));
3. Calling srand() every time you need a number
Broken code:
int get_random(void) {
srand(time(NULL));
return rand();
}
Why this is bad:
- If called multiple times within the same second,
time(NULL)may return the same value. - That can reset the generator repeatedly and produce repeated numbers.
Fix: seed once only.
int main(void) {
srand(time(NULL));
printf("%d\n", rand());
printf("%d\n", rand());
}
4. Assuming rand() % n is perfectly uniform
int n = rand() % 10;
This is common and often acceptable for simple programs, but it can introduce bias when RAND_MAX + 1 is not divisible by 10.
For beginner work, this is usually fine. Just know it is not mathematically perfect.
5. Invalid range math
Broken code:
int n = rand() % (max - min) + min;
This excludes max.
Correct inclusive version:
int n = rand() % (max - min + 1) + min;
6. Using rand() for security
Broken idea:
int secret = rand();
Do not use rand() for passwords, secure tokens, or cryptographic values.
Use a secure random source appropriate for your platform instead.
Comparisons
| Concept | What it does | Good for | Not ideal for |
|---|---|---|---|
rand() | Returns a pseudo-random integer from 0 to RAND_MAX | Basic randomness in simple C programs | Security-sensitive tasks |
srand(seed) | Sets the starting seed for rand() | Making sequences vary or repeat intentionally | Generating values by itself |
rand() % n | Shrinks result to 0 through n-1 | Simple ranges for beginner programs | Perfectly uniform distribution |
Fixed seed like srand(1) | Produces the same sequence every run | Testing, debugging, reproducible demos | Real randomness between runs |
Time-based seed like srand(time(NULL)) | Usually changes sequence each run | Games, simulations, CLI tools | High-security randomness |
rand() vs third-party libraries
-
Use
rand()when:- you are learning C
- you need simple pseudo-random integers
- you do not need cryptographic security
-
Use another library or platform API when:
- you need stronger randomness
- you need better statistical quality
- your application is security-sensitive
Cheat Sheet
Quick reference
Include headers
#include <stdlib.h>
#include <time.h>
Seed once
srand(time(NULL));
Get a pseudo-random integer
int x = rand();
- Range:
0toRAND_MAX
Get a number from 0 to n - 1
int x = rand() % n;
Get a number from min to max inclusive
int x = rand() % (max - min + 1) + min;
Repeatable sequence for testing
srand(1234);
Rules to remember
- Call
srand()once, not before everyrand()call. rand()is pseudo-random, not truly random.rand() % nmay introduce slight bias.- Do not use
rand()for security.
Common pattern
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
srand(time(NULL));
int roll = rand() % 6 + 1;
printf("%d\n", roll);
return 0;
}
FAQ
Does C have a built-in function for random integers?
Yes. C provides rand() in stdlib.h for pseudo-random integers.
What is the difference between rand() and srand() in C?
rand() returns the next pseudo-random number. srand() sets the seed that determines the sequence.
Why do I need srand(time(NULL))?
Without seeding, many programs produce the same sequence each run. Using the current time usually changes the sequence.
How do I generate a random number in a specific range in C?
Use:
rand() % (max - min + 1) + min
This gives a value from min to max inclusive.
Is rand() truly random?
No. It is pseudo-random, meaning it follows a deterministic algorithm based on a seed.
Can I use rand() for passwords or tokens?
No. rand() is not secure enough for cryptographic or security-sensitive uses.
Why do I get the same random number repeatedly?
A common reason is reseeding too often with srand(time(NULL)), especially multiple times in the same second. Seed once at startup.
What is RAND_MAX in C?
RAND_MAX is a constant that represents the largest value rand() can return.
Mini Project
Description
Build a small C program that simulates rolling a six-sided die multiple times. This project helps you practice seeding the random number generator once, generating integers in a range, and printing results in a loop. It mirrors a common real use case in games and simple simulations.
Goal
Create a program that rolls a die 10 times and prints each result as a number from 1 to 6.
Requirements
- Include the correct headers for random numbers and time-based seeding.
- Seed the random number generator exactly once.
- Generate values in the inclusive range from 1 to 6.
- Roll the die 10 times using a loop.
- Print each roll on its own line.
Keep learning
Related questions
2D Array Loop Order and Cache Performance in C
Learn why swapping nested loops changes 2D array performance in C, using row-major memory layout, cache locality, and practical benchmarks.
Array-to-Pointer Conversion in C and C++ Explained
Learn what array-to-pointer conversion means in C and C++, how array decay works, and how it differs from a pointer to an array.
Building More Fault-Tolerant Embedded C++ Applications for Radiation-Prone ARM Systems
Learn practical C++ and compile-time techniques to reduce soft-error damage in embedded ARM systems exposed to radiation.