헤더파일 관련 질문

asleea의 이미지

기초가 안되있어서 질문 드립니다.ㅜㅜ

어떤 헤더파일에서 함수를 선언하고

그 선언한 함수를 다른 파일에 따로 정의 하려고 합니다.

만약 헤더파일 이름이 as.h라고 하고 함수이름이 a()라고 하면

--as.h--
void a();
 
 
--a.c--
#include"as.h"
void a()
{
    .............;
}

로 해야되는 건가요 .?

재 기억으로는 이런식으로 했던거 같은데

위에 방법이 맞다면, 그냥 단순하게 생각하면

--as.h--
#include"a.h"
void a();
 
--a.h--
#include"as.h"
void a()
{
    ...........;
}

이런 식으로 둘다 헤더파일로 만들어서 서로 참조해야 되지 않나요 .?

내부적으로 무엇이 일어나는지 대충이라도 설명좀 .ㅜㅜ부탁 드립니다.

그리고 리눅스에서 이러한 부분을 사용하면 함수를 선언한 헤더파일하고 함수를 정의한 c파일하고 같은 폴더에 존재해야되나요 .?

shint의 이미지

이렇게 사용합니다.
#include "파일.h" //이것은 내가 만든 소스 경로에 있는 파일을 참조하는 경우
#include <파일.h> //이것은 개발툴에서 사용하는 기본 경로를 참조하는 경우. 입니다.

폴더 경로가 다를 경우는 요렇게 합니다. (개발도구'에 파일 경로'도 같이 변경해줘야 합니다.)
#include "../파일.h"//상위 경로
#include "./파일.h"//하위 경로
#include "./shint/파일.h"//하위 경로

//프로그램을 만들게 되시면 변수'와 함수 선언'은 언제나 구현된 소스의 정의부 윗 부분에 있어야 합니다.

int a = 0; //변수 선언 및 초기화
void fn_test(); //함수 선언
 
void fn_test() //함수 정의
{
    a = 1;
}

//그런데 이게 하나의 파일 안에 있으면. 보기가 불편해요. 길거든요. 그래서. .h로 파일을 나눕니다.

//a.h
int a; //변수 선언
void fn_test(); //함수 선언
 
//a.cpp
#include "a.h" //a.h에 선언'을 몰아 넣는겁니다.
a = 0; //변수 초기화
void fn_test() //함수 정의
{
    a = 1;
}

//이걸 보면. 지금 위에 적어주신대로. 역으로 include를 하게되면. 선언'하는게 위아래로 중복되고. 소스가 뒤죽 박죽이 됩니다.
//include 하실때는 선언'만 상위로 별도로 빼둔다. 라고 생각하시면 좋습니다.

//그리고 이걸 또 다른 파일에서 사용하고 싶어요. 그럼 어떻게 해야 할까요.

//a.h
int aa;
 
//a.cpp
#include <stdio.h>
#include "a.h"
void main()
{
	aa = 1;
	printf("%d\n", aa);
	return;
}
 
//b.cpp
#include "a.h"

이럴때.
Linking...
b.obj : error LNK2005: "int aa" (?aa@@3HA) already defined in a.obj
Debug/test.exe : fatal error LNK1169: one or more multiply defined symbols found
Error executing link.exe.
이런 에러가 납니다.

이유는.
a.h를 두번 선언한것과 같기 때문입니다.
a.cpp에서 한번. b.cpp에서 또 한번.
int aa;
int aa;
a.cpp
b.cpp 한것과 같습니다. (에러 문구에 써있듯이. already defined. 중복 선언되었습니다.)

이런 방식에 사용도 가능합니다
b.cpp의 함수를 호출해서 함수 인자값으로 aa를 넘기거나
extern 변수를 선언해서 사용할 수 있습니다.

//a.h
int aa;
 
//b.h
extern int aa;
int fn_test(int n);
 
//a.cpp
#include <stdio.h>
 
#include "a.h"
#include "b.h"
 
void main()
{
	aa = 1;
	printf("%d\n", aa);
	printf("%d\n", fn_test(aa));
	return;
}
 
//b.cpp
#include "b.h"
int fn_test(int n)
{
	return 5+n+aa;
}

기본적으로 이것은
a.cpp와 b.cpp에 a.h와 b.h의 헤더 값을 상위로 올려 놓은것으로 보시면 쉽습니다.
cpp라고 적고. c로 만들기. ㅡ_ㅡ;;;

하튼.
변수 선언
함수 선언
변수 초기화
함수 정의

이렇게 만들어요.

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

익명 사용자의 이미지

쉽게 말씀드리면.

선언만 한 헤더 파일이 있고,
구현부를 c파일에 할 때 그 c파일에서는 선언한 헤더 파일을 굳이 참조할 필요가 없습니다.

다른곳에서 쓸 때 선언만 한 헤더파일을 참조하고, 구현된 c파일을 같이 빌드하면 되는 거죠.
정리 끝!

tachyon92의 이미지

그래도 함수의 선언타입과 구현타입의 일관성을 위해 구현부에서도 굳이 헤더파일을 참조할 필요가 있다고 생각합니다.

tachyon92의 이미지

덧붙이자면,

void a() {}

라는 문장을 컴파일하면 목적파일에 '_a'라는 이름의 함수가 만들어집니다.

void a();

라는 문장이 있으면 나중에 prototype에 맞게 a() 라는 함수를 사용할 수 있게되고 링킹 과정에서 '_a'라는 symbol을 참조하게 됩니다.
만약 '_a'라는 symbol을 찾지 못하면 link-time에 에러를 낼 지 몰라도 compile-time에는 문제가 없습니다.

즉,

void a();

만 있고 그 구현이 없더라도 컴파일은 문제 없습니다.

헤더파일에서 구현파일을 참조할 필요는 없습니다.



또한 모든 c 파일은 따로 컴파일되며, #include는 단순히 헤더의 내용을 삽입하는 것에 불과합니다.

만약,

void a() {}

라는 선언이 포함된 헤더파일을 서로다른 c 파일에서 include 한 뒤에 컴파일 하면 '_a' 라는 symbol이 두 개 만들어 지기 때문에 link-time에 에러가 납니다. 어느 '_a'를 참조해야 할지 판단할 수 없기 때문입니다.

이 문제 때문에 구현과 선언을 분리해서 헤더파일을 고안했다고 알고 있습니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.