C 프로그래밍프로젝트 Chap 27. 파일의분할과헤더파일의디자인 2013.09.11. 오병우 컴퓨터공학과
설계 (design) 중요 27-1 프로그램의모듈화 변경, 확장등의유지보수가용이하도록설계 C 언어에서는 module 구성중요 C++, Java 등의객체지향언어에서는 class, abstraction 중요 Design Patterns 에대해 2 학년여름방학이나겨울방학에공부해보시기바랍니다. 모듈 (module) 이란무엇인가? 프로그램을구성하는구성요소의일부 관련된데이터와함수들이묶여서모듈을형성한다. 파일단위로나뉘는것이보통 모듈화 (modular) 프로그래밍 기능별로파일을나눠가며프로그래밍하는것 유지보수성이좋아진다. Department of Computer Engineering 2
3 27-1 프로그램의모듈화 파일의분할및컴파일 파일을나눌지라도완전히독립되는것은아니다. 파일이나뉘어도상호참조가발생할수있는데, 이는전역변수및전역함수로제한된다. 외부파일의변수 / 함수참조시 extern 선언
모듈구성예제 Home theater DVDPlayer.h Amplifier.h LCD.h DVDPlayer.c Amplifier.c LCD.c Department of Computer Engineering 4
Home theater 모듈구성예제 DVD Player 를 Blu-ray Player 로업그레이드 BluRayPlayer.h Amplifier.h LCD.h BluRayPlayer.c Amplifier.c LCD.c Department of Computer Engineering 5
모듈구성예제 Home theater 42 LCD 모니터를 100 Projector 로업그레이드 다른부분과독립적으로변경할수있도록설계할것 BluRayPlayer.h Amplifier.h Projector.h BluRayPlayer.c Amplifier.c Projector.c Department of Computer Engineering 6
7 27-1 프로그램의모듈화 파일의분할및컴파일 컴파일 : 변경사항이있는파일만별도컴파일 링크 : 실행파일을만들기위해모든 object 파일을모아서링크 extern 선언된함수나변수를찾아서연결 외부접근금지 static 키워드에의한접근의제한
8 27-2 헤더파일의구현과유용성 헤더파일 (header file) 의포함 (include) 이지니는의미 선행처리기에의해하나의파일을다른하나의파일에포함시키는작업
27-2 헤더파일의구현과유용성 헤더파일포함방법 <file> : 표준디렉토리파일포함 Linux: /usr/include 옵션에서 include 디렉토리추가할수있음 Visual C: \Microsoft Visual Studio\VC98\Include file : 현재디렉토리또는지정된경로에존재하는파일포함 / (slash) 추천, \ (back slash), \\ 모두사용가능 #include <abc.h> #include plus.h #include c:/include/abc.h #include..\plus.h // 표준디렉토리 // 현재작업디렉토리에있는 plus.h 포함 // c:\include에서 abc.h 포함 // 현재의상위디렉토리에있는 plus.h 포함 Department of Computer Engineering 9
27-2 헤더파일의구현과유용성 헤더파일의정의 여러소스파일에서공통으로사용되는선언의집합 include extern 변수및함수 구조체및 typedef (22, 23 장 ) 왜헤더파일을사용하는가? 선언의간략화 파일변경최소화! 주의 함수를사용하려는.c 파일이많을때, 함수의인자가변경되면모든.c 파일을수정해야함 Header file 를사용하면.h 만수정하면됨 (.c 에서는.h 를 include) 중복선언이되지않도록한다! 조건부컴파일로해결 (#ifdef, #ifndef, #else, #endif) 26 장참조 Department of Computer Engineering 10
27-2 헤더파일의구현과유용성 Department of Computer Engineering 11
calc.h 27-2 헤더파일의구현과유용성 extern int cal_num; double add (double a, double b); double minus (double a, double b); double multiple (double a, double b); double divide (double a, double b); calc.c int cal_num = 0; cal_main.c #include <stdio.h> #include calc.h int main (void) double a = 10.2; double b = 2.1; double add (double a, double b) cal_num++; return a+b; double multiple (double a, double b) printf ( 덧셈 : %f\n, add(a, b)); printf ( 총연산수 : %d\n, cal_num); return 0; Department of Computer Engineering 12
헤더파일사용예제 DVD 에서 Amplifier 를거치지않고바로 LCD 로출력 DVDPlayer.h Amplifier.h LCD.h DVDPlayer.c #include LCD.h Amplifier.c LCD.c char *playergetframe() void outsetframe(char *f) void *playerprocessframe() outsetframe(current); Department of Computer Engineering 13
헤더파일사용예제 DVD-Amplifier-LCD 순으로화면출력 DVDPlayer.h Amplifier.h LCD.h DVDPlayer.c char *playergetframe() Amplifier.c #include DVDPlayer.h #include LCD.h void ampprocessframe() p = playergetframe(); outsetframe(p); LCD.c void outsetframe(char *f) Department of Computer Engineering 14
DVD Player 모듈별헤더파일사용예제 DVDPlayer.h Amplifier.h LCD.h DVDPlayer.c char *playergetframe() Amplifier.c #include DVDPlayer.h #include LCD.h void ampprocessframe() p = playergetframe(); outsetframe(p); LCD.c void outsetframe(char *f) Department of Computer Engineering 15
모듈별헤더파일사용예제 Blu-ray Player 로업그레이드 Amplifier 모듈에서 include 변경 BluRayPlayer.h Amplifier.h LCD.h BluRayPlayer.c char *playergetframe() Amplifier.c #include BluRayPlayer.h #include LCD.h void ampprocessframe() p = playergetframe(); outsetframe(p); 변경없음 LCD.c void outsetframe(char *f) Department of Computer Engineering 16
공통헤더파일사용예제 공통인터페이스 (Interface) DVD Player 모듈과 Blu-ray Player 모듈에서공통적으로쓰는인터페이스를 Player.h 에저장하고있다면 include 를변경하는것도필요없음 Player.h Amplifier.h LCD.h 프로젝트에어떤.c 파일을넣을지에의해결정 BluRayPlayer.c DVDPlayer.c Amplifier.c #include Player.h 변경없음 LCD.c char *playergetframe() char *playergetframe() #include LCD.h void ampprocessframe() p = playergetframe(); outsetframe(p); 변경없음 void outsetframe(char *f) Department of Computer Engineering 17
27-3 조건부컴파일 #if, #elif, #else, #endif 기반조건부컴파일 컴파일하기전에실제컴파일할소스부분을지정 #if CONDITION1 expression1 #elif CONDITION2 expression2 #else expression3 #endif Department of Computer Engineering 18
27-3 조건부컴파일 헤더파일포함관계에서발생하는문제 중첩된관계로인해하나의헤더파일을두번이상포함하면 중복해서함수가정의되거나, 변수가선언되는문제점 중복을피해헤더파일을만들기는생각보다어렵다. 조건부컴파일로문제해결! Department of Computer Engineering 19
27-3 조건부컴파일 #ifndef, #endif 기반조건부컴파일 extern int GetCount(); int GetCount(); 함수선언하고 Department of Computer Engineering 20
기본적인모듈분리 정답이있는것은아님 MVC 디자인패턴참조 크게 3 모듈로분리하고점차세분화하여설계할것 App (Application) main() 함수를통해전체적인프로그램의흐름담당 Doc (Document) 응용프로그램에서처리하는데이터를관리하고 business logic 처리 기능별모듈로분리 View 눈에보이는부분처리 입력및출력 ( 분리가능 ) 추가모듈 Err (Error) 에러처리모듈 File 처리모듈 처리해야하는 file 종류별로모듈구성 Department of Computer Engineering 21
모듈구성예제 #ifndef _DOC_H_ #define _DOC_H_ // struct, typedef, enum 등 --------- // public functions --------------- // 모듈초기화 extern void docinit(); // 모듈종료처리 extern void docclose(); // Getter functions extern int docgetdata(); // Setter functions extern void docsetdata(int); #endif // _DOC_H_ Doc.h #include Doc.h // static variables --------------- static int docdata; // public functions --------------- // 모듈초기화 void docinit() // 변수초기화등 // 모듈종료처리 void docclose() // Getter functions int docgetdata() return docdata; // Setter functions void docsetdata(int a) docdata = a; Doc.c Department of Computer Engineering 22
함수호출예제 다른모듈의 extern 함수를호출하면서프로그램실행 모듈의데이터는 static으로만들어서보호 Getter 및 Setter 함수를 extern으로제공 Doc.c Extern docsetdata() Call Input.c #include Doc.h InputData() Extern Main.c #include Input.h #include View.h Write docgetdata() Read docdata Static Encapsulation Call View.c Extern Display() #include Doc.h -Doc.c 에서데이터를읽으면서화면출력 Call main() Department of Computer Engineering 23
Naming Convention 정답이있는것은아님 변수및함수이름부여규칙을미리정해놓을것 공통 ( 예제 ) 변수는명사로시작, 함수는동사로시작 단어가변경될때대문자로시작 예제, docgetdata() Local variable 과 global variable 을구분할수있도록이름붙일것 예를들면, local variable 은소문자로시작, global variable 은대문자로시작 예를들면, Global variable 은 g 로시작 ( 예제, gcount) 모듈별이름부여 모듈을구분할수있도록함수앞에 doc, view 등의 prefix 를붙임 예제, docgetdata() Department of Computer Engineering 24