1. 소개
프로그래밍에서 난수는 다양한 목적에 사용되며 특히 C 언어에서 널리 활용됩니다. 난수는 게임 시나리오 생성, 무작위 샘플링, 데이터 섞기 등 여러 상황에서 중요한 개념입니다. 이 글에서는 C에서 난수를 생성하는 방법을 자세히 설명하고 실제로 어떻게 활용할 수 있는지 예시를 제공합니다. C에서 난수 생성 방식을 이해하면 이를 효과적으로 적용할 수 있는 능력을 넓힐 수 있습니다.
2. 난수란 무엇인가?
난수와 의사난수의 개념
난수는 예측할 수 없으며 주어진 범위 내에서 임의로 생성되는 값을 말합니다. 하지만 컴퓨터가 생성하는 난수는 실제로 “의사난수(pseudorandom number)”라고 부릅니다. 이는 일정한 규칙에 따라 만들어지기 때문에 진정한 무작위가 아니기 때문입니다. 의사난수는 알고리즘에 의해 생성되므로 같은 시드값(초기값)을 사용하면 동일한 수열이 반복됩니다.
3. C에서 난수 생성하기
C 표준 라이브러리는 난수를 생성하기 위한 함수를 제공합니다. 여기서는 가장 많이 사용되는 rand() 함수, RAND_MAX 상수, 그리고 시드값을 설정하는 srand() 함수에 초점을 맞춥니다.
rand() 함수의 기본
rand() 함수는 C에서 난수를 생성하는 기본 함수입니다. 0부터 RAND_MAX 사이의 정수를 반환합니다. RAND_MAX 값은 라이브러리에서 정의된 상수이며 시스템이나 환경에 따라 다르지만 일반적으로 32767입니다.
#include <stdio.h>
#include <stdlib.h>
int main() {
int random_number = rand();
printf("Random number: %dn", random_number);
return 0;
}
위 코드에서 rand() 함수는 0부터 32767 사이의 난수를 생성하고 이를 출력합니다.
srand() 로 시드값 설정하기
rand() 함수는 시드값에 따라 숫자를 생성하므로 기본적으로 프로그램을 실행할 때마다 같은 수열을 반환합니다. 이를 방지하려면 srand() 함수를 사용해 시드값을 설정하면 서로 다른 수열을 만들 수 있습니다. 흔히 현재 시간을 시드값으로 사용합니다.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
srand((unsigned int) time(NULL)); // Initialize seed with current time
int random_number = rand();
printf("Random number: %dn", random_number);
return 0;
}
이 예제에서는 time(NULL) 로 현재 시간을 가져와 시드값으로 설정합니다. 따라서 프로그램을 실행할 때마다 다른 난수 수열이 생성됩니다.
특정 범위 내에서 난수 생성하기
예를 들어 1부터 10까지의 범위에서 난수를 만들고 싶다면 rand() 함수를 다음과 같이 사용합니다.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
srand((unsigned int) time(NULL));
int min = 1;
int max = 10;
int random_number = min + rand() % (max - min + 1);
printf("Random number between %d and %d: %dn", min, max, random_number);
return 0;
}
이 코드는 1부터 10 사이의 난수를 생성합니다. rand() % (max - min + 1) 식은 결과가 지정한 범위 안에 들어가도록 보장합니다.

4. 난수의 실용적인 활용
다음은 난수를 실제로 활용하는 몇 가지 예시입니다.
주사위 시뮬레이션
1부터 6까지의 난수를 생성하여 주사위 굴리기를 시뮬레이션할 수 있습니다.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
srand((unsigned int) time(NULL));
int dice_roll = 1 + rand() % 6;
printf("Dice roll: %dn", dice_roll);
return 0;
}
이 프로그램은 1부터 6 사이의 숫자를 무작위로 출력하여 주사위 굴림을 모방합니다.
배열 섞기
배열의 요소들을 무작위로 교환하여 섞을 수 있습니다.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void shuffle(int *array, int size) {
for (int i = 0; i < size; i++) {
int j = rand() % size;
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
int main() {
srand((unsigned int) time(NULL));
int array[] = {1, 2, 3, 4, 5, 6};
int size = sizeof(array) / sizeof(array[0]);
shuffle(array, size);
printf("Shuffled array: ");
for (int i = 0; i < size; i++) {
printf("%d ", array[i]);
}
printf("n");
return 0;
}
이 코드는 배열의 요소들을 무작위로 교환하여 섞습니다.
게임 개발에서 난수 사용
게임 개발에서는 적 스폰 위치를 결정하거나 아이템을 생성하는 등 다양한 작업에 난수를 사용합니다. 난수를 활용하면 게임에 예측 불가능성을 추가할 수 있어 플레이어에게 보다 현실감 있는 경험을 제공할 수 있습니다.
5. 난수 생성 시 유의할 점
rand() 함수의 한계
rand()는 기본적인 난수 생성에는 충분하지만, 유한한 주기를 갖는 의사난수를 생성합니다. 대량의 난수를 생성할 경우 주기적인 패턴이 나타날 수 있어 완전한 무작위성이 요구되는 상황에는 부적합합니다.
멀티스레드 환경에서의 문제
멀티스레드 환경에서 rand()를 사용하면 여러 스레드가 동일한 시드 값을 공유하게 되어 동일한 난수를 생성할 위험이 있습니다. 이를 방지하려면 각 스레드가 고유한 시드 값을 사용해야 합니다.
고품질 난수 생성기 사용
C++ 및 기타 언어에서는 보다 고품질의 난수 생성기를 제공합니다. C에서는 선택지가 제한적이지만, random() 함수나 메르센 트위스터(mt19937)와 같은 고급 알고리즘을 사용하는 것이 권장됩니다.
6. 결론
이 글에서는 C에서 난수를 생성하는 방법을 설명하고 실제 코드 예시와 실용적인 활용 사례를 제시했습니다. rand() 함수는 기본 프로그램에 매우 유용하지만, 진정한 무작위성이 필요할 때는 주의가 필요합니다.


