Chapter 11 함수 활용.

Slides:



Advertisements
Similar presentations
1 08 배열. 한국대학교 객체지향연구소 2 C 로 배우는 프로그래밍 기초 2 nd Edition 배열  동일한 자료유형의 여러 변수를 일괄 선언  연속적인 항목들이 동일한 크기로 메모리에 저장되는 구조  동일한 자료 유형이 여러 개 필요한 경우에 이용할 수 있는.
Advertisements

1. 2 차원 배열  배열은 동일한 데이터 유형으로 여러 개의 변수를 사용할 경우 같은 이 름으로 지정하여 간편하게 사용할 수 있도록 하는 것으로서 앞에서 1 차원 배열을 공부하였습니다.  2 차원 배열은 바둑판을 생각하면 되며, 1 차원 배열에서 사용하는 첨자를 2.
재료수치해석 HW # 박재혁.
ㅎㅎ 구조체 구조체 사용하기 함수 매개변수로서의 구조체 구조체 포인터와 레퍼런스 구조체 배열.
ㅎㅎ 구조체 C++ 프로그래밍 기초 : 객체지향의 시작 구조체 사용하기 함수 매개변수로서의 구조체 구조체 포인터와 레퍼런스
2장. 프로그램의 기본 구성. 2장. 프로그램의 기본 구성 2-1"Hello, World!" 들여다 보기 /* Hello.c */ #include int main(void) { printf("Hello, World! \n"); return 0;
Report #5 - due: 4/13 다음 10*5의 희소 행렬 A, B를 고려하라.
9장. C 언어의 핵심! 함수. 9장. C 언어의 핵심! 함수 9-1 함수의 정의와 선언 main 함수 다시 보기 : 함수의 기본 형태 { } 그림 9-1.
제3장 게임기본모듈 Page 153 ~ 182.
Chapter 7. 조건문.
제 9 장 구조체와 공용체.
Report #2 - Solution 문제 #1: 다음과 같이 프로그램을 작성하라.
컴퓨터 프로그래밍 기초 [Final] 기말고사
보고서 #7 (기한: 6/2) 2개의 스택, stk1, stk2를 이용하여 큐를 구현하라.
2007 1학기 10 함수 활용.
10장 함수.
CHAP 2:순환 순천향대학교 컴퓨터공학과.
Chapter 02 순환 (Recursion).
제 3장. C보다 나은 C++ II.
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
8장 함수 함수의 필요성 라이브러리 함수와 사용자 정의 함수 함수의 정의, 원형, 호출 배열을 함수 인자로 전달 재귀호출.
SqlParameter 클래스 선문 비트 18기 발표자 : 박성한.
컴퓨터 프로그래밍 기초 #02 : printf(), scanf()
Error Detection and Correction
2007 1학기 11 프로젝트 기초 실습.
Tail-recursive Function, High-order Function
13. 연산자 오버로딩.
10강. JSP 본격적으로 살펴보기-II 스크립트릿, 선언, 표현식 지시자 주석 Lecturer Kim Myoung-Ho
C 프로그래밍 C언어 (CSE2035) (Chap11. Derived types-enumerated, structure, and union) (1-1) Sungwook Kim Sogang University Seoul, Korea Tel:
Method & library.
JA A V W. 03.
사용자 함수 사용하기 함수 함수 정의 프로그램에서 특정한 기능을 수행하도록 만든 하나의 단위 작업
프로그래밍 개요
어서와 C언어는 처음이지 제14장.
자료구조: CHAP 7 트리 –review 순천향대학교 컴퓨터공학과 하 상 호.
27장. 모듈화 프로그래밍.
3장 상수 변수 기본 자료형 키워드와 식별자 상수와 변수 기본 자료형 형변환 자료형의 재정의.
문제 2명의 사형수가 있다. 둘에게는 검정색 모자와 흰색 모자를 임의로 씌우는데, 자기가 쓴 모자의 색은 절대로 알 수가 없다. 서로 상대의 모자색만을 볼 수 있고, 이들이 살기 위해선 자신의 쓴 색의 모자를 맞춰야 한다. 단, 둘 중 한명만이라도 자신이 쓴 모자의 색을.
Term Projects 다음에 주어진 2개중에서 한 개를 선택하여 문제를 해결하시오. 기한: 중간 보고서: 5/30 (5)
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
연산자 (Operator).
에어 조건문.
컴퓨터 프로그래밍 기초 - 10th : 포인터 및 구조체 -
2장. 변수와 타입.
컴퓨터 프로그래밍 기초 - 5th : 조건문(if, else if, else, switch-case) -
컴퓨터 프로그래밍 기초 - 8th : 함수와 변수 / 배열 -
5장 선택제어문 if 선택문 switch-case 선택문 다양한 프로그램 작성 조건 연산자.
보고서 #7 (기한: 6/2) 2개의 스택, stk1, stk2를 이용하여 큐를 구현하라.
9장. C 언어의 핵심! 함수. 9장. C 언어의 핵심! 함수 9-1 함수의 정의와 선언 main 함수 다시 보기 : 함수의 기본 형태 { } 그림 9-1.
함수(Function) ◈ 함수의 개념 및 사용 이유 ◈ 함수 정의, 호출 및 선언 ◈ 지역변수와 전역변수 ◈ return 문
제 6 장 함수(functions).
제 15 강 문자와 코드 shcho.pe.kr.
에어 PHP 입문.
4장. 데이터 표현 방식의 이해. 4장. 데이터 표현 방식의 이해 4-1 컴퓨터의 데이터 표현 진법에 대한 이해 n 진수 표현 방식 : n개의 문자를 이용해서 데이터를 표현 그림 4-1.
클래스 : 기능 CHAPTER 7 Section 1 생성자(Constructor)
Flow Diagram IV While.
7주차: Functions and Arrays
CHAP 2:순환.
Homework #8 (실습 #7) [1/2] 다음을 수행하는 PHP 프로그램을 작성하여 프로그램과 결과물을 프린트하여 제출한다. sin(45º), cos(45º), tan(45º)를 출력하는 프로그램을 작성하시오. 피보나치 수를 구하는 함수 fib($n)을 작성하고,
쉽게 배우는 알고리즘 2장. 점화식과 점근적 복잡도 분석
12 그리드 시스템.
함수, 모듈.
컴퓨터 프로그래밍 기초 - 9th : 배열 / 포인터 -
Numerical Analysis Programming using NRs
8장 선택 논리 II 1. 논리연산자 1.1 논리연산자 : AND (&&) 1.2 논리연산자 : OR (||)
실습과제 (변수와 자료형, ) 1. 다음 작업 (가), (나), (다)를 수행하는 프로그램 작성
개정판 누구나 즐기는 C언어 콘서트 제13장 동적 메모리 출처: pixabay.
7 생성자 함수.
6 객체.
함수 정의, void 자료형 함수 원형선언 함수 호출 변수 영역 규칙 재귀 함수
Presentation transcript:

Chapter 11 함수 활용

재귀 함수 재귀 특징 함수는 함수 구현에서 자기 자신의 함수를 호출 가능 자기 자신 함수의 호출을 재귀 호출(recursive call)이라 하고, 이러한 특징을 재귀(recursion)라 한다. 재귀를 다른 말로 되부름, 또는 순환이라 표현 재귀 호출을 허용하는 함수를 재귀 함수(recursive function) 특징 구현하려는 알고리즘 자체가 재귀적 특성을 갖는다면, 재귀 함수를 이용하면 쉽게 구현이 가능 재귀 함수를 이용하면 재귀적 특성을 표현하는 알고리즘에서 쉬운 문제해결을 찾을 수 있고 이해도 쉽다. 재귀 함수는 계속적인 함수의 호출로 인하여 시간과 메모리 공간의 효율성이 떨어지는 단점 일반적으로 재귀 함수는 반복문을 이용한 함수로 변환이 가능

재귀 특성 추출 n! 수식 n!(n factorial)은 1 * 2 * 3 * … * (n-2) * (n-1) * n을 의미 계승 수식은 재귀적 특성을 갖음 즉 n!을 구하기 위해서 (n-1)!을 먼저 구한다면 쉽게 n!을 구할 수 있음 n!을 함수 factorial(n)로 구현한다면 함수 factorial(n) 구현에서 다시 factorial(n-1)을 호출하여 그 결과를 이용할 수 있음

종료 조건 함수 구현 위 소스를 기본으로, 이제 함수 factorial()을 구현하기 위해 필요한 것은 재귀적 호출이 종료되는 조건을 구하는 일 이러한 종료 조건을 고려하는 것은 재귀적 함수가 갖는 공통된 특징 재귀적 호출이 종료되는 조건이 없다면 무한 호출에 의해 문제가 발생 재귀 함수의 종료 조건을 알아보기 위해 다시 5!을 고려

n! 함수 구현 n!을 조건식으로 표현하면 다음과 같고, 이를 함수로 구현

예제 소스 factorial.c 1부터 10까지의 n!을 구하여 출력하는 프로그램  

예제 소스 Binary.c 연산 예 임의의 십진수를 이진수로 바꾸는 재귀 함수를 작성 임의의 정수를 표준입력으로 입력 받아 그 수의 이진수를 출력 입력한 수가 0이면 종료하며 0보다 크면 이진수 변환을 계속 연산 예 이진수로 변환할 십진수 6에서 6/2한 결과 값인 3은 다시 이진수를 구하기 위하여 이용 또한 십진수 6에서 6%2한 결과 값인 0은 이진수의 마지막 비트에 해당한다. 즉 이 값의 출력이 제일 마지막에 이루어져야 한다

함수 구현 지금까지 살펴본 내용을 재귀적 특성으로 표현하여 함수 binary()로 구성

함수의 인자 함수의 인자는 함수를 정의하는 곳에서 기술된 인자인 형식인자(formal parameter)와 함수 호출에서 기술된 실인자(real parameter)로 구분 형식인자에 기술된 변수는 변수의 선언과 같이 식별자의 조건에 맞는 변수 이름을 사용한다. 함수를 호출할 때는 함수의 정의에 기술된 형식인자의 수와 자료형에 맞게 실인자를 기술 형식인자의 변수는 그 함수가 호출되는 경우에 메모리에 할당(allocation)되고, 그 함수 실행을 마치면 메모리에서 자동으로 제거 (free, deallocation)

값의 의한 호출 함수의 형식 인자가 일반 변수형(기본 자료형을 의미)일 때 실제 함수가 호출되는 경우, 실인자의 값을 형식인자에 할당된 새로운 변수에 복사 저장한다. 이러한 인자의 전달 방법을 값에 의한 호출 방법(call by value) 다음 소스를 살펴보면 메인 함수에서 다른 함수 increment()를 호출하고 있다. 호출 전에는 변수 number에 10이 저장되었고, 변수 number를 실인자로 함수 increment(number)를 호출한다. 함수 호출 후 변수 number의 값은 변했을까? int main(void) { int number = 10; increment(number); printf("number = %d\n\n", number);   return 0; } void increment(int number) ++number;

값의 의한 호출 함수 메인에서의 number는 메인 함수에서만 유효한 변수이고, 마찬가지로 형식인자인 변수 number는 함수 increment() 내부에서만 의미 있는 변수 그러므로 메인에서의 변수 number와 increment()에서의 변수 number는 전혀 다른 변수 함수 increment()에서 number는 이 함수 실행이 종료되면 메모리에서 자동으로 제거 그러므로 메인 함수에서 함수 increment()가 호출되어도 메인 함수의 변수 number에는 아무런 영향을 미칠 수 없다. 그러므로 메인 함수에서 함수 호출 후 출력되는 number 변수는 여전히 10

인자와 반환 값 인자 전달 방법이 값에 의한 호출 방법(call by value)에서의 함수 인자는 함수를 호출하는 부분에서 함수를 호출하는 영역으로 자료를 전달하는데 주로 사용 반대로 호출 함수가 작업을 수행한 후, 함수를 호출한 영역으로 결과 값을 전달할 때는 반환 값(return value)을 이용

예제 소스 Callbyvalue.c 값에 의한 전달 인자를 이해

난수 임의의 수를 난수(random number)라 하는데, 시스템 라이브러리에서 난수를 만드는 함수를 제공 함수 rand()를 이용하면 난수를 발생시킬 수 있는데, 이 함수를 사용하기 위해서는 헤더 파일 stdlib.h 파일을 첨가 함수 rand()에 의해 생성되는 정수는 [0, n] 사이의 임의의 정수 여기서 n은 시스템에 따라 다르다. n은 일반적으로 헤더 파일 stdlib.h 파일에 기호 상수 RAND_MAX에 의해 정의, 다음은 Visual C++의 헤더 파일 stdlib.h 파일의 일부로서 기호 상수 RAND_MAX는 16진수로 7fff이고 십진수로 32767

0에서 32767의 난수 Visual C++에서는 함수 rand()는 0에서 32767사이의 정수 중에서 임의로 하나의 정수를 반환 함수 rand()를 이용하면 임의의 수가 발생하는데, 6개의 난수를 발생하는 프로그램을 만들어 여러 번 실행해도 항상 같은 수가 발생

시드 이용 이러한 문제를 해결하는 방법이 매번 난수를 다르게 발생시키기 위하여 시드 (seed) 값을 주는 방법 씨앗이라는 의미의 시드는 이 값을 이용하여 난수를 만드는 수식에 이용 시드 값이 다르면 함수 rand()에서 발생시키는 난수가 다르다. 난수 발생 함수 rand()에서 시드 값이 난수의 값을 결정 이 시드 값을 주는 방법은 함수 srand()를 호출 함수 time()으로 반환되는 값을 함수 srand()의 인자로 이용 함수 time(NULL)은 1970년 1월 1일 이후의 경과된 시간을 초 단위로 반환 함수 이 함수 time()을 이용하려면 헤더 파일 time.h를 첨가   난수에 시드를 주기 위해 함수 srand( time(NULL) )을 호출

예제 소스 Random.c 함수 rand()에서 시드 값을 주지 않고 6개의 난수를 발생, 출력하고, 또한 1에서 45까지의 6개의 난수를 발생시켜 출력 매번 결과가 다르도록 시드 값을 함수 time(NULL)으로 주어 1에서 45까지의 난수를 6개 발생시켜 출력

피모나츠 수 수열 피보나츠 다음 수의 나열인 수열을 살펴보면 앞의 두 수의 합이 그 다음 수 위와 같은 특징의 수열을 피보나츠(Fibonacci) 수열 피보나츠 수는 맨 처음 1202년 수학자 레오나르도 피보나츠 (Leonardo Fibonacci)에 의해 다음과 같은 문제에서 제안

피보나츠 수 위 문제에서 매달 토끼장에 있는 토끼의 쌍을 계산해 보면 위 수열로 표현됨을 알 수 있고, 이 수열을 피보나츠(Fibinacci) 수열 n번째 달의 토끼 쌍의 수를 Fn이라 하면, Fn은 다음과 같이 재귀적으로 표현 피보나츠 수를 발생시키는 프로그램을 작성한다면 재귀적 특성을 이용하여 쉽게 구현이 가능

피보나츠 구현 여기에서는 재귀적 방법이 아닌 반복적 방법을 이용하여 구현 long fibo(int n) { int fn, fn1, fn2; int i;   if (n <= 1) { return n; } else { fn2 = 0; fn1 = 1; for (i = 2; i <= n; i++) { fn = fn1 + fn2; fn2 = fn1; fn1 = fn; } return fn;

예제 소스 Fibonacci.c 피보나츠 수를 구하는 모듈을 만들어 계속적으로 수와 비율을 구해보고, 함수 fibo()를 반복 구문을 이용하여 만들어 이를 호출하여 피보나츠 수를 출력하는 프로그램 황금비 피보나츠 수의 특징 중의 하나가 연속적인 수의 비율이 1.618..의 상수 값에 수렴한다는 것 이 수는 계속 반복적으로 일어나고 황금 비(golden ratio) 혹은 황금 평균치(golden mean)라고 불린다. 놀랍게도 우리 주위에는 황금 비를 이용한 사례가 많으며, 사람들은 너비와 높이가 황금 비율인 사각형을 안정적으로 선호

하노이 탑 위 문제를 그림으로 보면 A 말뚝의 원반 64개를 말뚝 B를 이용하여 말뚝 C로 모두 옮기는 것

하노이 문제 해결 문제해결 만일 원반이 1개일 때, 바로 원반을 말뚝 A에서 C로 옮기면 된다 원반이 2개인 경우는 … 원반이 3개인 경우는 … 그렇다면 원반이 64개인 경우는 어떻게 하면 될까?

분할 정복 방법 Divide and conquer

하노이 탑 구현 하노이 탑의 분할 정복을 재귀적 함수로 구현 함수 moveHanoi(char, char, char, int)의 인자의 역할은 각각 출발 말뚝, 중간이용 말뚝, 목적 말뚝, 원반의 수 하노이 문제를 해결하려면 함수 moveHanoi(‘A’, ‘B’, ‘C’, 64)로 호출

예제 소스 Hanoi.c 하노이 탑 문제를 재귀적 함수를 이용하여 해결 하노이 탑의 원반의 수를 입력 받아 결과를 출력하는 프로그램

프로그램 연습 프로그램 목적 구현 두 개의 양의 정수를 입력 받아, 이 두 수의 최대공약수를 구하는 프로그램을 작성 두 개의 자연수의 공통인 약수를 그들 수의 공약수 그리고 이들 공약수 중에서 가장 큰 수를 최대공약수 구현 두 수의 최대공약수(Greatest Common Devisor)를 구하는 해결 방법 중에서 프로그램에서 쉽게 적용할 수 있는 방법이 유클리드 호제법 함수 호출 큰 수(max) 작은 수(min) gcd(30, 20) 20 30 % 20 == 10 gcd(20, 10) 10 20 % 10 == 0 gcd(10, 0) 그러므로 정답은 10  

함수 구현 유클리드 호제법의 원리 두 수 a, b가 있을 때, 한 수를 다른 수로 나누었을 때의 식을 고려 예를 들어 a를 b로 나누었더니 몫이 q이고 나머지가 r이었다면 a=bq+r의 식이 성립 이 때, a와 b의 최대공약수는 b와 r의 최대 공약수와 같다(r이 0인 경우에 a와 b의 최대공약수는 b가 된다)라는 것이 유클리드 호제법의 원리 예를 들어 20과 30의 최대공약수를 유클리드 호제법으로 여기서 30=20*1+10이므로 30과 20의 최대공약수는 20과 10의 최대공약수와 같다. 20=10*2+0이므로 20과 10의 최대공약수는 10이 됨을 알 수 있다. 30과 20의 최대공약수는 20과 10의 최대공약수와 같고, 그 결과는 10이므로 30과 20의 최대공약수는 10 이러한 유클리드 호제법 연산과정은 나머지 연산자 %를 이용하고, 우리가 배운 재귀 함수를 이용하면 쉽게 해결할 수 있다. 함수 호출 큰 수(max) 작은 수(min) gcd(30, 20) 20 30 % 20 == 10 gcd(20, 10) 10 20 % 10 == 0 gcd(10, 0) 그러므로 정답은 10  

함수 구현 이 유클리드의 호제법을 정리 아래에서 A는 B보다 작지 않은 수로 가정 Gcd (A, B)를 구하려면 if (B == 0) {          두 수의 최대공약수는 A이다. } else { Gcd(B, A % B)를 다시 수행한다. } int gcd(int max, int min) { if (min == 0) { return max; } else { return gcd(min, max % min); }

소스와 결과