본강의자료는문정욱교수님의강의자료를활용하여작성하였습니다. C 언어맛보기 #3 함수 1 부산대학교전기컴퓨터공학부 김종덕 (kimjd@pusan.ac.kr) Intelligence Networking and Computing Lab.
강의의목표 프로그래밍에서 Function( 함수 ) 의의미를이해한다. 함수의호출구조를이해한다. 함수가포함된코드를 Debugging 할수있다. 함수의재귀적호출을이해한다. Intelligence Networking and Computing Lab. 2
함수의개념 함수 (function)? 함수 (function; 函數 ): 상자수 ; 상자에 수를넣으면수가나옴 입력값을넣으면출력값이나오는 (Black) Box 2.5 a 인수, 인자, 매개변수 (argument) square 함수 double square(double a) return a*a; double x=2.5; double z; z=square(x); printf("%f\n", z); 리턴값 6.25 6.250000 입출력결과 3
Function Definition Function Body Function Definition function_definition: ret_type funct_name(arguments) return expression; 함수가반환하는값의 Type 함수의이름 함수호출에필요한인자 / 매개변수 double square(double a) a = a 1; return a*a; double x=2.5; double z; Function Call 함수호출시 ( ) 안의변수또는 expression의값이매개변수로복사됨. 변수자체가함수로전달되는것이아님 z=square(x); printf("%f, %f\n", x, z); 이런함수호출방식을 Call by Value 라고함 Call by Reference 와구별 2.500000, 6.250000 입출력결과 함수내에서매개변수의값이변하더라도원래변수에는변화가없음!!! 4
함수의호출구조 여러개의인자전달 int add(int a, int b) return a+b; int x=2; int y=3; int z; z = add(x,y); printf("%d\n",z); 여러함수의호출 double square(double a) return a*a; double circle(double r) return 3.14*square(r); double area; area = circle(2.5); printf("%f\n", area); 5
함수호출 Debug 아래코드를 Debug 수행하라 square() 내의 return 문의줄번호위에 마우스커서를두고 double-click 을수 행해보라 Break-Point 설정 / 해제 Debug를다시수행하고 Resume(F8) 을눌렀을때 Break-Point의존재여부가미치는영향을이해하라. 디버깅모드에서커서가위 Break- Point에존재할때아래그림과같은 Debug 창을확인하라. Debug를시행하면위그림과같이 circle() 함수호출라인에서 Debugging이시작된다. 이때 Resume(F8), step-into(f5), step-over(f6) 의차이점을이해하라. F8 F5 F6 위 Debug 창을 Call Stack 이라고도 한다. 6
함수의호출구조 Call Stack double square(double a) return a*a; double circle(double r) return 3.14*square(r); double area; call call square() circle() main() return return Call Depth 3 (3) square(2.5) (2) circle(2.5) (1) main() Call Number = 3 area = circle(2.5); printf("%f\n", area); Stack : 쌓다 7
함수의호출구조 인자밖호출 double square(double a) return a*a; double pi(double b) return 3.14*b; double area,sq; 인자안호출 double square(double a) return a*a; double pi(double b) return 3.14*b; double area; sq = square(2.5); area = pi(sq); printf("%f\n", area); area = pi(square(2.5)); printf("%f\n", area); main() 을기준으로 square() 와 pi() 의 main() 을기준으로 square() 와 pi() 의 Call Depth 와 Call Number 는? Call Depth 와 Call Number 는? 8
함수의형태 함수에는인자가없거나 Return 값이없는함수도있을수있다. 인자가없거나 Return 값이없을때모두 void 를사용한다. 에서 void 의의미가인자가없는함수임을의미한다. 인자가없는함수의예 int read_integer(void) int n; scanf("%d",&n); return n; Return 값이없는함수의예 void print_integer(int a) printf("%d\n", a); Intelligence Networking and Computing Lab. Return 이없는함수를 Procedure 라고도한다. Return 문이없거나인자없이 return 을쓴다. void print_hello(int n) int i; if (n<=0) return; for (i=0; i<n; i=i+1) printf("hello World\n"); 9
함수에서다양한반환값처리 Return 값이있는함수에서 return 은여러번쓰일수있다. 다만모 든수행상황에대해 return 이호출되어야한다. 오류의예 int compare_integer(int a, int b) if (a > b) return 1; // positive: a > b if (a < b) return 1; // negative: a < b // a == b?..\main.c:9:1: warning: control reaches end of non void function [ Wreturn type] int compare_integer(int a, int b) if (a > b) return 1; // positive: a > b if (a < b) return 1; // negative: a < b if (a == b) // zero: a == b 조건과관련없이무조건실행되는 return 문이있는것이바람직 int compare_integer(int a, int b) if (a > b) return 1; // positive: a > b if (a < b) return 1; // negative: a < b // zero: a == b int compare_integer(int a, int b) return a b; int compare_integer(int a, int b) int ret_val = 0; if (a > b) ret_val = 1; if (a < b) ret_val = 1; return ret_val; Intelligence Networking and Computing Lab. 10
함수의재귀호출 (recursive call) Factorial! 1 0 1 1 Call sequence (7) factorial(0) (6) 1 factorial(1) int factorial(int n) if( n==0 ) return 1; return n*factorial(n 1); printf("%d\n",factorial(5)); 120 입출력결과 Call Depth = 7 1 (5) factorial(2) 2 (4) factorial(3) (3) 6 factorial(4) (2) 24 factorial(5) (1) 120 main() 11
함수의재귀호출 (recursive call) Fibonacci Sequence Call sequence 0 0 1 1 1 2 2 int fibo(int n) if ( n==0 ) if ( n==1 ) return 1; return fibo(n 1)+fibo(n 2); printf("%d\n",fibo(4)); 3 입출력결과 Call Depth = 5 (5) (6) fibo(1) fibo(0) 1 0 (4) (7) (9) (10) fibo(2) fibo(1) fibo(1) fibo(0) 1 1 1 0 (3) (8) fibo(3) fibo(2) 2 1 (2) fibo(4) 3 (1) main() ( 참고 ) Call Depth : 함수의호출깊이, 필요한메모리 (Stack) 양과관련있음. Call Number : 함수의호출횟수, 계산에필요한시간과관련있음 12
Hanoi Tower 재귀적처리의대표적예제 ) 하노이탑은다음그림처럼원반 n 개로구성된탑이다. 첫번째막대기에있는하노이탑을세번째막대기로옮기고자한다. 원반은한번에하나씩만옮길수있으며옮기는과정중에작은원반위에큰원반을올리면안된다. 이문제를풀기위한재귀함수 hanoi_tower() 를작성하라. void hanoi_tower(int n, int ox, int tx, int mx); int n : 이동할원반의수 int ox : 이동할 n개의원반이현재존재하는막대기의번호 int tx : 원반을이동시킬목적막대기번호 int mx : 나머지막대기번호 main 함수에서의호출 이때, 어떻게원반을움직여야하는지출력하는프로그램을작성하라. 막대기 1의맨위원반을 2의맨위로옮기는것은다음과같이출력한다. 1 -> 2 프로그램은하노이탑높이 n만입력으로받고막대기 1의높이 n인하노이탑을막대기 3으로옮기는데필요한원반이동을출력한다 void hanoi_tower(int n, int ox, int tx, int mx) // Your Code Here int n; printf("enter the height of the tower"); scanf("%d",&n); hanoi_tower(n, 1, 3, 2); 13
n=1 일때먼저생각해보자. Hanoi Tower void hanoi_tower(int n, int ox, int tx, int mx) // Your Code Here printf("%d > %d\n", ox, tx); n=k(>1) 일때 ox에있는 k개의원반중위로부터 k-1개의원반을 mx로옮긴다. : ox -> mx ox에남은하나 (k번째) 의원반을 tx로옮긴다. : ox -> tx mx에있는 k-1개의원반을 tx로옮긴다 : mx -> tx 위 Logic을재귀적함수을통해구현한다면? Intelligence Networking and Computing Lab. 14