#include <filename>과 #include“filename”의 차이점은 무엇입니까?


2354

C 및 C ++ 프로그래밍 언어에서 include다음과 같이 명령문 에서 꺾쇠 괄호 사용과 따옴표 사용의 차이점은 무엇 입니까?

  1. #include <filename>
  2. #include "filename"



Visual Studio의 동작에 대해서는 docs.microsoft.com/en-us/cpp/preprocessor/…
smwikipedia

답변:


1404

실제로, 전처리 기가 포함 된 파일을 검색하는 위치에 차이가 있습니다.

들면 #include <filename>통상 검색 디렉토리 구현 의존적으로 전처리 검색 컴파일러 / IDE에 의해 지정 사전. 이 방법은 일반적으로 표준 라이브러리 헤더 파일을 포함하는 데 사용됩니다.

#include "filename"전 처리기의 경우 , 지시문이 포함 된 파일과 동일한 디렉토리에서 먼저 검색 한 다음 #include <filename>양식에 사용 된 검색 경로를 따릅니다 . 이 방법은 일반적으로 프로그래머 정의 헤더 파일을 포함하는 데 사용됩니다.

보다 자세한 설명은 검색 경로 에 대한 GCC 설명서를 참조하십시오 .


135
"전처리 기가 동일한 디렉토리에서 검색합니다 ..."라는 문구는 실제로 사실 일 수 있지만 표준은 명명 된 소스 파일이 "구현 정의 방식으로 검색 됨"을 나타냅니다. piCookie의 답변을 참조하십시오.
Richard Corden

60
귀하의 답변이 "참"인 것처럼 보일 수 있지만, 이는 규칙에 따라 구현되는 횟수가 많으므로 aib 및 piCookie의 답변을 면밀히 검토해야합니다. 둘 다 (C 표준의 표현으로 뒷받침 됨) 실제 구별은 "헤더"포함과 "소스 파일"포함 ( "아니오,".h "대" "를 의미하지 않음)을 지적합니다. 씨"). 이 문맥에서 "소스 파일"은 ".h"파일 일 수 있습니다. 헤더는 반드시 파일 일 필요는 없습니다 (컴파일러는 파일이 아닌 정적으로 코딩 된 헤더를 포함 할 수 있습니다).
Dan Molding

5
"... 프리 프로세서는 파일이 포함되도록 컴파일되는 파일과 동일한 디렉토리에서 검색합니다." 이 진술은 완전히 정확하지 않습니다. 실제 답변이 무엇인지 궁금하기 때문에이 질문에 관심이 있었지만 #include "filename으로 지정된 파일을 검색하는 -I로 추가 포함 경로를 지정할 때 적어도 gcc에서는 이것이 사실이 아님을 알고 있습니다. h "
Gabriel Southern

9
대답이 마음에 들지 않는 사람들은 실제적인 예를 하나 제시하십시오.
0kcats

1
확실히, 나는 최근에 '같은'라이브러리의 헤더를 포함 할 때 이러한 구문을 혼합하여 재정의 오류로 끝났습니다. 올바르게 이해 #include <...>하면 시스템에 설치된 패키지를 #include "..."사용하고 가까운 리포지토리 버전을 사용하십시오. 나는 그것들을 거꾸로 가질 수 있습니다. 어느 쪽이든, 패키지 헤더의 포함 가드는 밑줄로 시작됩니다. (버전 한정자가 나에게 더 합리적이지만 패키지에 대한 규칙 일 수도 있고 의도적으로 두 혼합을 방지하는 방법 일 수도 있습니다.)
John P

714

알 수있는 유일한 방법은 구현 문서를 읽는 것입니다.

에서는 C 표준 , 섹션 6.10.2, 2~4 주 문단 :

  • 양식의 전처리 지시문

    #include <h-char-sequence> new-line

    와 구분 기호 사이의 지정된 순서로 고유하게 식별 된 헤더에 대해 일련의 구현 정의 된 위치를 검색하고 해당 지시문을 헤더 의 전체 컨텐츠로 대체합니다 . 장소가 지정되거나 헤더가 식별되는 방식은 구현에 따라 다릅니다.<>

  • 양식의 전처리 지시문

    #include "q-char-sequence" new-line

    구분 기호 사이의 지정된 순서로 식별 된 소스 파일 의 전체 내용으로 해당 지시문을 대체 합니다 ". 명명 된 소스 파일 은 구현 정의 방식으로 검색됩니다. 이 검색이 지원되지 않거나 검색이 실패하면 지시문은 읽은 것처럼 재 처리됩니다.

    #include <h-char-sequence> new-line

    >원래 지시문 의 동일한 포함 시퀀스 (있는 경우 문자 포함 )

  • 양식의 전처리 지시문

    #include pp-tokens new-line

    (이전의 두 형식 중 하나와 일치하지 않음)이 허용됩니다. include지시문에서 이후의 전처리 토큰 은 일반 텍스트에서와 같이 처리됩니다. (현재 매크로 이름으로 정의 된 각 식별자는 전처리 토큰의 교체 목록으로 대체됩니다.) 모든 교체 후 생성 된 지시문은 이전 두 양식 중 하나와 일치해야합니다. a <>전처리 토큰 쌍 또는 한 쌍의 "문자 사이의 일련의 전처리 토큰 이 단일 헤더 이름 전처리 토큰으로 결합되는 방법은 구현 정의됩니다.

정의 :

  • h-char : 개행 문자를 제외한 소스 문자 세트의 모든 멤버 >

  • q-char : 개행 문자를 제외한 소스 문자 세트의 모든 멤버 "


108

27
@piCookie <filename>과 "filename"은 모두 구현 정의 된 장소를 검색합니다. 차이점은 무엇입니까?
onmyway133

15
@ 스테판, 나는 INCLUDE_PATH에 대해 아무 말도하지 않는 표준을 인용하고 있습니다. 당신의 구현은 그렇게 할 수 있고, 그렇지 않을 수도 있습니다. 원래 질문은 일반적으로 C였으며 특히 gcc (INCLUDE_PATH를 사용하지 않는다고 생각) 또는 Microsoft C (제 생각에)라고 생각하지는 않습니다. 일반적으로 대답 할 수는 없지만 대신 각 구현 설명서를 참조해야합니다.
piCookie

12
이러한 모든 상황과 마찬가지로 구체적인 예 (특히 일반적인 시나리오)가 매우 유용하고 똑같이 높이 평가됩니다. 당연히 일반적인 답변은 실용적이지 않습니다.
vargonian

132
"C 표준을 자세하게 설명하고 질문에 대답하지 않는 방법"
anatolyg

287

<와> 사이의 문자 시퀀스는 헤더 일 뿐이며 반드시 파일 일 필요는 없습니다. 구현은 원하는대로 문자 시퀀스를 자유롭게 사용할 수 있습니다. (대부분 파일 이름으로 취급 하고 다른 게시물 상태와 같이 include 경로 에서 검색하면 됩니다 .)

경우 #include "file"양식, 지정된 이름의 파일에 대해, 구현 최초의 외모를 사용하는 지원합니다. 지원되지 않거나 검색이 실패하면 구현은 다른 #include <file>양식 ( )이 사용 된 것처럼 작동 합니다.

또한 세 번째 양식이 존재하며 #include지시문이 위의 양식 중 하나와 일치하지 않을 때 사용됩니다 . 이 형식에서는 매크로 확장과 같은 일부 기본 전처리가 #include지시문 의 "피연산자"에서 수행되며 결과는 다른 두 가지 형식 중 하나와 일치합니다.


50
+1, 아마도 가장 간결하고 정답 일 것입니다. (그의 대답에서 piCookie 따옴표), 유일한 표준에 따라 실제 차이는 "소스 파일"대 "헤더"입니다. 검색 메커니즘은 구현 정의 방식입니다. 큰 따옴표를 사용한다는 것은 "소스 파일"을 포함시키려는 것을 의미하는 반면, 꺾쇠 괄호는 "헤더"를 포함 시키려고하는 것으로, 파일이 아닐 수도 있습니다.
Dan Molding

3
quest49의 답변에 대한 Dan Moulding의 의견을 참조하십시오. 표준 헤더는 파일 형식 일 필요가 없으며 내장 될 수 있습니다.
aib

10
나는이 "표준 헤더가 파일 형식 일 필요는 없다"고 10 년 동안 읽었습니다. 실제 사례를 제공하고 싶으십니까?
Maxim Egorushkin

12
@Maxim Yegorushkin : 기존의 실제 사례도 생각할 수 없습니다. 그러나 헤더가 파일 일 필요가 없으면 MS-DOS에 대해 완전한 C11 컴파일러가 존재할 수 없습니다. 일부 C11 헤더 이름이 "8.3"MS-DOS 파일 이름 제한과 호환되지 않기 때문입니다.
Dan Molding

18
@MaximEgorushkin : VAX / VMS C 컴파일러는 모든 C 런타임 라이브러리 헤더를 단일 텍스트 라이브러리 파일 (유닉스 아카이브와 유사)에 보관 하고 라이브러리 사이에서 색인을 생성하기 위해 키 <>키 사이의 문자열을 사용했습니다 .
Adrian McCarthy

117

여기서 좋은 대답은 C 표준을 참조하지만 POSIX 표준, 특히 c99 (예 : C 컴파일러) 명령 의 특정 동작을 잊어 버렸습니다 .

공개 그룹 기본 사양 문제 7 에 따르면 ,

-I 디렉토리

일반적인 위치를 찾기 전에 디렉토리 경로 이름으로 이름이 지정된 디렉토리를 찾도록 이름이 절대 경로 이름이 아닌 헤더를 검색하는 알고리즘을 변경하십시오 . 따라서 이름이 큰 따옴표 ( "")로 묶인 헤더는 먼저 #include 행 을 사용하여 파일의 디렉토리에서 검색 한 다음 -I 옵션으로 이름이 지정된 디렉토리 에서 검색하고 일반적인 위치에서 마지막으로 검색해야합니다. 이름이 꺾쇠 괄호 ( "<>")로 묶인 헤더의 경우 헤더는 -I 옵션으로 이름 지정된 디렉토리에서만 검색 한 다음 일반적인 위치에서 검색해야합니다 . -I 옵션으로 명명 된 디렉토리 는 지정된 순서대로 검색됩니다.c99 명령 호출

그래서, POSIX와 호환되는 C 컴파일러와 POSIX 호환 환경에서, #include "file.h"가능성을 검색 할 것입니다 ./file.h첫째, 어디 .와 파일 디렉토리입니다 #include문을하면서 #include <file.h>, 가능성을 검색 할 것입니다 /usr/include/file.h첫째, 어디 /usr/include시스템 정의 헤더의 일반적인 장소 (POSIX에 의해 정의되지 않은 것 같습니다).


1
텍스트의 정확한 출처는 무엇입니까? IEEE Std 1003.1, 2013의 규범 부분에서 왔습니까?
osgx

7
@osgx : 그 표현 (혹은 매우 유사한 것)은 POSIX 사양에서 발견된다 c99. 이것은 C 컴파일러의 POSIX 이름이다. (POSIX 및 2008 표준은 거의 C11 참조 없었다; POSIX 2008 년 2013 업데이트가 언급하는 C 표준을 변경하지 않았다.)
조나단 레플러에게

1
이것도 저의 첫 생각이었습니다. gcc의 맨 페이지에는 다른 것과 마찬가지로이 내용이 포함되어 있습니다. 라이브러리에도 비슷한 것이 있습니다- -L.
Pryftan

50

GCC 문서는 이 둘의 차이점에 대해 다음과 같이 말합니다 .

사용자 및 시스템 헤더 파일 모두 사전 처리 지시문을 사용하여 포함됩니다 ‘#include’. 두 가지 변형이 있습니다.

#include <file>

이 변형은 시스템 헤더 파일에 사용됩니다. 표준 시스템 디렉토리 목록에서 file이라는 파일을 검색합니다. -I옵션을 사용하여 디렉토리를이 목록 앞에 추가 할 수 있습니다 ( 호출 참조 ).

#include "file"

이 변형은 자신의 프로그램의 헤더 파일에 사용됩니다. 현재 파일이 들어있는 디렉토리에서 먼저 file이라는 파일을 찾은 다음 quote 디렉토리에서에 사용 된 것과 동일한 디렉토리를 검색 <file>합니다. -iquote옵션을 사용하여 디렉토리를 인용 디렉토리 목록 앞에 추가 할 수 있습니다 . ‘#include’따옴표 나 꺾쇠 괄호로 구분 되든 의 인수는 주석이 인식되지 않고 매크로 이름이 확장되지 않는다는 점에서 문자열 상수처럼 동작합니다. 따라서 #include <x/*y>라는 시스템 헤더 파일을 포함하도록 지정합니다 x/*y.

그러나 파일 내에서 백 슬래시가 발생하면 이스케이프 문자가 아닌 일반 텍스트 문자로 간주됩니다. C의 문자열 상수에 적합한 문자 이스케이프 시퀀스는 처리되지 않습니다. 따라서 #include "x\n\\y"세 개의 백 슬래시가 포함 된 파일 이름을 지정합니다. (일부 시스템에서는 '\'를 경로 이름 구분 기호로 해석 ‘/’합니다. 이들 모두도 같은 방식으로 해석 됩니다 ‘/’.

파일 이름 다음 줄에 주석 이외의 것이 있으면 오류가 발생합니다.


46

그렇습니다:

"mypath/myfile" is short for ./mypath/myfile

.이 파일의 디렉토리 중 하나 인 #include에 포함되어, 및 / 또는 컴파일러의 현재 작업 디렉토리 및 / 또는default_include_paths

<mypath/myfile> is short for <defaultincludepaths>/mypath/myfile

경우 ./<default_include_paths>, 그것은 차이를 만들지 않습니다.

mypath/myfile다른 포함 디렉토리에 있으면 동작이 정의되지 않습니다.


12
아니요, #include "mypath/myfile"에 해당하지 않습니다 #include "./mypath/myfile". piCookie의 답변에서 알 수 있듯이 큰 따옴표는 컴파일러에 구현 정의 방식으로 검색하도록 지시합니다 #include <...>. 여기에는 지정된 위치에서 검색하는 것이 포함됩니다 . (실제로, 이것은 아마도 동일 /usr/include/mypath/myfile할 수 있지만 , 예를 들어, /usr/include/./mypath/myfile적어도 유닉스 계열 시스템에서는 언급 될 수 있기 때문에 만 가능 합니다.)
Keith Thompson

1
@ Keith Thompson : 맞습니다. 저는 리눅스 박스를 생각하고있었습니다. 분명히 다를 수 있습니다. 실제로는 비 Posix 운영 체제 인 Windows도 /를 경로 구분 기호로 해석하고 ./도 존재합니다.
Stefan Steiger

1
그런 다음 -L dirpath 옵션 은 (위 참조)에 다른 의미를 부여하는 것과 달리 dirpath 를에 추가합니다 . 이것은 모두가 예상되는 결과를 가지고 와 에서 검색 dirpathdefaultincludepaths.#include "..."#include <...>
Protongun

1
큰 따옴표와 함께 포함 된 헤더가 항상 현재 작업 디렉토리에서 검색된다는 것을 의미하기 때문에이 답변이 잘못되었다고 생각합니다. 검색 메커니즘이 더 자세합니다. 이 답변은 불완전합니다. 불만이나 소리를 내기 위해이 의견을 추가하지는 않지만 시스템 이이 답변에 투표를 한 이유를 설명하기 위해 의견을 추가하도록 요청하기 때문에.
Carlo Wood

39

(가) <file>포함은에서 검색하는 전처리를 알려줍니다 -I디렉토리와 미리 정의 된 디렉토리에 처음 .c 파일의 디렉토리에 다음. (가) "file"포함 소스 파일의 디렉토리를 검색 할 수 처리기를 알려줍니다 첫째 , 다음으로 되돌아 -I와 미리 정의. 어쨌든 모든 대상이 검색되며 검색 순서 만 다릅니다.

2011 표준은 주로 "16.2 소스 파일 포함"의 포함 파일에 대해 설명합니다.

2 양식의 전처리 지시문

# include <h-char-sequence> new-line

<및> 구분 기호 사이의 지정된 시퀀스로 고유하게 식별 된 헤더에 대한 구현 정의 된 장소 시퀀스를 검색하고 해당 지시문을 헤더의 전체 컨텐츠로 대체합니다. 장소가 지정되거나 헤더가 식별되는 방식은 구현에 따라 다릅니다.

3 양식의 전처리 지시문

# include "q-char-sequence" new-line

"구분자 사이에서 지정된 순서로 식별 된 소스 파일의 전체 내용으로 해당 지시문을 대체합니다. 명명 된 소스 파일은 구현 정의 방식으로 검색됩니다.이 검색이 지원되지 않거나 검색이 실패한 경우 지시문은 마치 읽은 것처럼 재 처리됩니다.

# include <h-char-sequence> new-line

원래 지시문의 동일한 포함 시퀀스 (> 문자가있는 경우 포함)

그 주 "xxx"에 양식이 저하 <xxx>파일을 찾을 수없는 경우 양식을. 나머지는 구현 정의입니다.


4
C -I비즈니스 에서이 비즈니스가 지정된 위치에 대한 참조를 제공 할 수 있습니까?
juanchopanza

1
에 대한 참조가 없습니다 -I.
juanchopanza

2
이것이 "구현 정의"부분입니다.

27

#include <file.h>컴파일러가 "includes"디렉토리에서 헤더를 검색하도록 지시합니다 (예 : MinGW의 경우 컴파일러는 file.hC : \ MinGW \ include \에서 또는 컴파일러가 설치된 모든 위치에서 검색 함).

#include "file"컴파일러에게 현재 디렉토리 (즉, 소스 파일이있는 디렉토리)를 검색하도록 지시합니다 file.

-IGCC에 플래그를 사용하여 꺾쇠 괄호가있는 포함을 발견하면 이후 디렉토리에서 헤더를 검색해야한다고 알릴 수 있습니다 -I. GCC는 플래그 뒤에있는 디렉토리를 마치 includes디렉토리 인 것처럼 취급합니다 .

예를 들어, myheader.h자신의 디렉토리에 호출 된 파일이있는 #include <myheader.h>경우 플래그를 사용하여 GCC를 호출했는지 말할 수 있습니다 -I .(현재 디렉토리에서 포함을 검색해야 함을 나타냄).

-I플래그가 없으면 #include "myheader.h"파일을 포함 시키거나 컴파일러 myheader.hinclude디렉토리로 이동 해야합니다 .


22

표준에 따르면-예, 다릅니다.

  • 양식의 전처리 지시문

    #include <h-char-sequence> new-line

    <>구분 기호 사이의 지정된 순서로 고유하게 식별 된 헤더에 대해 일련의 구현 정의 된 장소를 검색하고 해당 지시문을 헤더의 전체 컨텐츠로 대체합니다. 장소가 지정되거나 헤더가 식별되는 방식은 구현에 따라 다릅니다.

  • 양식의 전처리 지시문

    #include "q-char-sequence" new-line

    "구분 기호 사이의 지정된 순서로 식별 된 소스 파일의 전체 내용으로 해당 지시문을 대체합니다 . 명명 된 소스 파일은 구현 정의 방식으로 검색됩니다. 이 검색이 지원되지 않거나 검색이 실패하면 지시문은 읽은 것처럼 재 처리됩니다.

    #include <h-char-sequence> new-line

    >원래 지시문 의 동일한 포함 시퀀스 (있는 경우 문자 포함 )

  • 양식의 전처리 지시문

    #include pp-tokens new-line

    (이전의 두 형식 중 하나와 일치하지 않음)이 허용됩니다. include지시문에서 이후의 전처리 토큰 은 일반 텍스트에서와 같이 처리됩니다. (현재 매크로 이름으로 정의 된 각 식별자는 전처리 토큰의 교체 목록으로 대체됩니다.) 모든 교체 후 생성 된 지시문은 이전 두 양식 중 하나와 일치해야합니다. a <>전처리 토큰 쌍 또는 한 쌍의 "문자 사이의 일련의 전처리 토큰 이 단일 헤더 이름 전처리 토큰으로 결합되는 방법은 구현 정의됩니다.

정의 :

  • h-char : 개행 문자를 제외한 소스 문자 세트의 모든 멤버 >

  • q-char : 개행 문자를 제외한 소스 문자 세트의 모든 멤버 "

표준은 구현 정의 방식 사이의 관계를 나타내지 않습니다. 첫 번째 양식은 구현 정의 방식으로 검색하고 다른 양식은 구현 정의 방식으로 검색합니다. 이 표준은 또한 특정 포함 파일이 존재하도록 지정합니다 (예 <stdio.h>:).

공식적으로 컴파일러의 매뉴얼을 읽어야하지만 일반적으로 (전통적으로) #include "..."양식 #include은 처음 발견 된 파일의 디렉토리를 검색 한 다음 양식이 검색하는 디렉토리 #include <...>(포함 경로, 예를 들어 시스템 헤더)를 검색합니다 ).


2
이것은 7 년 전의 piCookie의 답변과 거의 동일한 텍스트 입니다.
Kyle Strand

5
@KyleStrand 동일한 텍스트가 표준의 관련 섹션을 인용하기 때문에 텍스트는 동일 해야 합니다. 실제 답변은 동일한 텍스트가 아니며 다소 다릅니다. 또한 구현에 대한 설명서에 작성 될 것임을 알고 있지만 해석되는 전통적인 방법도 있습니다 (내가 사용한 대부분의 컴파일러 또는 대부분의 컴파일러) .
skyking

2
IMO는 표준이 말하는 것과 대부분의 컴파일러가 실제로하는 것을 모두 다루기 때문에 여기에 가장 좋은 대답입니다.
plugwash

17

큰 답변에 감사드립니다. Adam Stelmaszczyk 및 piCookie 및 aib.

많은 프로그래머들과 마찬가지로, 나는 "myApp.hpp"응용 프로그램 특정 파일에 대한 <libHeader.hpp>형식과 라이브러리 및 컴파일러 시스템 파일에 대한 형식, 즉 환경 변수에 지정된 파일 /IINCLUDE환경 변수에 대한 형식을 표준으로 생각하는 비공식 규칙을 사용했습니다 .

그러나 C 표준에 따르면 검색 순서는 구현별로 다르므로 이식성이 복잡해질 수 있습니다. 설상가상으로 잼을 사용하여 포함 파일의 위치를 ​​자동으로 파악합니다. 포함 파일에 상대 또는 절대 경로를 사용할 수 있습니다. 즉

#include "../../MyProgDir/SourceDir1/someFile.hpp"

이전 버전의 MSVS에는 이중 백 슬래시 (\\)가 필요했지만 이제는 필요하지 않습니다. 언제 바뀌 었는지 모르겠습니다. 'nix와의 호환성을 위해 슬래시를 사용하십시오 (Windows에서 허용).

정말로 걱정 한다면 "./myHeader.h"소스 코드와 동일한 디렉토리에 포함 파일을 사용하십시오 (현재 매우 큰 프로젝트에는 중복 구성 파일 이름이 실제로 구성 관리 문제가 있습니다).

여기의 MSDN 설명 의 편의를 위해 여기에 복사가).

인용 양식

전처리 기는 다음 순서로 포함 파일을 검색합니다.

  1. #include 문이 포함 된 파일과 동일한 디렉토리에 있습니다.
  2. 현재 열려있는 포함 파일의 디렉토리에서 파일을 열었던 순서와 반대 순서로
    . 검색은 상위 포함 파일의 디렉토리에서 시작하여
    조부모 포함 파일의 디렉토리를 통해 계속 진행됩니다.
  3. /I컴파일러 옵션으로 지정된 경로를 따라 .
  4. INCLUDE환경 변수에 의해 지정된 경로를 따라 .

꺾쇠 괄호 양식

전처리 기는 다음 순서로 포함 파일을 검색합니다.

  1. /I컴파일러 옵션으로 지정된 경로를 따라 .
  2. INCLUDE환경 변수 로 지정된 경로를 따라 명령 행에서 컴파일 할 때 .

16

GCC 버전 <= 3.0 이상인 경우 꺾쇠 괄호 형식은 포함 된 파일과 포함 된 파일 간의 종속성을 생성하지 않습니다.

따라서 종속성 규칙을 생성하려면 (예 : GCC -M 옵션 사용) 종속성 트리에 포함되어야하는 파일에 대해 인용 된 양식을 사용해야합니다.

( http://gcc.gnu.org/onlinedocs/cpp/Invocation.html 참조 )


1
예-종속성을 생성하는 여러 가지 방법이 있습니다. 그것은 그들 중 하나이지만 유일한 것은 아닙니다.
Pryftan

15

들어 #include ""컴파일러 일반적으로 포함하는 것을 포함하고 다른 폴더 파일의 폴더를 검색합니다. 들어 #include <>컴파일러 현재 파일의 폴더를 검색하지 않습니다.


1
사람들이 왜 동의하지 않는지 잘 모르겠습니다.
Maxim Egorushkin

나는 대부분의 사람들이 CWD의 파일 만 컴파일하기 때문이라고 생각합니다. 디렉토리 foo에 있고 foo / unittest / bar.c를 컴파일하고 있는데 bar.h를 포함하고 있다면 "bar.h"는 작동하고 <bar.h>는 작동하지 않습니다.

1
설명하는 동작이 표준 C가 아니기 때문에 @Maxim 사람들이 동의하지 않습니다.
osvein

2
오른쪽 @Spookbuster, 표준은 모두 말합니다 <filename>"filename"구현 정의 장소를 검색합니다.
Maxim Egorushkin

14

#include <filename>을 사용하면 전처리 기는 C \ C ++ 헤더 파일 (stdio.h \ cstdio, string, vector 등)의 디렉토리에서 파일을 찾습니다. 그러나 #include "filename":을 사용하면 먼저 전처리 기가 현재 디렉토리에서 파일을 찾고 여기에 없으면 C \ C ++ 헤더 파일의 디렉토리에서 파일을 찾습니다.


1
몇 년 동안 완벽한 답변을 얻을 수 있었는데, 왜 답변을 제출해야합니까? 일반적이지만 #include지시문은 파일과 전혀 관련이 없습니다.
IInspectable

@IInspectable 왜 파일과 관련이 없는지 설명해주세요.
Behrooz Karjoo

11

꺾쇠 괄호가있는 #include는 포함 할 파일에 대해 "구현에 의존하는 장소 목록"( "시스템 헤더"를 말하는 매우 복잡한 방법)을 검색합니다.

따옴표가있는 #include는 파일을 검색합니다 ( "구현 방식에 따라"bleh). 즉, 일반 영어에서는 사용자가 던지는 경로 / 파일 이름을 적용하려고 시도하고 시스템 경로 앞에 추가하거나 다른 방식으로 변경하지 않습니다.

또한 #include ""가 실패하면 표준에서 #include <>로 다시 읽습니다.

GCC 문서는 gcc가 특정 아닌 표준되고 있지만, ISO 표준의 변호사 스타일의 이야기보다 이해하기가 훨씬 쉽다이다 (컴파일러 특정) 설명이있다.


그러나 꺾쇠 괄호 나 따옴표를 사용해도 파일이 포함되는 방식에는 영향을 미치지 않습니다. 전처리 기는 기본적으로 포함 파일에서 원본 소스 파일로 코드를 복사하여 붙여 넣어 큰 소스 파일을 생성합니다. 그것은 컴파일러에게 (전처리 기는 #define sustitution, #if 평가 등과 같은 다른 일을하지만 #include 처리는 쉽다)
Loghorn

갈등은 어떻습니까? 예를 들어 zlib.h'사용자'검색 경로에 있고 시스템 검색 경로에 다른 버전이 존재한다고 가정 #include <zlib.h>하면 시스템 버전과 #include "zlib.h"자체 버전 이 포함 됩니까?
the_mandrill

: 아하, 내 자신의 질문에 대답 stackoverflow.com/questions/21593/...
the_mandrill

표준 표준 구현 규칙이 표준에 의해 지정되지 않았기 때문에 알 수 없다고 말하는 것이 아니라 표준 일반적인 구현 규칙이 모두 관련 되어 있음을 인정해 주셔서 감사합니다 .
Kyle Strand

10
#include "filename" // User defined header
#include <filename> // Standard library header.

예:

파일 이름은 Seller.h다음과 같습니다.

#ifndef SELLER_H     // Header guard
#define SELLER_H     // Header guard

#include <string>
#include <iostream>
#include <iomanip>

class Seller
{
    private:
        char name[31];
        double sales_total;

    public:
        Seller();
        Seller(char[], double);
        char*getName();

#endif

클래스 구현 (예 : Seller.cpp및 파일을 사용할 다른 파일 Seller.h)에서 사용자가 정의한 헤더가 다음과 같이 포함되어야합니다.

#include "Seller.h"

10
  • #include <> 사전 정의 된 헤더 파일 용

헤더 파일이 사전 정의되어 있으면 헤더 파일 이름을 꺾쇠 괄호로 작성하면 다음과 같이 표시됩니다 (사전 정의 된 헤더 파일 이름 iostream이 있다고 가정).

#include <iostream>
  • #include " " 프로그래머가 정의한 헤더 파일 용

프로그래머가 자신의 헤더 파일을 작성한 경우 헤더 파일 이름을 따옴표로 묶습니다. 따라서이라는 헤더 파일을 작성 myfile.h했다고 가정하면 include 지시문을 사용하여 해당 파일을 포함시키는 방법의 예입니다.

#include "myfile.h"

2
미리 정의 된 헤더 파일과는 전혀 관련이 없습니다. 검색 할 위치와 관련이 있습니다.
C Johnson

9

여기의 많은 답변은 컴파일러가 파일을 찾기 위해 검색하는 경로에 중점을 둡니다. 이것이 대부분의 컴파일러가하는 일이지만, 적합한 컴파일러는 표준 헤더의 효과로 미리 프로그래밍되고 #include <list>스위치로 취급 될 수 있으며 파일로 존재할 필요는 없습니다.

이것은 순전히 가설이 아닙니다. 그런 식으로 작동하는 컴파일러가 하나 이상 있습니다. #include <xxx>표준 헤더 만 사용 하는 것이 좋습니다.


9
#include <abc.h>

표준 라이브러리 파일을 포함하는 데 사용됩니다. 따라서 컴파일러는 표준 라이브러리 헤더가 상주하는 위치를 확인합니다.

#include "xyz.h"

컴파일러가 사용자 정의 헤더 파일을 포함하도록 지시합니다. 따라서 컴파일러는 현재 폴더 또는 -I정의 된 폴더 에서 이러한 헤더 파일을 확인합니다 .


7

C ++에서 두 가지 방법으로 파일을 포함하십시오.

첫 번째는 #include로 사전 처리기에서 사전 정의 된 기본 위치에서 파일을 찾도록 지시합니다. 이 위치는 종종 파일을 포함 할 경로를 나타내는 INCLUDE 환경 변수입니다.

두 번째 유형은 #include "filename"으로, 프리 프로세서는 현재 디렉토리에서 파일을 찾은 다음 사용자가 설정 한 사전 정의 된 위치에서 파일을 찾도록 지시합니다.


7

양식 1-#include <xxx>

먼저, 지시문이 호출 된 곳에서 현재 디렉토리에 헤더 파일이 있는지 찾습니다. 찾을 수없는 경우 사전 구성된 표준 시스템 디렉토리 목록에서 검색합니다.

양식 2-#include "xxx"

지시문이 호출되는 현재 디렉토리에 헤더 파일이 있는지 찾습니다.


정확한 검색 디렉토리 목록은 대상 시스템, GCC 구성 방법 및 설치 위치에 따라 다릅니다. -v 옵션으로 실행하여 GCC 컴파일러의 검색 디렉토리 목록을 찾을 수 있습니다.

-I dir 을 사용하여 추가 디렉토리를 검색 경로에 추가 할 수 있습니다.이 명령을 사용 하면 dir이 현재 디렉토리 뒤 (명령어의 인용 형식으로) 표준 시스템 디렉토리보다 먼저 검색됩니다.


기본적으로 "xxx"형식은 현재 디렉토리에서 검색 할뿐입니다. 양식을 다시 찾지 못하면


3
잘 정립되고 정답이있는 오래된 질문에 대답하기로 결정한 경우, 늦은 시간에 새 답변을 추가하면 크레딧을 얻지 못할 수 있습니다. 독특한 새로운 정보가 있거나 다른 답변이 모두 잘못되었다고 확신하는 경우 반드시 새로운 답변을 추가하되, 질문이 일반적으로 제기 된 후 오랫동안 동일한 기본 정보를 제공하는 '아직 다른 답변'을 작성하십시오. ' 당신은 많은 신용을 얻습니다.
Jonathan Leffler

1
@Jonathan Leffler Darshan의 답변만큼 간결하고 정확하다고 생각하는 "잘 확립 된"답변을 알려 주시겠습니까?
personal_cloud

1
#include "header.h"@personal_cloud 에서 양식에 대한 설명이 정확하지 않습니다. piCookieYann Droneaud 의 답변이 정보의 출처를 식별 할 때 가장 관련성이 있다고 생각합니다. 최고 투표 답변도 완전히 만족 스럽지는 않습니다.
Jonathan Leffler

이 답변이 맨 위에 표시되는 반면 두 답변 아래에 650 개 이상의 투표가 있습니다. 이 답변은 내가 관찰 한 행동과 일치하지 않기 때문에 나를 혼란스럽게했습니다. 꺾쇠 괄호를 이탈하지 않아 마지막 문장이 깨져서 발생할 수 있습니다. 무슨 뜻인지 잘 모르겠습니다.
Neonit

6

#include <filename>시스템 파일이 언급 될 때 사용된다. 이는 /usr/include또는 과 같은 시스템 기본 위치에서 찾을 수있는 헤더 파일입니다 /usr/local/include. 다른 프로그램에 포함되어야하는 고유 한 파일의 경우 #include "filename"구문 을 사용해야 합니다.


6

표준 C 라이브러리 위치에서 "<filename>"검색

"filename"은 현재 디렉토리에서도 검색합니다.

이상적으로는 표준 C 라이브러리에는 <...>를 사용하고 현재 디렉토리에 작성하고 존재하는 라이브러리에는 "..."를 사용하십시오.


4
어떤 답변이 다른 답변에이 답변을 추가합니까?
Daniel Langr

5

일반적인 일반적인 규칙은 꺾쇠 괄호를 사용하여 컴파일러와 함께 제공되는 헤더 파일을 포함하는 것입니다. 큰 따옴표를 사용하여 다른 헤더 파일을 포함하십시오. 대부분의 컴파일러는 이런 식으로합니다.

1.9 — 헤더 파일 은 전 처리기 지시문에 대해 자세히 설명합니다. 초보자 프로그래머 인 경우 해당 페이지를 통해 모든 것을 이해할 수 있습니다. 나는 여기에서 그것을 배웠고 직장에서 그것을 따르고 있습니다.


4
#include <filename>

C / C ++ 시스템 또는 컴파일러 라이브러리의 헤더 파일을 사용하려는 경우에 사용됩니다. 이 라이브러리는 stdio.h, string.h, math.h 등이 될 수 있습니다.

#include "path-to-file/filename"

프로젝트 폴더 또는 다른 곳에있는 사용자 정의 헤더 파일을 사용하려는 경우에 사용됩니다.

전 처리기 및 헤더에 대한 자세한 내용 C- 전처리기를 읽으십시오 .


3

#include <filename>

  • 전처리 기는 구현에 따라 검색합니다. 컴파일러에게 시스템 헤더 파일이있는 디렉토리를 검색하도록 지시합니다.
  • 이 방법은 일반적으로 표준 헤더 파일을 찾는 데 사용됩니다.

#include "filename"

  • 이것은 컴파일러에게 프로그램이 실행중인 헤더 파일을 검색하도록 지시합니다. 실패한 경우 #include <filename>시스템 헤더 파일이 저장된 위치에서 해당 헤더 파일을 검색하고 검색하십시오.
  • 이 방법은 일반적으로 사용자 정의 헤더 파일 (사용자가 생성 한 헤더 파일)을 식별하는 데 사용됩니다. 표준 라이브러리를 호출하려면 컴파일 시간보다 더 많은 시간이 걸리기 때문에 이것을 사용하지 마십시오 #include <filename>.

2

현재 구성을 기반으로 gcc를 사용하여 시스템에서 검색 순서를 보려면 다음 명령을 실행할 수 있습니다. 이 명령에 대한 자세한 내용은 여기를 참조하십시오.

cpp -v /dev/null -o /dev/null

Apple LLVM 버전 10.0.0 (clang-1000.10.44.2)
대상 : x86_64-apple-darwin18.0.0
스레드 모델 : posix InstalledDir : 라이브러리 / 개발자 / CommandLineTools / usr / bin
"/ 라이브러리 / 개발자 / CommandLineTools / usr / bin / clang"-cc1 -triple x86_64-apple-macosx10.14.0 -Wdeprecated-objc-isa-usage -Werror = deprecated-objc-isa-usage -E -disable-free- disable-llvm-verifier -discard-value-names -main-file-name null -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -fno-strict-return -masm-verbose- munwind-tables -target-cpu penryn -dwarf-column-info -debugger-tuning = lldb -target-linker-version 409.12 -v -resource-dir /Library/Developer/CommandLineTools/usr/lib/clang/10.0.0- isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk -I / usr / local / include -fdebug-compilation-dir / Users / hogstrom -ferror-limit 19 -fmessage-length 80-스택 보호기 1 -fblocks -fencode-extended-block-signature -fobjc-runtime = macosx-10.14.0 -fmax-type-align = 16 -fdiagnostics-show-option -fcolor-diagnostics-전통적인 cpp -o--xc / dev / null
존재하지 않는 디렉토리 "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/local/include"를 무시하고 존재하지 않는 clang -cc1 버전 10.0.0 (clang-1000.10.44.2) 기본 대상 x86_64-apple-darwin18.0.0 디렉토리 "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/Library/Frameworks"#include "
..."검색 시작 :
#include <...> 검색 시작 :
/ usr / local / include
/ 라이브러리 / 개발자 /CommandLineTools/usr/lib/clang/10.0.0/include
/ Library / Developer / CommandLineTools / usr / include
/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include
/ Library / Developer / CommandLineTools / SDKs / MacOSX10.14.sdk / System / Library / Frameworks (프레임 워크 디렉토리)
검색 목록의 끝.


1
#include <file> 

기본 포함 디렉토리가있는 파일을 포함합니다.

#include "file" 

파일이 컴파일 된 현재 디렉토리에 파일을 포함시킵니다.


-2

#include 문을 작성하는 방법에는 두 가지가 있습니다.

#include"filename"
#include<filename>

각 형태의 의미는

#include"mylib.h"

이 명령은 mylib.h설정되었을 수있는 include 검색 경로에서 언급 된대로 지정된 디렉토리 목록뿐만 아니라 현재 디렉토리에서 파일 을 찾습니다 .

#include<mylib.h>

이 명령은 mylib.h지정된 디렉토리 목록에서만 파일 을 찾습니다 .

포함 검색 경로는 포함되는 파일을 검색 할 디렉토리 목록 일 뿐이며 다른 C 컴파일러를 사용하면 검색 경로를 다른 방식으로 설정할 수 있습니다.


1
잘 정립되고 정답이있는 오래된 질문에 대답하기로 결정한 경우, 늦은 시간에 새 답변을 추가하면 크레딧을 얻지 못할 수 있습니다. 독특한 새로운 정보가 있거나 다른 답변이 모두 잘못되었다고 확신하는 경우 반드시 새로운 답변을 추가하되, 질문이 일반적으로 제기 된 후 오랫동안 동일한 기본 정보를 제공하는 '아직 다른 답변'을 작성하십시오. ' 당신은 많은 신용을 얻습니다.
Jonathan Leffler
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.