선언과 정의란?
먼저 main.cpp 파일에서 cal.cpp 파일에 구현되어 있는 sum 함수를 호출해보려고 할 때 어떻게 하면 되는지 알아보겠습니다. cpp파일을 컴파일러가 컴파일 할 때는 위에서 부터 읽으면서 코드를 실행시킬 수 있도록 변환 해줍니다.
main() 함수가 실행되기 전에 sum 함수가 있기 때문에 아래 코드의 경우에는 오류없이 실행이 되는 것을 확인할 수 있을거에요.
//main.cpp
#include <iostream>
// function
int sum(int x, int y) {
return x+y;
}
int main() {
int y = sum(3,4); /* Use the function here */
printf("%d\\n", y);
return 0;
}
하지만 아래의 경우에는 컴파일이 제대로 될 까요?! 컴파일러는 위에서 부터 순차적으로 complile 하기 때문에, 아래의 경우에는 main 함수에서 sum을 호출할 때 sum이 무슨 함수인지 알 수 없어서 빌드가 안되는 에러가 발생합니다.
main.cpp: In function ‘int main()’:
main.cpp:5:13: error: ‘sum’ was not declared in this scope
5 | int y = sum(3,4); /* Use the function here */
|
이런.. 코드의 위치를 잘못두어서 에러가 발생하게 되는거네요? 그럼 이런 컴파일 에러를 방지하기 위해서 그리고, 코드를 읽기 쉽게 하기 위해서 필요한 것이 바로 선언과 정의를 나누어서 작성해주는 것 입니다.
5번째 줄에 함수의 모양(prototype)을 “선언” 해주고, 그 선언에 대한 동작을 하는 실제 코드 부분을 아무 곳에나 “정의” 하는 방식으로 분리 하여 작성합니다.
파일을 나누어 선언 / 정의 하기
모든 함수의 선언과 정의를 하나의 main.cpp 파일에서 관리하는 것은 가능합니다. 하지만 많은 분들은 하나의 파일에서 모든 기능을 관리하지 않습니다. 아니 관리하기가 힘들다고 해야겠네요 ㅎㅎ.. 그래서 파일을 나누어 관리합니다. 예를 들어서 수를 계산하는 함수들은 calculate.cpp 에 모아서 관리 하고,
문자열 관련 함수들은 string_manager.cpp 파일에 모아서 관리할 수 있습니다.
예를 들어서 main.cpp에는 선언 부분을 남겨두고, 실제 정의(함수 동작)은 calculator.cpp 파일에 작성하는 거에요.
이렇게 선언과 정의를 나누어 작성하면 보다 깔끔하게 코드를 관리할 수 있게 되었습니다.
다음으로는 header 파일을 사용해 보겠습니다.
헤더 파일을 사용하는 이유는?
리눅스 커널 등 프로젝트의 규모가 큰 코드를 살펴보면, 헤더파일에 함수 및 클래스들이 헤더파일에 분리되어 선언되어 있습니다. 왜 그렇게 구성을 할 까요? 동일한 기능을 하는 함수가 있을 때 이 함수를 각 파일마다 선언하여 사용하는 것 보다는, 특정 파일에 선언 및 구현을 해두고 그 파일을 include 하여 사용하면 재사용성 할 수 있기 때문입니다.
아래와 같이 작성하여 컴파일을 하면 되는데요, 이렇게 작성한 경우에는 헤더파일을 include 하여 여러 파일에서 재사용 하여 사용할 수 있게 됩니다.