프로그램을 구현하다 보면 난수(Random Number)를 발생시켜야 하는 경우가 종종 있다. 여기서 말하는 난수란 임의의, 정해지지 않은, 무엇이 될지 모르는 수를 의미하는 것으로 무작위로 값을 생성해야 함을 의미한다.
ANSI표준에서는 이렇게난수를 생성할 때 사용할 수 있는 함수 rand를 제공하고 있다.
다음 예에서는 rand 함수의 사용 방법과 난수의 범위를 보여준다.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i;
printf("난수의 범위 : 0부터 %d까지\n", RAND_MAX);
for(i = 0; i < 5; i++)
printf("난수 출력 : %d \n", rand() );
return 0;
}
#include <stdlib.h>
int main(void)
{
int i;
printf("난수의 범위 : 0부터 %d까지\n", RAND_MAX);
for(i = 0; i < 5; i++)
printf("난수 출력 : %d \n", rand() );
return 0;
}
위의 예제를 여러 번 돌려보면 한가지 특징을 발견할 수 있다. 그것은 발생하는 난수가 규칙적이라는 것이다.
예를 들어서 처음 실행했을 때 생성된 난수가 21, 1, 43, 13, 2라면 다시 실행해 봐도 생성되는 난수는 21, 1, 43, 13, 2가 생성된다는 것이다. 이는 분명히 문제다! 왜냐하면 진짜로 난수가 생성되는 것이 아니기 때문이다. 따라서 rand 함수를 가리켜 의사 난수(pseudo-random number)를 생성하는 함수라고 하는 것이다. 의사 난수라는 뜻은 가짜 난수를 의미한다.
물론 여기에는 대안이 있다. srand함수를 사용하는 것이다.
#include <stdlib.h>
void srand( unsigned int seed );
void srand( unsigned int seed );
함수 srand는 하나의 인자를 전달받는다. 이 인자를 가리켜 씨드(seed) 값이라 한다. 씨드란 씨앗이라는 뜻이다. 즉 난수 생성을 위해 씨앗을 심는 용도로 사용되는 함수이다. "콩 심은 데 콩 나고, 팥 심은 데 팥 난다."는 속담이 있듯이 씨드 값이 무엇이냐에 따라서 rand 함수 호출 시 생성되는 난수들은 달라지기 마련이다.
다음 예제는 씨드값을 입력 받아서 srand 함수를 호출하는 예제이다.
#include < stdio.h >
#include < stdlib.h >
int main(void)
{
int seed, i;
printf("씨드 값 입력: ");
scanf("%d", &seed);
srand(seed); //씨앗을 심는다.
for( i = 0; i < 5 ; i++)
printf("정수 출력: %d \n", rand()); //열매를 수화ㅏㄱ한다.
return 0;
}
#include < stdlib.h >
int main(void)
{
int seed, i;
printf("씨드 값 입력: ");
scanf("%d", &seed);
srand(seed); //씨앗을 심는다.
for( i = 0; i < 5 ; i++)
printf("정수 출력: %d \n", rand()); //열매를 수화ㅏㄱ한다.
return 0;
}
srand 함수도 공부했으니 이제 진정한 난수를 발생시킬 수 있겠는가?
아니다!! 여전히 문제는 있다. 위 예제처럼 프로그램을 실행할 때마다 씨드 값을 입력받을 수는 없는 노릇 아닌가? 설사 입력받는다 해도 매번 다른 값을 입력받는다는 가정을 세우는 것도 무리가 있다. 한가지 방법은 있다. 시스템의 시간을 이용하는 것이다. 현재 여러분 컴퓨터의 시간 값을 얻어와서 srand 함수의 인자로 전달할 수만 있다면 문제는 해결이 된다. 왜냐하면 컴퓨터의 시간은 계속해서 변하기 때문이다.
그렇다면 컴퓨터의 현재 시간을 어떻게 얻어와야 할까? 헤더파일 time.h 에 선언되어 있는 time이라는 이름의 함수를 사용하면 된다. 이 함수는 컴퓨터의 현재 시간과 1970년 1월 일 이후의 시간적 차를 초 단위로 계산하여 반환해 준다(굉장하지 않은가?) 우리는 정확한 시간을 얻겠다는 것이 아니고, 프로그램 실행시 마다 변경되는 값을 얻겠다는 것이므로, 이 정도면 충분하다.
지금까지 이야기한 내용을 종합하여 진정한 난수를 발생시키는 예를 제시하겠다. 실행해 보면 매번 출력되는 난수의 값이 다르다는 것을 알 수 있을 것이다.
#include < stdio.h >
#include < stdlib.h >
#include < time.h >
int main(void)
{
int i;
srand( (int) time (NULL) ); //현재 시간을 이용해서 씨드 설정
for( i = 0; i < 5; i++ )
printf("정수 출력 : %d \n", rand() );
return 0;
}
#include < stdlib.h >
#include < time.h >
int main(void)
{
int i;
srand( (int) time (NULL) ); //현재 시간을 이용해서 씨드 설정
for( i = 0; i < 5; i++ )
printf("정수 출력 : %d \n", rand() );
return 0;
}
출처 : C프로그래밍 _ 윤성우 저
'Language > C언어' 카테고리의 다른 글
문자열 배열 (0) | 2011.02.26 |
---|---|
메모리 동적 할당 _ 1] malloc 함수 - free 함수 - calloc 함수 (0) | 2010.09.28 |
C 언어의 메모리 구조 (0) | 2010.09.27 |
[포인터] 함수 포인터 배열 (0) | 2010.09.03 |
[포인터] 함수 인자에서 포인터 사용 : 값에 의한 호출과 주소에 의한 호출 (0) | 2010.09.03 |