270 likes | 391 Views
제 4 장 함수와 기억 클래스. 함수의 기초 (cont’d). 함수 주 프로그램으로부터 인수 (argument) 를 전달받아 알련의 작업을 수행한 후 생성된 결과를 주프로그램 (main) 으로 전달하는 하나의 단위 프로그램 함수를 사용하는 이유 반복되는 코드 작성을 없애줌 프로그램을 이해하기 쉽고 이식이 용이하게 함 모듈성 (modularity) 향상시킴. 함수의 기초. 함수 간의 통신 인자의 전달과 리턴되는 값 외부 변수를 이용. 내장 함수. 라이브러리 함수
E N D
함수의 기초 (cont’d) • 함수 • 주 프로그램으로부터 인수(argument)를 전달받아 알련의 작업을 수행한 후 생성된 결과를 주프로그램(main)으로 전달하는 하나의 단위 프로그램 • 함수를 사용하는 이유 • 반복되는 코드 작성을 없애줌 • 프로그램을 이해하기 쉽고 이식이 용이하게 함 • 모듈성(modularity) 향상시킴
함수의 기초 • 함수 간의 통신 • 인자의 전달과 리턴되는 값 • 외부 변수를 이용
내장 함수 • 라이브러리 함수 • printf(), scanf(), getch() • reference guide 참조 • 헤더 파일 • 내장 함수들을 기능별로 구분하여 선언해 놓은 파일 • #include를 사용하여 포함 • ex) math.h : 수학적 처리에 담당하는 함수 graphics.h : 그래픽 관련 함수 string.h : 문자열 처리 함수
사용자 함수 • 사용자가 정의한 함수 • 사용자가 직접 선언 필요 • 함수의 정의 return-typefuction-name(argument declarations) { declarations and statements }
정수 이외의 값을 리턴하는 함수 • void 형 함수 • 리턴 값이 없는 함수 • return ; 의 형태로 사용 • 정수 이외의 값을 리턴하는 함수 • C는 함수의 리턴형이 명시되지 않으면 int형으로 간주 • 함수의 원형(prototype)이 필요
정수 이외의 값을 리턴하는 함수 • 함수의 원형(prototype)이 필요한 이유 • 함수의 리턴값을 알 수 있음 • 함수 호출시 자동적인 인자의 형 검사 • 컴파일시 인자 전달 오류 검사 가능
함수의 원형 선언 • 선언 방법 • return-type function-name(argument list); • 인자 리스트에 인자의 데이터형만을 지정해도 됨 • 인자가 없는 경우는 void로 지정 • 함수의 원형 선언은 함수의 정의와 일치하여야 한다 • 형식 인자의 이름은 달라도 됨
함수의 원형 선언 • 예제 double sqrt(double x); double atof(char []); int getchar(void);
예제 #include <stdio.h> float max(float a, float b, float c); main() { float x,y,z,k; printf("입력:"); scanf("%f %f %f", &x, &y, &z); k = max(x, y, z); printf("최대값: %f\n",k); }
예제(con’d) float max(float a, float b, float c) { float mx; if (a > b) mx = a; else mx = b; if (c > mx) mx = c; return(mx); }
인수의 전달 • Call by value • 복사한 값 사용, 다른 기억장소에 저장 • 함수 내에서 값을 변경하여도 원본에는 바뀌지 않는다. • Call by reference • 인수의 메모리 번지가 전달, 함수에서 메모리 번지를 참조하여 값을 읽음 • 함수에서 값을 바꾸면 주프로그램의 값 자체가 바뀐다. • 주 프로그램으로 여러 개의 계산 결과를 전달하고자 할 때 유용
인수의 전달 예제 #include <stdio.h> void inc_bad(int a) { a += 1; } void inc_good(int *a) { *a += 1; }
인수의 전달 예제(con’d) void main(void) { int i = 5, j = 10; int *p; p = &j; printf("%d %d %d",inc_bad(i),inc_good(&j),inc_good(p)); } • inc_bad(i)는 call by value • inc_good(&j) 와 inc_good(p)는 call by reference
Recursion 함수 • 재귀 호출(recursion) • 함수가 자기자신을 직접 또는 간접적으로 호출 • 재귀 호출을 사용하지 않았을 때보다 훨씬 코드가 간결 • 코드를 이해하기 어렵게 만들고 기억 공간을 많이 요구하는 단점을 가짐 • 재귀적인 특성을 갖는 자료 구조(트리, 리스트)나 작업에 사용
Recursion 함수의 예제 #include <stdio.h> long fact(int n) { if(n <= 1) return 1; else return(n * fact(n-1)); } main() { int num; for(num = 1;num <= 10;num++) printf("%2d! = %10ld",num, fact(num)); }
main 함수와 인자 • main() 함수의 원형 • int main( int argc, char *agrv[], char *env[] ) ; • int argc : command line에 쓰여지는 인자의 갯수 • char *argv[] : command line에서 입력한 인자들이 존재하는 메모리의 번지수를 차레대로 기억하고 있다. • argv[0] : 실행 파일 이름(경로가 입력된 경우는 경로까지 포함) • argv[1] : 첫 번째 인자의 내용 • 인자들 사이는 white character(space나 tab)에 의해 구분
C 전처리기(preprocessor) • 전처리기(preprocessor) • 컴파일의 첫번째 단계를 수행 • 기능 • 화일의 포함: #include • 매크로 치환: #define • 조건부 컴파일: #if, #else, #endif, #ifdef, #ifndef • 파일의 포함 • 헤더화일을 포함시킬 때 사용 • #include "filename" 또는 #include <filename> • "filename"이면 소스 프로그램이 존재하는 디렉토리부터 화일의 탐색 시작 • <filename>이면 컴파일러가 사용하는 규칙에 따라 화일을 찾음
매크로 치환 • #define은 심볼 상수나 인자를 갖는 매크로를 정의하는데 사용 • #define name replacement text • replacement text가 두개이상의 행으로 나타날 때 각 행의 끝에 \ • 토큰 name을 replacement text로 치환하는 일을 수행 • #define은 인자를 갖는 매크로를 정의할 수 있음 • #define max(A, B) ((A) > (B) ? (A) : (B))
기억 클래스 • 모든 변수는 참조될 수 있는 범위(scope)를 가진다. • 지역 변수(local variable, 내부 변수) • 함수 안에 즉 어떠한 블록 안에 정의된 변수 • 블록({}으로 묶인 부분)안에서만 통용 • 다른 함수에서는 참조될 수 없다 • 함수가 호출되면 생성되었다가 리턴하면 소멸(자동변수, automatic variable)
기억 클래스 • 전역 변수(global variable, 외부 변수) • 함수의 바깥에서 정의된 변수로 여러 함수가 전역적으로 접근 가능 • 함수와 함수 사이에서 데이터 전달 수단으로 사용될 수 있음 • 프로그램 시작시 생성되고 종료될 때가지 유지 • 반드시 한 번만 정의되어야 하며 여러 번 선언 가능
기억 클래스 • 외부 변수와 범위 • 변수의 정의 • 변수를 선언 • 변수의 데이터형에 해당하는 크기의 기억 장소 할당 • 변수의 선언 기능도 수행 • 변수의 선언 • 변수의 이름과 데이터 형을 알림 • 기억 장소 할당이 없음
기억 클래스 • ex) int extvar ; /* 정의 */ char extarray[100] ; /* 정의 */ extern int extvar ; /*선언, 보통 extvar은 다른 모듈에 선언*/ extern char extarray[100] ; /*선언*/
기억 클래스 • 정적 변수(static variable) • 지역 변수의 값을 유지하기 위해 사용 • 프로그램의 종료 후에도 그 값이 소멸되지 않고 보관되며 다시 호출될 때에는 그 직전의 값 참조 • ex) static int c ; • register 변수 • 기억할 자료의 값을 메모리에 저장하는 대신 직접 CPU내의 기억장소인 레지스터내에 기억 : performace측면 • int형과 unsigned int 형만 가능
기억 클래스 예제(static 변수) #include <stdio.h> void test() { static int s_count = 0; int a_count = 0; s_count++; a_count++; printf("static count = %dcount = %d",s_count,a_count); } main() { int I; for(i=1; i<=10;i++) test(); }
예제 (Factorial) #include <stdio.h> double fact(); /* 함수 선언 */ main() { int n = 0; /* 내부변수의 선언 */ do { printf("양수 입력:"); scanf("%d",&n); if (n<0) return(0); /*입력된 수가 0보다 작*/ fact(n); /* 으면 프로그램 종료 */ printf("\n"); } while (1); /* 조건이 1(참)이므로 무한루프 */ }
예제(con’d) double fact( int k ) { register int i; /* 레지스터 변수 선언 */ double s = 1; for (i = 1;i <= k;i++) { s *= i; printf("%3d! => %16.0f\n",i,s); } return(s); }