본문 바로가기
프로그래머의 길/C & C++

rand() ,srand() 역활 (C에서 random 함수 사용)

by 제이콥케이 2007. 2. 27.
반응형
int num = 0;
srand(time(NULL));
num = rand() % 10;
 
Q.1  srand() 함수와 rand() 함수가 어떤 역활을 하는지 알고 싶습니다.
Q.2  num = rand() % 10; 가 무슨 뜻인지도 알려 주세요.

[A]

우선 stdlib.h를 include를 해줘야 한다.

 

time undefined warning이 뜬다면 <time.h>도 포함해주면 된다.



난수라는 것은, 알 수 없는 수입니다.
즉, 사람의 개입 없이, 어떤 숫자를 하나 취하고 싶을 때 사용하는 것이 난수입니다.

그런데 C언어에서의 난수는 사실상 난수가 아닙니다.
C언어에는 여러개의 난수표가 존재하며,
이 하나하나의 난수표에는 임의의 숫자들이 아무런 상관관계 없이 나열되어 있죠.
C언어에서의 난수란, 이 난수표 중 하나에서 순서대로 숫자를 하나씩 꺼내는 작업을 말합니다.
순서대로 숫자를 꺼내는 것이지만, 그 숫자들이 아무런 관계가 없이 나열되어 있기 때문에
사람들이 볼 때는 난수처럼 보이는 것이죠.

그런데 만약, 프로그램이 실행될 때마다 동일한 난수표에서 난수를 뽑아낸다면 어떻게 될까요?
프로그램이 실행될 때마다 동일한 숫자들이 나타날 것입니다.
따라서, 매번 실행할 때마다 다른 난수표를 선택해야 하겠죠.

여기서 난수표를 seed라고 부릅니다.
어떤 난수표에서 숫자를 하나씩 꺼내는 함수가 rand()입니다.
그리고 C언어에 내장되어 있는 여러개의 난수표 중에서 하나를 선택하는 함수가 srand()입니다.

매번 실행할 때마다 다른 난수표를 사용하기 위해서 srand()를 먼저 호출하게 되는데요,
이때 srand()의 인자로 어떤 숫자를 넘겨줘야 합니다.
이 숫자가 난수표 번호에 해당하는데요,
매번 다른 난수표 번호를 지정하기 위해서 보통 time()이라는 함수를 사용합니다.
time()은 현재 시간이죠.
매번 실행할 때마다 시간이 다를 것이므로,
srand(time(NULL))은 매번 다른 난수표(seed)를 선택하게 됩니다.
그 다음 rand()를 호출하게 되면 그 난수표에서 하나씩 난수를 꺼내어 리턴해주는 것이죠.

rand()를 사용해서 꺼내지는 난수들은 범위가 있습니다.
0 ~ RAND_MAX라는 범위의 숫자들이 리턴되죠.
RAND_MAX의 값은 0x7fff입니다.
10진수로 하면 32767이죠.
따라서 rand()가 리턴하는 값은 0 ~ 32767 사이의 숫자입니다.

그런데 우리가 필요한 것이 0 ~ 9까지의 숫자라면 어떻게 해야 할까요?
rand()가 0 ~ 9까지의 난수만 리턴하도록 설정하면 좋을 것입니다.
하지만 앞에서 말한 것처럼, 이미 난수란 것은 입력된 값입니다.
정해져 있다는 것이죠.

따라서 rand()에게 0 ~ 9까지의 숫자만 리턴하라도 설정할 수 없습니다.
그렇기 때문에 우리는, rand()가 리턴하는 0 ~ 32767까지의 숫자를,
다시 0 ~ 9까지의 숫자로 변환해서 써야 합니다.
그러기 위해서 %연산자를 쓰게 됩니다.
%연산자는 나눗셈의 나머지를 취하는 연산자이죠.
우리가 어떤 수를 X라는 값으로 나누게 되면,
그 나머지는 항상 0 ~ X - 1의 수가 되죠?
예를 들어서 어떤 수를 10으로 나누면, 어떤 수를 나누던간에, 그 나머지는 항상 0 ~ 9까지의 숫자가 됩니다.
이 원리를 이용해서 0 ~ 32767까지의 숫자를 0 ~ X - 1까지의 범위로 바꿀 수 있는 것입니다.
위의 코드에서 rand() % 10을 한 것은,
0 ~ 32767까지의 난수를 0 ~ 9까지의 숫자로 변환하기 위한 코드입니다.

그런데 우리가 필요한 것이, 임의의 주사위 숫자처럼, 0부터 시작하는 것이 아니라 1부터 시작한다면 어떻게 해야 할까요?
rand % 6 + 1 을 해야 합니다.
나머지 연산자는 항상 0을 포함한 범위만 가능하기 때문에,
1을 더해줘야 하는 것이죠.
1을 더할 것이기 때문에 나눗셈을 할 숫자도 7이 아니라 6로 해야 합니다.
7로 나누게 되면 0 ~ 6까지의 숫자가 나타나게 되고,
1을 더하면 1 ~ 7까지의 숫자가 나타나게 되죠.
7은 주사위에 없죠.

따라서 6으로 나누고, 그 나머지 0 ~ 5에다가 1을 더해서
1 ~ 6사이의 숫자가 되도록 변환하는 것입니다.

반응형



정리!!

우선 stdlib.h를 include를 해줘야 한다.
time undefined warning이 뜬다면 <time.h>도 포함해주면 된다.


rand() -> 랜덤함수, 그러나 항상 랜덤값의 순서가 같다. 그래서,
srand(int) -> 랜덤값 순서 변경함수를 이용해서

srand((unsigned)time(NULL));
이렇게 한후
rand();
하면 완벽한 랜덤값이 된다..

참고:srand는 한번만 하세요..


반응형

'프로그래머의 길 > C & C++' 카테고리의 다른 글

고수준 파일 입출력 함수 정리  (0) 2007.03.07
문자열 조작 함수  (0) 2007.03.06
printf() 출력 형식 지정자  (0) 2007.02.15
아스키 코드표  (0) 2007.02.15
SI 단위  (0) 2007.02.12