Presentation is loading. Please wait.

Presentation is loading. Please wait.

A Book on C Written by University of Inchon No. 5-1 함수 정의 (1) 함수가 수행할 작업을 기술한 C 코드를 함수정의 (function definition) 라고 한다. int factorial(int n) /* header */

Similar presentations


Presentation on theme: "A Book on C Written by University of Inchon No. 5-1 함수 정의 (1) 함수가 수행할 작업을 기술한 C 코드를 함수정의 (function definition) 라고 한다. int factorial(int n) /* header */"— Presentation transcript:

1 A Book on C Written by University of Inchon No. 5-1 함수 정의 (1) 함수가 수행할 작업을 기술한 C 코드를 함수정의 (function definition) 라고 한다. int factorial(int n) /* header */ { /* body starts here */ int i, product = 1; for(i = 2; i <= n; ++i) product *= i; return product; } 처음의 int 는 컴파일러에게 함수의 리턴 값이 int 이라는 것을 알려준다. 이 함수를 호출하기 위해서는 factorial(7) 과 같은 수식을 사용하면 된다.

2 A Book on C Written by University of Inchon No. 5-2 함수 정의 (2) void wrt_address(void) { printf("%s\n%s\n%s\n%s\n%s\n\n", " **********************", " ** SANTA CLAUS *", " ** NORTH POLE *", " ** EARTH *", " **********************",); } 앞부분의 void 는 이 함수는 리턴 값이 없음을 컴파일러에게 알려준다. 두 번째 void 는 인자가 없음을 알려준다.

3 A Book on C Written by University of Inchon No. 5-3 함수 정의 (3) 함수 정의의 예를 보자. void nothing(void){} /* this function does nothing */ double twice(double x) { return(2.0 * x); } int all_add(int a, int b) { int c;..... return(a + b + c); }

4 A Book on C Written by University of Inchon No. 5-4 함수 정의 (4) 함수형이 정의되지 않은 경우에는 기본적으로 int 형을 가지게 된다. 함수형을 정확히 명시해 주는 것이 좋은 프로그래밍 습관이다. all_add(int a, int b) {..... 함수의 몸체 부분 안에서 선언된 변수를 지역 (local) 변수라고 하고, 함수 밖에서 선언된 변수를 전역 (global) 변수라고 한다. 다음 예제를 보자.

5 A Book on C Written by University of Inchon No. 5-5 함수 정의 (5) #include int a=33; /* a is external and initialized to 33 */ int main(void) { int b = 77; /* b is local to main() */ printf("a = %d\n", a); /* a is global to main() */ printf("b = %d\n", b); return 0; }

6 A Book on C Written by University of Inchon No. 5-6 함수 정의 (6) 프로그램을 작은 함수들의 모임으로 작성하는 데는 중요한 이유가 있다. 1.프로그램의 작성이나 디버깅(debugging) 작업이 훨씬 수월하다. 2.프로그램의 유지와 보수도 쉽게 된다.

7 A Book on C Written by University of Inchon No. 5-7 return 문 (1) return; return ++a; return(a * b); 함수가 실행되다가 return 문을 만나게 되면 함수는 종료되고, 제어는 함수를 호출한 다음 명령문으로 돌아가게 된다. float f(char a, char b, char c) { int i;..... return i; /* the value returned will be converted to a float */ }

8 A Book on C Written by University of Inchon No. 5-8 return 문 (2)  return 문은 없거나 여러 개를 포함할 수도 있다. double absolute_value(double x) { if (x >= 0.0) return x; else return -x; }

9 A Book on C Written by University of Inchon No. 5-9 return 문 (3) 함수가 값을 리턴하더라도 그 값을 꼭 사용할 필요는 없다. while(...) { getchar(); /* get a char, but do nothing with it */ c = getchar(); /* c will be processed */..... }

10 A Book on C Written by University of Inchon No. 5-10 함수 원형 함수는 호출되어 사용되기 전에 선언되어야 한다. 함수원형은 컴파일러에게 인자의 형 (type) 과 인자의 개수, 그리고 리턴되는 값의 형을 알려준다. double sqrt(double, double); void f(char c, int i); f(char, int); 두예문은 동등한 함수원형의 선언이다. 함수원형ㅇ느 컴파일러가 프로그램을 더 철저히 검사할 수 있게 한다. return value type

11 A Book on C Written by University of Inchon No. 5-11 거듭 제곱표를 생성하는 예제 (1) long power(int, int); void prn_heading(void); void prn_tbl_powers(int); int main(void) { prn_heading(); prn_tbl_of_powers(N);..... void prn_tbl_of_powers(int n) { printf("\n:::: A TABLE OF POWERS ::::\n\n");..... }

12 A Book on C Written by University of Inchon No. 5-12 거듭 제곱표를 생성하는 예제 (2) void prn_tbl_of_powers(int n) {..... for(i = 1; i <= n; ++i) { for(j = 1; j <= n; ++j) if(j == 1) printf("%ld", power(i, j)); else printf("%ld", power(i, j)); putchar('\n');..... long power(int m, int n) {..... for(i=1 ; i<=n; ++i) product *= m; return product;.....

13 A Book on C Written by University of Inchon No. 5-13 컴파일러 관점에서의 함수선언 (1) 만약 함수선언이나 정의 또는 함수원형의 선언 전에 함수 f(x) 가 호출되었다면, 컴파일러는 기본적으로 다음과 같은 형태로 함수가 선언되었다고 가정한다. int f(); /* default declaration */ int f(x) /* traditional C style */ double x; {..... int f(double x) /* ANSI C style */ {.....

14 A Book on C Written by University of Inchon No. 5-14 함수정의 순서의 다른 형태 /* The use of an alternate style is to remove the list of function prototype */ #include #define N 7 void prn_heading(void) {..... } long power(int m, int n) {..... } void prn_tbl_powers(int n) {..... } int main(void) { prn_heading(); prn_tbl_powers(N);.....

15 A Book on C Written by University of Inchon No. 5-15 함수 호출과 값에 의한 호출 (1) 프로그램은 항상 main() 함수부터 수행된다. 함수는 함수의 이름과 괄호 안의 인자 리스트를 작성하여 호출된다. 모든 인자는 값에 의한 호출 (call by value) 로 전달된다. int main(void) {..... prn_heading(); prn_tbl_powers(N);.....

16 A Book on C Written by University of Inchon No. 5-16 함수 호출과 값에 의한 호출 (2) /* We illustrate the concept of "call by value" */..... int n=3, sum, compute_sum(int); printf("%d\n", n); /* 3 is printed */ sum = compute_sum(n); printf("%d\n", n); printf("%d\n", sum);..... } int compute_sum(int n) { /* sum the integers of 1 to n */... for( ; n > 0; --n) sum += n; /*stored value of n is changed*/ return sum; }

17 A Book on C Written by University of Inchon No. 5-17 대형 프로그램의 개발 (1) #includes..... #defines.......... list of fct prototypes pgm.h #include "pgm.h"..... #include "pgm.h"..... #include "pgm.h"..... main.cfct.cprn.c

18 A Book on C Written by University of Inchon No. 5-18 대형 프로그램의 개발 (2) 일반적으로 대형 프로그램에서는 각각 별도의 디렉토리에.h 파일과.c 파일을 작성하게 된다. 헤더파일 pgm.h 는 #include, #defines, 열거형 변수 선언, 구조체와 공용체 그리고 다른 프로그램 구성 원소를 포함하고, 마지막으로 함수원형들을 맨 아래에 포함하고 있을 것이다. 헤더파일 pgm.h 는 모든 C 파일의 서두에 사용되어 프로그램과 프로그램 사이를 연결하는 역할을 하게 된다.

19 A Book on C Written by University of Inchon No. 5-19 대형 프로그램의 개발 (3) /* A simple example of a large program */ #include /* In file pgm.h: */ #include #define N 3 void fct1(int k); void fct2(void); void prn_info(char *); #include "pgm.h" /* In file main.c: */ int main(void) {..... scanf(" %c", &ans); if(ans == 'y' || ans == 'Y') prn_info("pgm"); for(i=0 ; i < n; ++i) fct1(i);..... }

20 A Book on C Written by University of Inchon No. 5-20 대형 프로그램의 개발 (4) #include "pgm.h" /* In file fct.c */ void fct1(int n) {..... for(i = 0; i < n; ++i) fct2(); } void fct2(void) { printf("Hello from fct2()\n"); } #include "pgm.h" /* In file prn.c */ void prn_info(char *pgm_name) {...... }

21 A Book on C Written by University of Inchon No. 5-21 대형 프로그램의 개발 (5) 다음과 같이 컴파일될 수 있다. cc -o pgm main.c fct.c prn.c 컴파일러는 세 개의.c 파일을 컴파일 하고 세 개의.o 파일로 구성된 하나의 실행 가능한 pgm 파일을 만든다.

22 A Book on C Written by University of Inchon No. 5-22 단 정 (1) #include int f(int a, int b); int g(int c); int main(void) {..... scanf("%d%d", &a, &b);..... c = f(a, b); assert(c > 0); /* an assertion */.....

23 A Book on C Written by University of Inchon No. 5-23 단 정 (2)  assert() 에 인자로 전달된 관계식이 거짓 값을 갖는 경우 시스템은 메시지를 출력하고 프로그램을 중단시킨다. 인자 a 는 1 이나 -1 값을 가지고 b 의 예상 구간을 [7, 11] 안에 있다고 가정해 보자. int f(int a, int b) {..... assert(a == 1 || a == -1); assert(b >= 7 && b <= 11);..... }

24 A Book on C Written by University of Inchon No. 5-24 유효범위 규칙 (1) 기본적인 유효범위 규칙은 변수가 선언된 블록 안에서만 그 변수를 이용할 수 있는 것이다. { int a = 2; /* outer block a */ printf("%d\n", a); /* 2 is printed */ { int a = 5; /* inner block a */ printf("%d\n", ++a); /* 5 is printed */ } /* back to the outer block */ printf("%d\n", ++a); /* 3 is printed */ }

25 A Book on C Written by University of Inchon No. 5-25 유효범위 규칙 (2) /* We illustrate hidden variables in the nested blocks */ { int a=1, b=2, c=3; printf("%3d%3d%3d\n", a, b, c); /* 1 2 3 */ { int b=4; float c=5.0; printf("%3d%3d%5.1f\n", a, b, c); /* 1 4 5.0 */ a = b; { int c; c = b; printf("%3d%3d%3d\n", a, b, c); /* 4 4 4 */ } printf("%3d%3d%5.1f\n", a, b, c); /* 4 4 5.0 */ } printf("%3d%3d%3d\n", a, b, c); /* 4 2 3 */ }

26 A Book on C Written by University of Inchon No. 5-26 유효범위 규칙 (3) 블록 밖에서 선언된 변수가 블록 안에서 다시 선언되지 않았으면 블록 안에 서도 유효하다. 정수형 변수 a 는 바깥쪽 블록에서 선언되고는 다시 선언되지 않았다. 그러므로 블록 안에서 같은 변수로 사용될 수 있다.

27 A Book on C Written by University of Inchon No. 5-27 유효범위 규칙 (4) 병렬 블록과 중첩 블록 { int a, b;..... { /* inner block 1 */ float b;..... /* int a is known, but not int b */ }..... { float a;..... /* int b is known, but not int a */ /* nothing in inner block 1 in known */ }.... }

28 A Book on C Written by University of Inchon No. 5-28 유효범위 규칙 (5) 디버깅을 위한 블록 구조의 이용 { /* debugging starts here */ static int cnt = 0; printf("*** debug: cnt = %d v = %d\n", ++cnt, v); }

29 A Book on C Written by University of Inchon No. 5-29 기억영역 클래스 (1)  C 언어에서 사용되는 변수는 두 가지 속성을 가진다. 하나는 형 (type) 이고 또 다른 하나는 기억영역 클래스 (storage class) 이다. auto extern register static 함수의 몸체 부분에서 선언된 변수는 디폴트로 자동 기억영역 클래스이다. 키워드 auto 를 사용하여 자동 기억영역 클래스임을 명시적으로 선언 할 수도 있다. auto int a, b, c; auto float f; 지역변수들은 블록을 빠져 나가게 되면 모두 메모리에서 제거되어 사용할 수 없게 된다. 그러므로 변수가 저장하고 있던 값들을 잃게 된다.

30 A Book on C Written by University of Inchon No. 5-30 기억영역 클래스 (2) 블록과 함수간에 정보를 교환하기 위한 방법 중 외부 변수를 사용하는 방법이 있다. 변수를 함수 밖에서 선언하면, 프로그램이 종료할 때까지 메모리에 계속 남아 있다. 외부변수 (external variable) 들은 전역변수 (global variables) 로 취급되어 외부 변수 선언 뒤에 있는 블록이나 함수가 끝나더라도 사라지지 않고 변수로 존재하게 된다. 다음 예제는 외부 변수의 사용 예이다.

31 A Book on C Written by University of Inchon No. 5-31 기억영역 클래스 (3)..... int a=1, b=2, c=3; /* global variables */ int f(void); int main(void) { printf("%3d\n", f()); /* 12 is printed */ printf("%3d%3d%3d\n", a, b, c);..... /* 4 2 3 is printed */ } int f(void) { int b, c; /* b and c are local */ a = b = c = 4; /* global b, c are masked */ return (a+b+c); }

32 A Book on C Written by University of Inchon No. 5-32 기억영역 클래스 (4)  file1.c 에 저장 #include int a=1, b=2, c=3; /* external variables */ int f(void); int main(void) { printf("%3d\n", f()); printf("%3d%3d%3d\n", a, b, c);..... }  file2.c 에 저장 int f(void) { extern int a; /* look for it elsewhere */ int b, c; a = b = c = 4; return (a + b + c); }

33 A Book on C Written by University of Inchon No. 5-33 기억영역 클래스 (5) 위 예문의 두 파일은 분리되어 컴파일 될 수 있다. 두 번째 파일에서 extern 의 사용은 컴파일러에게 이 변수가 현재 파일 내의 어디서나 선언되어 있거나 또는 다른 파일 내에 선언되었음을 알려준다. 외부변수는 프로그램 실행되는 동안 전체에 걸쳐 존재하기 때문에 함수들에 값을 전달하는 용도로 사용될 수 있다. 함수 안으로 정보를 전달하는 데는 두 가지 방법이 있다. 하나는 외부 변수를 사용하는 것이고, 다른 하나는 매개변수를 사용하는 방식이다.

34 A Book on C Written by University of Inchon No. 5-34 기억영역 클래스 (6) 모든 함수는 외부 저장영역 클래스를 사용한다. extern double sin(double); extern double sin(double x) {..... 기억영역 클래스 register 는 컴파일러에게 변수를 가능하다면 고속 메모리인 레지스터에 저장되도록 지시하다. { register int i; for(i=0; i < LIMIT; ++i) {..... } } /* block exit will free the register */

35 A Book on C Written by University of Inchon No. 5-35 기억영역 클래스 (7) 정적 변수는 두가지 중요한 용도로 사용된다. 기본적인 용도는 그 블록으로 다시 들어갈 때 지역 변수로 선언된 변수가 이전의 값을 유지하고 있게 하는 것이다. void f(void) { static int cnt = 0; ++cnt; if(cnt%2 == 0)..... /* do something */ else..... /* do something different */ }

36 A Book on C Written by University of Inchon No. 5-36 정적 외부 변수 (1) 정적 외부 변수는 유효범위의 제한이 있는 외부변수이다. 정적 외부 변수의 유효범위는 그들이 선언된 소스 파일의 아래 나머지 부분이다. 그러므로 해당 파일 안에서 정적 외부 변수 선언보다 앞서서 정의된 함수나 다른 파일에서 정의된 함수들은 정적 외부 변수의 값을 사용할 수 없다. void f(void) {..... /* v is not available here */ } static int v; /* static external variable */ void g(void) {..... /* v can be used here */ }

37 A Book on C Written by University of Inchon No. 5-37 정적 외부 변수 (2) /* A family of pseudo random number generators. */..... static unsigned seed = INITIAL_SEED; /* external, but private to this file */ unsigned random(void) { seed =(MULTIPLIER * seed + INCREMENT)% MODULUS; return seed; } double probability(void) { seed =(MULTIPLIER * seed + INCREMENT)% MODULUS; return(seed / FLOATING_MODULUS); }

38 A Book on C Written by University of Inchon No. 5-38 정적 외부 변수 (3)  static 의 마지막 용도는 함수정의와 원형을 위한 저장영역 클래스 명시자로 사용되는 것이다. 정적 함수들은 그들이 선언된 파일 내에서만 사용될 수 있다. static int g(void); /* function prototype */ void f(int a) /* function definition */ { /* g() is available here,..... but not in other files */ } static int g(void) /* function definition */ {..... }

39 A Book on C Written by University of Inchon No. 5-39 디폴트 초기화  C 언어에서 외부 변수와 정적 변수는 프로그래머가 초기화하지 않아도 시스템에 의해 0 으로 초기화된다. 이와 같은 방식으로 초기화 되는 것에는 배열, 문자열, 포인터, 구조체, 공용체가 있다. 반면에, 자동 변수와 레지스터 변수는 일반적으로 시스템에 의해 초기화되지 않는다.

40 A Book on C Written by University of Inchon No. 5-40 재귀 호출 (1) 함수가 자기 자신을 호출하는 것을 재귀호출이라 한다. #include int main(void) { printf("The universe is never ending!"); main(); return 0; }

41 A Book on C Written by University of Inchon No. 5-41 재귀 호출 (2) int sum(int n) { if(n <= 1) return n; else return (n + sum(n - 1)); } 재취호출 함수 sum() 은 다음 테이블에서 설명된 것처럼 실행된다.

42 A Book on C Written by University of Inchon No. 5-42 재귀 호출 (3) int factorial(int n) { /* recursive version */ if (n <= 1) return 1; else return (n * factorial(n -1)); } 위 예문은 시스템이 제공하는 정수 범위의 한계를 초과하지 않는다면 옳은 값을 계산할 것이다..

43 A Book on C Written by University of Inchon No. 5-43 재귀 호출 (4) 대부분 간단한 재귀 함수를 반복 계산 함수 (iterative functions) 로 다시 작성하는 것이 가능하다. int factiorial(int n) { /* iterative version */ int product = -1; for( ; n>1; --n) product *= n; return product; }

44 A Book on C Written by University of Inchon No. 5-44 재귀 호출 (5) /* write a line backwards. */ #include void wrt_it(void); int main(void) {..... wrt_it(void);..... } void wrt_it(void) { int c; if((c = getchar()) != '\n') wrt_it() putchar(c); } Input a line: sing a song of sixpence ecnepxis fo gnos a gnis

45 A Book on C Written by University of Inchon No. 5-45 재귀 호출 (6) 많은 알고리즘은 재귀호출 방식이나 반복계산 방식을 사용하고 있다. 전형적으로, 재귀호출이 더 간결하고, 같은 계산을 하는 데 더 적은 변수가 필요하다. 이번에는 간단한 예인 피보타치 수열 계산의 효율성에 대해 고찰해 보자. int fibonacci(int n) { if( n <= 1 ) return n; else return(fibonacci(n-1) + fibonacci(n-2)); }

46 A Book on C Written by University of Inchon No. 5-46 재귀 호출 (7)


Download ppt "A Book on C Written by University of Inchon No. 5-1 함수 정의 (1) 함수가 수행할 작업을 기술한 C 코드를 함수정의 (function definition) 라고 한다. int factorial(int n) /* header */"

Similar presentations


Ads by Google