이번 포스팅에서는 전처리문 #ifndef을 이용하여 header파일의 중복을 막는 방법을 포스팅하겠다.
먼저 #ifndef이 적용된 예제파일을 먼저 보겠다.
_ #ifndef을 이용한 예제
1. coordinate.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #ifndef COORDINATE #define COORDINATE #include <stdio.h> struct coordinate{ int x; int y; }; void print_coordinate(struct coordinate *coord); #endif | cs |
2. coordinate.c
1 2 3 4 5 6 7 | #include "coordinate.h" void print_coordinate(struct coordinate *coord){ printf("X: %d\n", coord->x); printf("Y: %d\n", coord->y); } | cs |
3. main.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include <stdio.h> #include "coordinate.h" int main(void){ struct coordinate coord; coord.x = 5; coord.y = 3; print_coordinate(&coord); return 0; } | cs |
4. Makefile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | VPATH=./ EXEC=main OBJDIR=./ CC=gcc CFLAGS=-Wall -Wfatal-errors OBJ=coordinate.o main.o OBJS = $(addprefix $(OBJDIR), $(OBJ)) DEPS = $(wildcard ./*.h) Makefile all: obj results $(EXEC) $(EXEC): $(OBJS) $(CC) $(COMMON) $(CFLAGS) $^ -o $@ $(LDFLAGS) $(OBJDIR)%.o: %.c $(DEPS) $(CC) $(COMMON) $(CFLAGS) -c $< -o $@ obj: mkdir -p obj results: mkdir -p results .PHONY: clean clean: rm -rf $(OBJS) $(EXEC) | cs |
해당 코드는, coordinate라는 구조체를 선언하고, 이를 출력해주는 함수를 coordinate.h, coordinate.c에 넣어놓고, 이를 main.c에서 참조해서 사용하는 프로그램이다.
Makefile을 이용해서 make에서 프로그램을 실행시켜보면 다음과 같은 결과를 출력한다.
예제가 잘 작동하는 것을 확인했다.
이제 왜 #ifndef이라는 전처리문을 사용하는지 다음 예제를 이용해서 확인해보자.
_ #ifndef이 없는 예제
1. coordinate.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | //#ifndef COORDINATE //#define COORDINATE #include <stdio.h> struct coordinate{ int x; int y; }; void print_coordinate(struct coordinate *coord); //#endif | cs |
2. coordinate.c
1 2 3 4 5 6 7 | #include "coordinate.h" void print_coordinate(struct coordinate *coord){ printf("X: %d\n", coord->x); printf("Y: %d\n", coord->y); } | cs |
3. main.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <stdio.h> #include "coordinate.h" #include "coordinate.h" int main(void){ struct coordinate coord; coord.x = 5; coord.y = 3; print_coordinate(&coord); return 0; } | cs |
4. Makefile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | VPATH=./ EXEC=main OBJDIR=./ CC=gcc CFLAGS=-Wall -Wfatal-errors OBJ=coordinate.o main.o OBJS = $(addprefix $(OBJDIR), $(OBJ)) DEPS = $(wildcard ./*.h) Makefile all: obj results $(EXEC) $(EXEC): $(OBJS) $(CC) $(COMMON) $(CFLAGS) $^ -o $@ $(LDFLAGS) $(OBJDIR)%.o: %.c $(DEPS) $(CC) $(COMMON) $(CFLAGS) -c $< -o $@ obj: mkdir -p obj results: mkdir -p results .PHONY: clean clean: rm -rf $(OBJS) $(EXEC) | cs |
해당 코드는 첫번째 예제와는 다르게 #ifndef을 주석처리하고, main.c에서 coordinate.h를 두번 넣은 것을 제외하고는 같은 파일이다.
해당 코드를 make해서 결과를 확인하면 다음과 같다.
다음과 같이 coordinate.h:6:8 error: redefinition of 'struct coordinate'라는 에러를 출력한다.
해당 구조체가 재 선언되었다고 이야기하고있다.
해당 코드와 같은 작은 프로그램의 경우야 이를 확인하는게 크게 어렵지 않지만,
대규모 프로그램에서 다음과 같이 헤더파일의 중복 선언은 정말 찾기가 너무 힘들다.
따라서 #ifndef같은 전처리 문을 사용해서 중복 선언을 막게된다.
1 2 3 4 5 6 7 | #ifndef STRING #define STRING (...) #endif | cs |
다음과 같이 #ifndef을 사용하게 되면, 코드의 흐름은 다음과 같다.
- STRING이라는 상수가 선언되어있는지 확인한다.
- 상수가 선언이 안되있다면, STRING이라는 상수를 선언한다.
- header에 들어갈 내용이 작성된다.
- 만약에 STRING이라는 상수가 선언이 안되있다면, 그냥 해당 참조는 무시하게 된다.
이런 형태를 만들어서 중복 참조를 막는게 header파일에서 #ifndef이라는 전처리문을 사용하는 핵심 이유가 된다.
그렇다면, 전처리문을 사용해보고 헤더파일을 중복참조해보자.
해당코드는 이미 제공되었기 때문에, 코드와 결과는 생략하도록 하겠다.
'IT > C|C++' 카테고리의 다른 글
[C] 외부 변수 참조, extern (0) | 2017.05.01 |
---|---|
[C] 구조체, Structure (0) | 2017.04.24 |
[C] 재귀 함수 Recursion function (0) | 2017.03.28 |
[MinGW/Eclipse c++] Compile Error (0) | 2016.06.06 |
[Eclipse C++]Install Eclipse c++/ Eclipse c++ 설치하기 (0) | 2016.06.06 |