Download presentation
Presentation is loading. Please wait.
Published by혜경 강 Modified 7년 전
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)
Similar presentations