290 likes | 895 Views
8.12.1 난수 생성 함수 : rand p.356. 난수 (random number) 가 필요한 예 컴퓨터와 사람이 가위바위보 게임을 하는 프로그램 컴퓨터가 무엇을 낼지 ? 주사위를 두 개 던져 나오는 값의 합을 맞추는 게임 프로그램 게임 때마다 두 주사위의 값을 어떻게 다르게 지정할까 ? 초등학생의 덧셈과 뺄셈 연습 프로그램 초등학생에게 문제를 낼 때마다 덧셈이나 뺄셈하는 두 수가 달라져야 한다 . 이 두 값을 어떻게 지정할까 ?. 8.12.1 난수 생성 함수 : rand p.356.
E N D
8.12.1 난수 생성 함수 : rand p.356 • 난수(randomnumber)가필요한 예 • 컴퓨터와 사람이 가위바위보 게임을 하는 프로그램 • 컴퓨터가 무엇을 낼지? • 주사위를 두 개 던져 나오는 값의 합을 맞추는 게임 프로그램 • 게임 때마다 두 주사위의 값을 어떻게 다르게 지정할까? • 초등학생의 덧셈과 뺄셈 연습 프로그램 • 초등학생에게 문제를 낼 때마다 덧셈이나 뺄셈하는 두 수가 달라져야 한다.이 두 값을 어떻게 지정할까?
8.12.1 난수 생성 함수 : rand p.356 • 난수 생성기(random number generator) • 무작위로 선택된 임의의 값을 한 개 반환하는 함수 • C 언어의 난수 생성기는rand 함수 • rand 함수의사용 • 함수 원형 : int rand(void) rand 함수의 호출 : rand( ) • 호출 결과 값은 0~32767 범위 안의 임의의 정수 • #include <stdlib.h> 필요
8-19 난수를 5개 구해 출력하기 p.357 1 #include <stdio.h> 2 #include <stdlib.h> // rand 함수 3 4 int main() 5 { 6 int i, random; 7 8 for (i=1; i<=5; i++) 9 { 10 random = rand(); // 난수 얻기 11 printf("%d번째 난수: %5d \n", i, random); 12 } 13 14 return 0; 15 }
8.12.2 스케일링 p.357 • 스케일링(scaling) • rand 함수의 반환 값(0~RAND_MAX 중 한 개)을 원하는 값의 범위로 조정하는 작업 • 스케일링 예) • 던져진 주사위 값 die를 1~6 중 한 개 값이 되도록 조정하기 die = rand() % 6 + 1; 0 ~ 5
8.12.2 스케일링 p.358 • 스케일링 예) 표 8-1 • 5 ~ 10 중의 정수 rand() % 6 + 5 • begin~ end 중의실수 rand() * (end - begin) / RAND_MAX + begin ㈜ begin과 end 중 하나는 반드시 실수형이어야 한다. rand 함수의최대 반환값32767을 매크로 상수로 정의한 것
8.12.2 스케일링 p.358 • 컴퓨터와 사람이 하는 가위바위보 게임 코드의 일부 1 computer = rand() % 3 + 1; // 컴퓨터가 낼 것 2 3 printf(" 컴퓨터와 함께 가위 바위 보를!!!\n"); 4 printf("==================================\n"); 5 printf(" 무엇을 내겠습니까(1. 가위 2. 바위 3. 보)? "); 6 scanf("%d", &man); :
8.12.3 씨드 설정 함수 : srand p.358 • 씨드(seed) 난수생성기가 생성하는 난수값과 순서를 결정 • [프로그램 8-19]의 세 번 실행 결과 모두 동일한 순서의 난수가 발생 • 8 for (i=1; i<=5; i++) • 9 { • 10 random = rand(); // 난수 얻기 • 11 printf("%d번째 난수: %5d \n", i, random); • 12 }
8.12.3 씨드 설정 함수 : srand p.359 • 씨드 설정 • 프로그래머가 직접 씨드를 지정 가능 → 지정한 씨드에 따라 rand의 난수가 순서대로 발생 • 씨드 설정 srand(씨드값); • 인수에 해당하는 값이 rand 함수의씨드로 설정됨→ 이후로 이 씨드에 따른 난수가 발생함 • #include<stdlib.h>가필요
8.12.3 씨드 설정 함수 : srand p.359 • [프로그램 8-19]의 7행에 씨드를 설정하기 p.359 • 7 • 8 for (i=1; i<=5; i++) • 9 { • 10 random = rand(); // 난수 얻기 • 11 printf("%d번째 난수: %5d \n", i, random); • 12 }
8.12.3 씨드 설정 함수 : srand p.359 • 여전히 남는 문제 p.359 • 7행에서 srand(1);을추가하더라도 씨드가1로 고정되므로 이 프로그램을 여러 번 실행하면 언제나 동일 순서의 난수가 발생 • 프로그램 실행마다 씨드를 다르게 지정하려면? • srand(인수): 호출 시 함수의 인수를 프로그램 실행마다 다르게 지정 • 7 srand(1); • 8 for (i=1; i<=5; i++) • 9 { • 10 random = rand(); // 난수 얻기 • 11 printf("%d번째 난수: %5d \n", i, random); • 12 } 첫 실행 결과 둘째 실행 결과
8.12.3 씨드 설정 함수 : srand p.359 • 현재 시간을 씨드로 설정하기 p.359 srand( time(NULL) ) 함수 호출문time(NULL) 실행 시 컴퓨터의 시간이 반환됨 time 함수는 #include <time.h>가 필요
8-20 현재 시간을 씨드로 설정하기 p.360 1 #include <stdio.h> 2 #include <stdlib.h> // rand, srand함수 3 #include <time.h> // time 함수 4 5 int main() 6 { 7 int i, random; 8 10 srand(time(NULL)); 11 12 for (i=1; i<=5; i++) 13 { 14 random = rand(); 15 printf("%d번째 난수: %5d \n", i, random); 16 } 17 18 return 0; 19 }
8.13.1 컴퓨터가 숨긴 수 맞히기 게임 p.361 • 문제 • 컴퓨터가 숨기고 있는 1~100 중 정수 하나를 맞추는 게임 프로그램 • 분석 • 컴퓨터가 숨기는 값 computer • 1~100 중 임의의 난수: computer = rand() % 100 + 1; • 사용자가 정답을 맞힐 때 까지 반복 do { - 'begin~end사이의 값임을 표시 후 사용자의 추측 답 user입력받기 - 게임 시도 회수 count1 증가 - 컴퓨터가 숨긴 값과 사용자 입력 값 비교 후 그 결과에 따라begin이나 end 값 수정하기 } while (user != computer);
8.13.1 컴퓨터가 숨긴 수 맞히기 게임 p.361 • 사용자 입력 값 user에따라 begin 또는 end 수정하기 • (user == computer) →do~while문 끝내기 • (user > computer) → end를 user-1로 수정 • (user < computer) → begin을 user+1로 수정 begin end user computer
8-21 컴퓨터가 숨긴 1~100 중의 정수 맞히기 p.362 1 #include <stdio.h> 2 #include <stdlib.h> // rand, srand 3 #include <time.h> // time 함수를 위한 헤더 파일 4 5 int main() 6 { 7 int begin = 1, end = 100; // 컴퓨터가 숨길 값 범위 8 int count = 0; // 답 맞히기 시도 횟수 9 int computer, user; // 컴퓨터가 숨긴 값,사용자 추측 값 10 11 srand(time(NULL)); ` // 현재 시간을 씨드로 설정 12 13 computer = rand() % (end - begin + 1) + 1; // 스케일링 14 15 printf("\n>> 컴퓨터가 숨긴 수를 맞히는 게임입니다. \n"); 16 printf("\n============================================\n");
8-21 컴퓨터가 숨긴 1~100 중의 정수 맞히기 p.362 18 do 19 { 20 printf("%3d ~ %3d 중의 값입니다. 얼마일까요? ", begin, end); 21 scanf("%d", &user); 22 23 count++; // 시도 횟수 1증가 24 25 // 숨긴 수의 범위 수정 26 if (user > computer) 27 end = user - 1; 28 else if (user < computer) 29 begin = user + 1; 30 31 } while (user != computer); // 추측 값이 틀리면 다시 반복 32 33 printf("============================================\n"); 34 printf ("\n 컴퓨터가 숨긴 %d를 %d번 만에 맞혔습니다.", computer, count);
8-21 컴퓨터가 숨긴 1~100 중의 정수 맞히기 p.362 팁) 프로그램 개발 동안 computer 값을 특정 값으로 고정하면 편리 컴퓨터가 숨긴 수를 미리 알고 있다면 프로그램 개발시 편하므로 13행을 주석문으로가린 후 14행에 computer = 30;과 같이 특정 값으로 직접 지정한 후 결과가 제대로 나온다는 것을 확인하고나서 스케일링 식을 명령문으로 사용해보자. 13 computer = rand() % (end - begin + 1) + 1; // 스케일링 14 15 printf("\n>> 컴퓨터가 숨긴 수를 맞히는 게임입니다. \n"); 16 printf("\n============================================\n");
8.13.5 별 반짝임 횟수 맞추기 게임 p.368 • 커서를 원하는 좌표로 이동하는 gotoxy함수 • 예전 콘솔용 응용 프로그램을 위한 통합 개발 환경인 터보C/C++에서 제공 • gotoxy함수의 사용 예 • 비주얼C++ 2010에서는 gotoxy함수를 제공하지 않는다. 대신 윈도우 API 함수를 이용하여 해결할 수 있다.
8-26 입력 위치를 원하는 곳으로 변경하기 p.370 1 #include <stdio.h> 2 #include <windows.h> // SetConsoleCursorPosition함수를 위한 헤더 파일 3 4 void gotoxy(int x, int y); // 함수의 원형 선언 5 6 int main() 7 { 8 intinput; 9 10 gotoxy(0, 3); // 커서 이동하기 11 printf("\t>> 다음 중에서 해당하는 번호를 고르세요. ( )\n\n"); 12 printf("\t1. 초등학생 \t\t 2. 중학생 \n"); 13 printf("\t3. 고등학생 \t\t 4. 대학생 \n"); 14 15 gotoxy(51, 3); // 커서를 위로 번호 입력하는 곳으로 이동 16 scanf("%d", &input); 17 18 gotoxy(0, 9); // 입력 결과 출력 위해 커서를 아래로 이동 19 printf("\t%d번을 선택하셨습니다.\n", input); 21 return 0; 22 }
8-26 입력 위치를 원하는 곳으로 변경하기 p.370 25 // 커서를 (x, y) 좌표로 이동하는 함수 24 void gotoxy(int x, int y) 25 { 26 COORD Cur; 27 Cur.X= x; 28 Cur.Y= y; 29 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Cur); 30 }
8.14 재귀 함수 p.380 • 재귀 함수(recursivefunction) • 함수 정의 안에서 함수 자신을 호출하는 재귀 호출(recursive call)을 포함하는 함수 • 반복문으로 해결하는 것 보다 문제의 정의와 더욱 가깝게 표현하며, 보다 쉽게 해결할 수 있다. • 재귀 함수로 해결할 수 있는 문제 • 언젠가는 재귀 호출을 하지 않고 함수 실행을 완료할 수 있는 정지(stopping 또는 base) 조건을 포함하는 문제
8.14.1 문제의 재해석을 통한 재귀 호출 p.380 • 재귀 함수를 이용한 해결 • 주어진 문제 자체를 재귀 호출로 풀 수 있도록 재해석하는 것이 필요 • 5에서 1까지 거꾸로 출력하기 위한 for문 for (i=5; i>=1; i--) printf("%3d", i); • 5에서 1까지 거꾸로 출력하는 문제의 재해석 ① 5 출력하기 ② 4에서 1까지 거꾸로 출력하기 • 5에서 1까지가 아닌 4에서 1까지의 출력으로, 처음 출력하는 숫자만 다를 뿐 원래 해결하려던 문제와 같다.
8-30 재귀 함수 이용 n에서 1까지 거꾸로 출력하기 p.381 5 int main() 6 { 7 int n; 9 printf("n에서 1까지 거꾸로 출력하는 프로그램입니다. n은? "); 10 scanf("%d", &n); 11 12 reverse(n); 13 14 return 0; 15 } • 18 void reverse(int n) • 19 { • 20 printf("%3d", n); • 21 if (n > 1) • 22 reverse(n-1); • 23 • 24 return; • 25 }
8.14.2 반환 값을 갖는 재귀 함수 p.383 • 1~n의 합을 반복문으로 해결한 함수 • 1~n의 합을 구하는 문제의 재해석 ① 1에서 n-1까지의 합 구하기 ② ①의 결과에 n 더하기 • int compute_sum(int n) • { • int i, sum = 0; • for (i=1; i<=n; i++) • sum = sum + i; • return sum; • } 재귀 호출
8-31 재귀 함수를 이용 1~n의 합 구하기 p.383 5 int main() 6 { 7 int n; 9 printf("1에서 n까지의 합을 구하는 프로그램입니다. n은? "); 10 scanf("%d", &n); 12 printf("1에서 %d까지의 합은 %d입니다.", n, addition(n)); 14 return 0; 15 } 17 18 int addition(int n) 19 { 20 int result; 21 22 if (n > 1) 23 result = addition(n-1) + n; 24 else 25 result = 1; 26 27 return result; 28 }