본문 바로가기
C언어/C언어

[C언어]C언어에서 헤더파일이 필요한 이유?(헤더파일 필요성)

by Oliver_Candy 2023. 2. 16.

 


 헤더파일 이란

C언어에서는 두 종류의 소스코드 파일이 있다. (.h 와 .c)

이 두 파일을 비교해 보면 다음과 같다.

C파일 (.c) 헤더 파일 (.h)
  • 실제 프로그램을 돌게하는 로직 코드를 저장하는 파일
  • 내용(함수 정의(=함수 구현), 매크로, 변수, 전역변수등)
  • 여러 소스코드 파일에 공통적으로 필요한 것들을 저장하는 파일
  • 내용(함수 선언, 매크로, extern 변수 선언등)
  • #include 로 헤더파일을 인클루드 함

여기서 C파일과 헤더 파일은 그냥 합쳐서 하나의 파일로 만들면 되지 않을까?라는 생각이 들 수 있다.

 

 

 

 

 헤더파일의 필요성

  • 없어도 되지만 있는 것이 더 편해서
  • 프로그래머들은 한 파일 안에 모든 코드들을 넣기보다 체계적으로 나누어서 넣는 것을 좋아한다. 그렇기에 연관된 기능끼리 모아서 .c 파일을 저장하면서 여러 .c 파일이 생기게 된다. 이때 동일한 함수를 여러 파일에 써야 하는 경우가 생긴다면 복붙을 해야 할 까?
  • No! 복붙하고 수정할 때, 하나를 빼먹고 안 해버릴 수도 있고 관련된 여러 파일이 너무 많으면 모두 고치기에도 귀찮기에 유지 보수에 어려움이 생긴다
  • 이럴 때, 함수가 선언된 헤더파일을 인클루드 한다면 여러 파일과 공유가 가능하다. (C#은 이걸 Tool에서 해주기에 헤더파일이 없고 cs파일 하나만 있는 것이다.)

 

 

 

.c 와 .h 사용예시를 다음 코드로 보이겠다.

 

/* main.c */
int main(void)
{
	/* 코드 내용 생략 */
}
/* monster.c */
#include "action.h"

/* 다른 코드 생략 */
walk(10.0f, west);
/* player.c */
#include "action.h"

/* 다른 코드 생략 */
walk(20.0f, east);
/* action.h */
void walk(float speed, direction dir);
/* action.c */
void walk(float speed, direction dir)
{
	/* 코드 내용 생략 */
}
  • monster.c 파일과 player.c파일은 모두 walk라는 함수를 공통적으로 필요로 한다
  • 이 동일한 함수를 각 파일에 복붙을 하게 된다면? => 유지, 보수에 어려움이 발생하기에 이 함수를 사용할 수 있게 헤더파일(action.h)을 만들어서 함수 선언을 해준다
  • 그리고 monster.c 와 player.c에 #include "action.h"를 해준다
  • 이렇게 된다면 이 walk함수를 수정하게 되는 경우가 발생하더라도 함수 정의가 있는 action.c함수를 수정하고 action.h에서 선언을 맞춰준다면 monster.c 와 player.c 파일에서는 코드 수정 없이 walk함수를 계속 사용할 수 있다.

 결론

파일(action.c)에서 함수가 바뀌더라도 헤더파일에서 원형만 바꾸면 monster.c 와 player.c 에서 그대로 사용할 수 있기 때문에 헤더파일에 원형을 넣는다.

 

 

 

이렇게 설명하면 이런 궁금증이 생길 수 있다

함수 선언(=함수 원형)만으로 함수 정의를 어떻게 알아서 찾을 수 있나요?

해놨으니 나중에 다른 애(링커)가 함수 정의를 찾아주겠지 하고 채워달라는 표현으로 구멍을 만들어 놓기 때문에 컴파일러에서는 해결이 되고 나중에 오브젝트 코드들을 모두 합쳐서 링커가 함수 정의를 알아서 찾아 구멍을 메꿔준다. 그렇기 때문에 컴파일과정에서 오류가 발생하지 않는다.

 

 

출처 : POCU Academy COMP2200

댓글