C Programming 전처리 (Preprocessing) Seo, Doo-Ok Clickseo.com clickseo@gmail.com
목 차 C 전처리기 조건및분할컴파일 2
C 전처리기 C 전처리기 매크로상수 매크로함수 조건및분할컴파일 3
전처리 (Preprocessing) C 전처리기 (1/3) 원시소스파일을컴파일하기전에행해야할일련의작업 외부파일포함기능 : #include 매크로상수 : #define 조건부컴파일 (conditional compile) 시스템내장매크로사용 C 컴파일러 전처리기 (Preprocessor) 와번역기 (Translator) 로구성 전처리는컴파일러가동작하기전단계에서작업이이루어진다. 4
프로그램예제 : 전처리개념의적용 C 전처리기 (2/3) #include <stdio.h> # 전처리사용시 #define PI 3.14159 int main(void) double // 매크로상수 area, radius; 프로그램수정용이 전체적인프로그램구조의간결성유지 printf(" 원의반지름입력 : "); scanf("%lf", &radius); area = radius * radius * PI; printf("\n 원의면적 %.2f\n", area); return 0; 5
C 전처리기 (3/3) #define preprocessing (macro expansion) #define MAX_SIZE 1024 #define MAX_SIZE 1024 #define ADD(a, b) ((a) + (b)) #define ADD(a, b) ((a) + (b)) int main(void) int main(void) char str[max_size]; char str[1024]; int res; int res; res = ADD(10, 20); res = 10 + 20; return 0; return 0; 6
매크로상수 매크로상수 매크로상수정의예 #define MAX_SIZE 100 #define PI 3.14159 #define TITLE Hi~ Clickseo // 정수형상수정의 // 실수형상수정의 // 문자열상수정의 #define ESC 0x1b #define CR 0x0d #define LF 0x0a // ESC 키에대한 ASCII 코드 // 캐리지리턴 // 라인피드 #define TRUE 1 #define FALSE 0 // Boolean 값 true // Boolean 값 false 7
매크로함수 (1/3) 매크로함수 매크로함수정의 함수호출에따르는시간적부담이적다. #define ADD(a, b) ((a) + (b)) 함수의내용 함수의몸체정의 ( 괄호를생략주의 ) 인자리스트 일반함수의형식인자와동일단, 자료형을명시하지는않는다. 인자가없을수는있지만괄호를생략할수는없다. 함수명 가급적대문자로작명하여일반함수와구분해주는것이좋다. sum = ADD(10, 20); sum = (10 + 20); preprocessing (macro expansion) 8
매크로함수 (cont d) 매크로함수 (2/3) 매크로에의환치환은문자열내에서는이루어지지않는다. #include <stdio.h> #define ADD(a, b) printf( a + b = %d \n", a + b) int main(void) ADD(3, 4); #include <stdio.h> #define OUTPUT(expr) printf(#expr = %d, expr) return 0; #define ADD(a, b) printf(#a "+" #b "=%d \n", a + b) int main(void) ADD(3, 4); return 0; 9
매크로함수 (cont d) 매크로함수 (3/3) ## : 토큰을결합할때사용 토큰 (token) : 컴파일러가인식하는의미를지니는문자나문자열의최소단위 ( 변수나함수의이름을동적으로작성하기위하여사용 ) #define CAT(a, b) a##b res = CAT(n, Value); 문장은 res = nvalue; 의문장으로처리된다. 10
조건및분할컴파일 C 전처리기 조건및분할컴파일 조건컴파일 시스템내장매크로 분할컴파일 11
조건컴파일 (1/4) 조건컴파일 (conditional compile) 특정조건을만족할경우에지정한범위내의문장을컴파일 조건컴파일지시자사용형식 를사용하지않기때문에 #endif 생략불가 ++, --, &, * 와기타복합연산자사용제한 #ifdef 와 #ifndef는 #if defined( 매크로명 ), #if!defined( 매크로명 ) #if 상수식 #1 실행문장영역 #1 #elif 상수식 #2 실행문장영역 #2 #else 실행문장영역 #n #endif #ifdef 매크로명실행문장영역 #1 #elif 상수식1 실행문장영역 #2 #else 실행문장영역 #n #endif #ifndef 매크로명실행문장영역 #1 #elif 상수식1 실행문장영역 #2 #else 실행문장영역 #n #endif 12
프로그램예제 : #undef 지시문 #include <stdio.h> 조건컴파일 (2/4) #define SIZE 100 #define OUTPUT(temp) printf("%d\n", temp); int main(void) int a, b; a = SIZE; OUTPUT(a); #ifdef SIZE #undef SIZE #endif #define SIZE 200 b = SIZE; PRINT(b); return 0; // #undef : 이미정의된매크로기능을없던일로되돌린다. #ifdef TITLE #undef TITLE #endif #define TITLE COMPUTER SCIENCE 13
조건컴파일 (cont d) #error 조건컴파일 (3/4) 오류가발생할경우오류메시지를출력하기위한용도로사용 #error 문을만나면컴파일을즉시중단하고, 시스템에서미리정의한오류메시지의일부로 errmsg 를포함하여출력한다. #if REQUIRED_MEMORY > 1024 #else #error OOPs! This program can be used with 1024 RAM #endif #line 현재컴파일되고있는프로그램의행번호와파일명을변경하고자할때사용한다. #line 1000 Clickseo..c // 다음라인을 1001번라인으로파일명은 Clickseo.c 로설정 #error see this error message 에러가자주발생하는영역 14
조건컴파일 (cont d) #pragma 조건컴파일 (4/4) 컴파일러에게특수한기능이나동작을수행하게끔지시하는용도 #pragma warn -rvl // Function should return a value 경고를발생하지못하게한다. #pragma warn +cln // long 형상수에접미사 L 을붙이지않으면경고를발생케한다. 주의 : 컴파일러의종류에따라용법에차이가있다. 15
시스템내장매크로 (1/3) 시스템내장매크로 시스템에서제공하는미리내장된매크로 내장매크로 기능 STDC 컴파일러의 ANSI C 표준준수여부 (1 이면준수 ) FILE LINE 현재컴파일되고있는파일의이름 현재컴파일되고있는프로그램의행번호 DATE 컴파일날짜 ( 월, 일, 년 ) TIME 컴파일이시작된시간 ( 시 : 분 : 초 ) TIMESTAMP 컴파일이시작된날짜와시간 16
시스템내장매크로 (2/3) 프로그램예제 : 시스템내장매크로사용예 #1 #include <stdio.h> int main(void) printf("compile Information: %s, line: %d, on %s, at %s\n", FILE, LINE, DATE, TIME ); #line 1000 "seethis.c" printf("changed compile Information\n"); printf("compile Information: %s, line: %d, on %s, at %s\n", FILE, LINE, DATE, TIME ); return 0; 17
시스템내장매크로 (3/3) 프로그램예제 : 시스템내장매크로사용예 #2 #include <stdio.h> int main(void) printf(" 현재컴파일되고있는날짜 : %s\n", DATE ); printf(" 현재컴파일되고있는시간 : %s\n", TIME ); printf(" 현재컴파일되고있는날짜와시간 : %s\n", TIMESTAMP ); printf(" 파일명 : %s\n", FILE ); printf(" 현재라인 : %d\n", LINE ); #ifdef STDC printf(" 현재컴파일러는 ANSI 표준 \n"); #else printf(" 현재컴파일러는 ANSI C 표준의확장 \n"); #endif return 0; 18
단일컴파일환경 라이브러리모듈파일 (Library Module File) 분할컴파일 (1/8) a.c 컴파일러 (Compiler) 링커 (Linker) 로더 (Loader) 원시파일 (Source File) a.obj exe 목적파일 (Object File) 실행파일 (Executable File) 실행 (Execution) hello.c hello.obj hello.exe 19
분할컴파일환경 분할컴파일 (2/8) 라이브러리모듈파일 (Library Module File) 1.c 컴파일러 (Compiler) 1.obj 2.c 컴파일러 (Compiler) 2.obj 링커 (Linker) exe 로더 (Loader) 3.c 컴파일러 (Compiler) 3.obj 원시파일 (Source File) 목적파일 (Object File) 실행파일 (Executable File) 실행 (Execution) 20
분할컴파일 (3/8) #include 외부의헤더파일 (.h) 에정의된내용을현재프로그램의내부로포함시키는역할 #include< 시스템정의파일명 > #include 사용자정의파일명 #include <stdio.h> #include <stdlib.h> #include test.h #include C:\clickseo\test.h // 단, 절대경로의사용은좋은습관이아니다. #include /home/clickseo/my_c/include/test.h // UNIX 21
#define MAX_SIZE 3 #ifndef SCORE_H_ #define SCORE_H_ typedef struct _score char name[12]; int kor, eng, math, tot; float ave; SCORE; #endif score.h void INPUT(SCORE *); void OUTPUT(SCORE *); #include "score.h" int main(void)... #include <stdio.h> #include "score.h" void INPUT(SCORE *p)... #include <stdio.h> #include "score.h" void INPUT(SCORE *p)... main.c input.c output.c main.obj input.obj output.obj score.exe 22
분할컴파일 (5/8) 프로그램예제 : #include 적용 score.h #define MAX_SIZE 3 #ifndef SCORE_H_ #define SCORE_H_ typedef struct _score char name[12]; int kor, eng, math, tot; float ave; SCORE; #endif void INPUT(SCORE *); void OUTPUT(SCORE *); 23
분할컴파일 (6/8) 프로그램예제 : #include 적용 main.c #include "score.h" int main(void) SCORE arr[max_size]; INPUT(arr); OUTPUT(arr); return 0; 24
분할컴파일 (7/8) 프로그램예제 : #include 적용예 input.c #include <stdio.h> #include "score.h" void INPUT(SCORE *p) int i; for(i=0; i<max_size; i++, p++) printf("\n %d 번째학생성적입력... \n", i+1); printf(" 학생이름 : "); gets(p->name); printf(" 국어점수 : "); scanf("%d", &p->kor); printf(" 영어점수 : "); scanf("%d", &p->eng); printf(" 수학점수 : "); scanf("%d%*c", &p->math); p->tot = p->kor + p->eng + p->math; p->ave = (float)p->tot / 3; return; 25
분할컴파일 (8/8) 프로그램예제 : #include 적용예 output.c #include <stdio.h> #include "score.h" void OUTPUT(SCORE *p) int i; printf("\n \t ### 학생성적 ### \n"); for(i=0; i<max_size; i++, p++) printf("%10s %3d %3d %3d %5d %8.2f \n", p->name, p->kor, p->eng, p->math, p->tot, p->ave); return; 26
참고문헌 [1] 서두옥, 이동호 ( 감수 ), ( 열혈강의 ) 또하나의 C : 프로그래밍은셀프입니다, 프리렉, 2012. [2] Paul Deitel, Harvey Deitel, "C How to Program", Global Edition, 8/E, Pearson, 2016. [3] SAMUEL P. HARBISON Ⅲ, GUY L. STEELE, C 프로그래밍언어, C : A Reference Manual, 5/E, Pearson Education Korea, 2005. [4] 문병로, 쉽게배우는알고리즘 - 관계중심의사고법, 개정판, 한빛아카데미, 2018. [5] 주우석, CㆍC++ 로배우는자료구조론, 한빛아카데미, 2015. [6] Behrouz A. Forouzan, Richard F. Gilberg, 김진외 7인공역, 구조적프로그래밍기법을위한 C, 도서출판인터비젼, 2004. [7] Brian W. Kernighan, Dennis M. Ritchie, 김석환외 2인공역, The C Programming Language, 2/E, 대영사, 2004. [8] 김일광, C 프로그래밍입문 : 프로그래밍을모국어처럼유창하게, 한빛미디어, 2004. [9] 정재은, " 다시체계적으로배우는 C 언어포인터 ", 정보문화사, 2003. 이강의자료는저작권법에따라보호받는저작물이므로무단전제와무단복제를금지하며, 내용의전부또는일부를이용하려면반드시저작권자의서면동의를받아야합니다. Copyright Clickseo.com. All rights reserved. 27