파일 분할을 이렇게 하는 이유가 뭔가요?

jonyon의 이미지

C언어 문법을 공부할땐 별 생각없이 지나갔던 파일 분할 파트를 다시 보고 있습니다.

제가 이해하고 있는 것으로는
1. 헤더파일에 함수 원형을 넣는 것은 좋지 않다
2. 사용자 정의 자료형은 헤더파일에 넣는것이 좋다
3. 큼직큼직한 함수들을 묶어 따로따로 파일을 분할하는 것이 좋다.

이 정도 인데요.

이해가 안되는건 전처리 과정입니다.

예를 들어 main함수에서 Big_Func()를 호출한다 하면

main.c

#include "Funcs.h"
 
int main(...) {
 ...
 Big_Func();
 ...
}

Funcs.h

...자잘한 다른 선언들
int Big_Func(...);

Big_Func.c

#include "Funcs.h"
 
...Big_Func.c에서 호출할 자잘한 함수들
 
int Big_Func(...){
 ...
}

이런식으로 예제를 보여주던데
main.c에서 Funcs.h를 인클루드하는건 이해가 됬어요.
그런데 Big_Func.c에서 뭐하러 Funcs.h를 인클루드 하는건지 모르겠습니다.
인클루드 안해도 컴파일할때 경고나 에러도 안뜨던데...

제가 생각하기에는 Big_Func()에서 사용할 사용자 정의 자료형이 Funcs.h에 정의되어 있을까봐 그런거같은데...
Big_Func()에서 사용할 사용자 정의 자료형이 Funcs.h에 없다면 굳이 Funcs.h를 인클루드할 필요 없는것 아닌가요?

음.. 글 쓰다보니 질문이 두개가 되서 정리합니다.

1. Big_Func.c에서 Funcs.h를 인클루드 하는 이유가 뭔가요?
2. 만약에 사용자 정의 자료형때문에 Funcs.h를 인클루드하는거라면, Big_Func.c에서 Funcs.h를 호출할 필요는 없죠?

익명 사용자의 이미지

1. 헤더파일에 함수 원형을 넣는 것은 좋지 않다

함수 원형 선언은 헤더파일에 들어가는게 정상입니다.
"함수 정의를 넣는 것은 좋지 않다"가 맞습니다.
실제로는 좋지 않은 정도가 아니라 거의 대부분 에러가 뜹니다.
단, 매크로 함수나 C++의 템플릿의 정의는 그 반대로 헤더파일에 들어가야 합니다.

2. 사용자 정의 자료형은 헤더파일에 넣는것이 좋다

다른 모듈(.o)에서 참조가 필요할 때 그렇습니다. 해당 모듈 내부에서만 쓰는 자료형이라면 .c에 넣어도 상관 없습니다.

3. 큼직큼직한 함수들을 묶어 따로따로 파일을 분할하는 것이 좋다.

'큼직큼직한'의 기준이 뭔지 모르겠습니다만,
어차피 링크 과정에서 다 합쳐지므로 크기를 기준으로 나누는 것은 별 의미가 없습니다.
기능별로 의미별로 묶는게 보통입니다.

4. Big_Func.c에서 Funcs.h를 인클루드 하는 이유가 뭔가요?

가지고 있는 C언어 책의 함수 선언 부분에 대해 읽으십시오.

5. 만약에 사용자 정의 자료형때문에 Funcs.h를 인클루드하는거라면, Big_Func.c에서 Funcs.h를 호출할 필요는 없죠?

할 필요가 없을 때도 있습니다. 그러나 질문 내용을 보건대 님은 그런 구분을 할 능력이 없습니다.
.h에 꼬박꼬박 모든 함수의 원형 선언을 적어주고, .c에서는 그 헤더파일을 include 하도록 작성하십시오.

jonyon의 이미지

1번은 용어를 헷갈렸습니다 ㅋㅋㅋ... 좀 무안하네요
3번에서 큼직큼직하다는것은 전체 프로그램에서 그 함수의 역할이 차지하는 비중을 말하는거였습니다.
말씀하신대로 '기능별로 묶는다'는게 좀더 매끄러운표현이 맞는거 같네요.
그리고 1번~3번은 질문이 아니었습니다.
그래도 지적해주신건 감사히 받아들이겠습니다.

4번이 제일 주된 질문이었는데요, 분명 어느 책을 보더라도 "정의되지 않은 함수를 호출하려면" 미리 함수 원형을 기술해야 한다고 적혀있습니다.
하지만 예시로 든 Big_Func.c에서는 그런 상황이 존재하지 않습니다.
네 물론 Big_Func.c에서 Funcs.h에 망라된 어떤 함수중에 하나를 쓸 필요가 있다면 Funcs.h를 인클루드 해야겠죠.
그 질문이 5번입니다.

이정도면 제대로 된 답변 기대할 수 있을까요? ㅎㅎ

익명 사용자의 이미지

헤더파일에는 외부함수선언과 사용자 정의형만 들어가는게 아닙니다.
그리고 컴파일시 에러나 경고가 없다고 아무 문제 없다고 생각하는건 좋은 습관이 아닙니다.

> 이정도면 제대로 된 답변 기대할 수 있을까요? ㅎㅎ

위의 답변은 제대로 된 답변이 아니란 말씀이신지?
이런 스타일이 몹시 피곤한 질문자 스타일인데,
이미 자신이 원하는 답변이 딱 정해져 있고,
그 답이 나올 때까지 계속 없던 얘기가 추가되거나 기존의 질문이 변형됩니다.
즉 순수하게 궁금해서 묻는게 아니란 얘기죠.

> 하지만 예시로 든 Big_Func.c에서는 그런 상황이 존재하지 않습니다.

맨 처음 올리신 질문에는 그걸 판단할 만한 충분한 근거가 존재하지 않았습니다.

Funcs.h

...자잘한 다른 선언들
int Big_Func(...);

Big_Func.c

#include "Funcs.h"

...Big_Func.c에서 호출할 자잘한 함수들

int Big_Func(...){
...
}

이것만 가지고는 헤더 파일이 없어도 될지 판단하기 어렵고,
질문자의 수준을 고려해서 일반적인 경우에 대한 다음과 같은 답변을 드린 것입니다.

"할 필요가 없을 때도 있습니다. 그러나 질문 내용을 보건대 님은 그런 구분을 할 능력이 없습니다.
.h에 꼬박꼬박 모든 함수의 원형 선언을 적어주고, .c에서는 그 헤더파일을 include 하도록 작성하십시오."

님이 원하는 것은 답변이 아니라
자신의 발상? 호기심? 학습 수준?에 대한 인정인 것 같군요.

jonyon의 이미지

전 답변을 받고싶어서 답변 받을수 있을까요 라고 한게 아니라 우회적으로 돌려 말한거였는데, 너무 돌려말했나보네요.
이해하지 못하셨다면 어쩔수 없이 안타까운일입니다. 이해하지 못하셔도 상관은 없습니다.

인터넷상에서 말다툼 하는게 정말 무식한 짓인건 알지만, 이건 한마디 해야겠습니다.

전 댁한테 답변을 받고싶어서 글을 올린게 아닙니다. 1:1 질문이라면 모를까, 당신에게 무시받을 이유는 없습니다.
만약에 당신이 제 선배나 선생쯤 되는 사람이었다면, 아니면 온라인상이라도 좀 검증된 실력을 가졌다고 인정할 수 있는 사람이면 무시 받더라도 그냥 이 사람과 나는 수준이 다르구나 하고 넘어갈 수 있습니다.
그런데 익명으로 굳이 시간들여서 "공부가 부족하시네요"같은 답변같지도 않은 답변을 달다니? 익명성에 기대서 시비거는걸 즐기는 것으로밖에 안보입니다.

인터넷을 이용해서 말다툼 하는것만큼 바보같은 일이 없습니다. 아무런 의미도 없는짓을 뭐하러 합니까.

그쪽이 원하는건 제가 공손하게 물러나서 '전문가의 조언 겸허히 받아들이겠습니다'하고 인정해주는것이잖아요?

익명 사용자의 이미지

> "공부가 부족하시네요"같은 답변같지도 않은 답변을 달다니?

나는 귀하에게 "공부가 부족하시네요" 같은 소릴 한적이 없습니다.
그건 귀하의 자격지심이 만들어낸 환청입니다.

귀하가 자신이 원하는 반응을 얻지 못했을 때 어떻게 나올지는 익히 예상하고 있었습니다.
유감스럽게도 귀하같은 사람을 하루 이틀 보는게 아닙니다.
그럼에도 친절하게 답변을 달아 준 것은 공개된 게시판에서 잘못된 생각이 제3자에 파급되는 것을 우려해서입니다.

> 인터넷을 이용해서 말다툼 하는것만큼 바보같은 일이 없습니다. 아무런 의미도 없는짓을 뭐하러 합니까.

근데 하고 계시네요. 왜 그러고 계십니까?

> 님이 원하는건 제가 공손하게 물러나서 '전문가의 조언 겸허히 받아들이겠습니다'하고 인정해주는것이잖아요?

하하하 귀하같은 사람한테 그런 소리 듣는건 의외로 쉽습니다.
원하는 사탕을 손에 쥐어주면 그 다음은 뭐든지 간단하죠.
굳이 그렇게 하지 않는건 그럴 필요가 없기 때문입니다.
귀하같은 사람에게 인정받으며 하하호호 하는건 제 취향이 아닙니다.

jick의 이미지

Funcs.h에서 "int Big_Func(...)"라고 써놓고 Big_Func.c에서 "void Big_Func(...)"라고 쓴다고 생각해 봅시다.

만약 해당 파일에서 Funcs.h를 #include 안했다면, 컴파일하면서 아무 에러도 안 납니다.

"에이 누가 그런 실수를 하겠어?"라고 생각하실지도 모르지만... 그런 실수 누구나 합니다. 경험이 있는 프로그래머일수록 자기가 실수를 반드시 할 거라는 걸 알기 때문에 실수가 났을 때 최대한 컴파일러가 에러를 낼 수 있도록 프로그램을 구성합니다.

jonyon의 이미지

아하 그런 깊은 뜻이!
생각해보니까 그런 경험이 몇번 있었던것 같네요.
마지막 말 "경험이 있는 프로그래머일수록 자기가 실수를 반드시 할 거라는 걸 알기 때문에 실수가 났을 때 최대한 컴파일러가 에러를 낼 수 있도록 프로그램을 구성합니다."이건 명언이네요 ㅋㅋ
꼭 기억하겠습니다.

라스코니의 이미지


1. Big_Func.c에서 Funcs.h를 인클루드 하는 이유가 뭔가요?

==> 유용한 함수를 라이브러리로 쓰기 위해서 입니다. lib, dll 로 만들던 아니면 source를 카피해서 넣던지 재활용을 하기 위해서라면 헤더 파일을 생성해야 하는거죠. 잘게 소스 파일을 쪼개야 유지보수가 쉬워지는 수도 있고요. 그럴때 소스를 유지보수가 잘 되도록 짜는 것도 중요하지만요.

2. 만약에 사용자 정의 자료형때문에 Funcs.h를 인클루드하는거라면, Big_Func.c에서 Funcs.h를 호출할 필요는 없죠?

==> 사용자 정의 자료형이라면 typedef int INT32 이런 거 인가요? 보통 회사마다 사용자 정의 자료형이 있습니다. 그것을 여러 헤더 파일에 모아놓고 프로젝트 시작시마다 그 헤더 파일을 포함하도록 하고 있습니다. #include "mycompany_common_type.h" 이런 식으로요. 자신이 만든 함수를 나중에 라이브러리로 재활용하기 위해서는 이러한 정보들이 체계적으로 관리되어야 합니다.

jonyon의 이미지

라이브러리 만드는 파트 공부하고 있는데 도움이 많이 된것 같아요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.