언어/C언어

[C언어] 난수생성 rand, srand, time 함수 설명과 사용방법 예제

REAKWON 2019. 1. 25. 04:32

우리는 난수를 사용하고 싶을 때가 있습니다. 하지만 이런 기능을 만드는 것은 좀처럼 쉬운 일은 아니지요. 귀찮기도 하구요.

C언어에서는 그러한 프로그래머를 위해서 난수생성함수를 제공하고 있습니다. 바로 rand라는 함수이지요. 외우기도 쉽네요. rand(om)으로 기억하면 되니까요.

 

rand

rand함수를 사용하기 위해서는 stdlib.h 헤더파일을 include해야합니다. rand함수는 0부터 RAND_MAX까지 범위까지 난수를 생성합니다. 함수 원형을 같이보시죠.

#include <stdlib.h>

int rand(void);

보시는 바와 같이 rand함수는 int형을 반환하게 됩니다. 아하, 그러면 rand함수를 쓰게 되면 랜덤인 정수형이 나오겠구나. 알 수 있죠?

이제 이 함수를 이용해서 1부터 100까지 정수 중 10개의 수를 랜덤하게 뽑아내는 프로그램을 짜보도록 하지요.

#include <stdio.h>
#include <stdlib.h> 

int main() { 
        int i; 
        for (i = 1; i <= 10; i++) 
                printf("%d ", (rand() % 100) + 1); 
        printf("\n");
}
이제 결과를 보도록 할까요??
 
42 68 35 1 70 25 79 59 63 65

 

 

오 랜덤하게 실행이 되는 군요. 100가지의 숫자 중 랜덤한 10개의 숫자를 뽑아냈습니다.

저는 신기해서 한번 더 실행해보겠습니다.

 

42 68 35 1 70 25 79 59 63 65

????

프로그램을 실행할때마다 바뀌지 않는데요? 우리는 이런 랜덤한 값을 원한게 아닙니다. 우리는 프로그램을 실행할때마다 랜덤하게 10개의 수를 출력하는 프로그램을 원하는 건데요. 지금 출력된 것은 단지 일정한 숫자 배열을 출력한 것과 같다고 느껴집니다.

왜 C언어는 우리에게 이런 사기를 치는 것일까요?

 

srand

사실 rand함수는 srand함수에 의존적입니다. srand의 s는 seed라는 뜻으로 이 seed값에 따라 rand의 값이 바뀌게 됩니다. srand는 rand함수와 같이 stdlib.h 헤더파일에 존재합니다.

만일 이 함수를 호출하지 않고 rand함수를 호출한다면 srand(1)을 호출하고 rand함수를 호출한 효과와 같습니다.

함수의 원형은 다음과 같은데요.

#include <stdlib.h>

void srand(unsigned int seed);

양의 정수만 seed로 사용할 수 있습니다. 그렇다면 우리가 srand의 seed값을 2로 주면 위의 결과와 다를까요?

위의 코드에서 for로프 위에 srand(2)를 추가해보세요.

46 17 99 96 85 51 91 32 6 17

 

아까와는 다른 결과를 볼 수 있군요. srand에서 seed를 바꿔서 실행시켜보세요. 나오는 값이 계속 달라짐을 알 수 있습니다. seed값만 바꿔주면 그 seed값에 따라 값을 랜덤하게 뽑아 올 수 있군요.

 

하지만 이것 마저도 아직 우리를 만족시킬 수가 없습니다. 이렇게 되면 프로그램을 실행시킬때마다 seed값을 바꾸고 다시 컴파일하는 과정을 거쳐야하기 때문이죠. 우리는 이런 허접한 코드는 쓰지 말도록 합시다.

 

우리는 이것보다 더 잘할 수 있습니다. 잘 할 수 있고 말고요. 한번 생각해봅시다. 프로그램 실행시 계속 바뀌는 값은 뭐가 있을까요?

주소값? (사실 제가 랜덤함수를 구현한다고 생각해볼때 고려해봤던 것 중 하나입니다.)

바로 시간입니다. 시간은 지금 이 순간에도 항상 바뀌고 있지요. 그래서 소개할 다음 함수가 time이라는 함수입니다.

time

time함수는 이름 그대로 시간에 대한 정보를 얻어오는 함수랍니다. 우선 time함수를 사용하기 위해서는 time.h라는 헤더파일을 include해야하지요.

함수의 원형을 한번 살펴볼까요?

#include <time.h>

time_t time(time_t *tloc);

 

이 함수는 1970년 1월 1일 0시 (UTC)부터 현재까지 흐른 시간을 반환합니다. 반환은 하지만 그 시간이 초단위입니다. 만일 우리가 현재까지 흐른 시간을 구하려면 만약 timeptr에 NULL을 전달하고 반환값을 받거나, 아니면 timeptr에 인자를 전달해서 현재까지 흐른 시간을 초단위로 받을 수 있습니다.

이제 아주 기본적인 사용법을 알게 됐으니 코드로 구현하도록 해봅시다. 

 

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

int main() { 
        int i; 
        srand(time(NULL));

        for (i = 1; i <= 10; i++)  
                printf("%d ", (rand() % 100) + 1);
        printf("\n");
}

 

단지 srand의 인자를 time(NULL)로 바꾼거 밖에 없습니다. time(NULL)을 호출하면 1970/1/1 0시부터 현재(프로그램 실행 시)까지 흐른 시간을 return한다고 했지요? 그러니 이 프로그램을 실행할때마다 srand의 seed값이 바뀌게 되는 겁니다.

이제 확인을 해봅시다.

첫번째 실행

79 61 20 69 3 67 82 24 63 35

두번째 실행

44 53 56 15 86 98 95 14 15 46

어떻습니까? 이제 이 프로그램을 여러번 실행해도 값이 다르게 나온다는 것을 알 수 있습니다.

 

그렇다면 우리가 랜덤한 값을 얻고자 할때는 rand, srand, time함수를 전부 다 써야하나요?

네, 이 세가지 함수들은 묶어서 기억하셔야합니다. 사용법은 어렵지 안잖아요 그쵸??

 

이상으로 여기까지 C언어에서 난수를 생성하는 쉬운 방법을 알아보았습니다.

반응형