#include <filename>と#include“ filename”の違いは何ですか?


2357

CおよびC ++プログラミング言語では、include次のように、山かっこを使用することとステートメントで引用符を使用することの違いは何ですか?

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



Visual Studioの動作については、docs.microsoft.com
us

回答:


1405

実際には、プリプロセッサがインクルードされたファイルを検索する場所が異なります。

ために #include <filename>、通常の検索ディレクトリで実装依存的にプリプロセッサを検索し、コンパイラ/ IDEによって指定事前。このメソッドは通常、標準ライブラリヘッダーファイルを含めるために使用されます。

#include "filename"プリプロセッサの場合、最初にディレクティブを含むファイルと同じディレクトリを検索し、次に、#include <filename>フォームに。このメソッドは通常、プログラマー定義のヘッダーファイルを含めるために使用されます。

より完全な説明は、検索パスに関する GCC ドキュメントで入手できます


135
「プリプロセッサが同じディレクトリを検索する...」という記述は実際には当てはまるかもしれませんが、標準では指定されたソースファイルは「実装定義の方法で検索される」と述べています。piCookieからの回答を参照してください。
Richard Corden

60
あなたの答えは「本当」であるように見えるかもしれませんが、これは慣例により多くの実装が機能するため、aibとpiCookieの答えをよく見る必要があります。彼らは両方とも(C標準の文言に裏打ちされて)「ヘッダー」のインクルードと「ソースファイル」のインクルード(そして、いいえ、これは「.h」と「。 c ")。この文脈での「ソースファイル」は、「。h」ファイルである可能性があります(通常、そうであり、ほとんどの場合そうであるはずです)。ヘッダーは必ずしもファイルである必要はありません(コンパイラーは、ファイルではなく、静的にコード化されたヘッダーを含めることができます)。
ダン成形

5
「...プリプロセッサは、コンパイルされるファイルと同じディレクトリを検索して、含まれるファイルを探します。」このステートメントは完全に正しくはありません。私は実際の答えが何であるか知りたくてこの質問に興味を持っていましたが、少なくとも#cc "filenameで指定されたファイルを検索する-Iで追加のインクルードパスを指定すると、gccでこれが真実ではないことを知っています。 h "
ガブリエルサザン

9
答えが気に入らない人は、実際の例を1つ挙げてください。
0kcats

1
案の定、私は最近、「同じ」ライブラリからのヘッダーを含めるときにこれらの構文を混合し、再定義エラーが発生しました。私が正しく理解していれば#include <...>、システムにインストールされているパッケージを#include "..."使用し、近くのリポジトリバージョンを使用しました。私はそれらを後方に持っているかもしれません。どちらの方法でも、パッケージ化されたヘッダーのインクルードガードの前にはアンダースコアが付けられます。(バージョンの修飾子は私にはより理にかなっていますが、それはパッケージの規則または2つを意図的に混在させない方法である可能性があります。)
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

    (前の2つの形式のいずれとも一致しない)は許可されます。includeディレクティブの後の前処理トークンは、通常のテキストと同じように処理されます。(現在マクロ名として定義されている各識別子は、前処理トークンの置換リストに置き換えられます。)すべての置換の後に生成されるディレクティブは、前の2つの形式のいずれかと一致します。<>前処理トークンのペアまたは"文字のペアの間の前処理トークンのシーケンスを単一のヘッダー名前処理トークンに組み合わせる方法は、実装によって定義されます。

定義:

  • h-char:改行文字を除くソース文字セットの任意のメンバーと >

  • q-char:改行文字を除くソース文字セットの任意のメンバーと "


108
関連:g ++およびVisual C ++
Alexander Malakhov

27
@piCookieは、<filename>と "filename"の両方で実装定義の場所を検索します。それで、違いは何ですか?
onmyway133 2013

15
@Stefan、私はINCLUDE_PATHについて何も言わない標準を引用しているだけです。あなたの実装はそれをするかもしれません、そして私のものはそうしないかもしれません。元の質問は一般的にCであり、特にgcc(INCLUDE_PATHを使用するとは思わない)またはMicrosoft C(私はそうだと思う)などではないため、一般的に回答することはできませんが、代わりに各実装のドキュメントを参照する必要があります。
piCookie 2013

12
これらすべての状況と同様に、具体的な例(特に一般的なシナリオ)は非常に役立ち、等しく評価されます。不必要に鈍い一般的な答えはそれほど実用的ではありません。
vargonian 2014

132
「これは、C標準を冗長にして、質問に答えない方法です」
anatolyg

287

<と>の間の文字シーケンスは一意にヘッダーを参照しますが、これは必ずしもファイルである必要はありません。実装では、文字シーケンスを自由に使用できます。(ただし、ほとんどの場合、それをファイル名として扱い、他の投稿の状態と同様に、インクルードパスで検索を行います。)

#include "file"フォームが使用されている場合、サポートは、指定された名前のファイルを最初に検索します(サポートされている場合)。サポートされていない場合、または検索が失敗した場合、実装は他の(#include <file>)形式が使用されているかのように動作します。

また、3番目の形式が存在し、#includeディレクティブが上記のいずれの形式とも一致しない場合に使用されます。この形式では、いくつかの基本的な前処理(マクロ展開など)が#includeディレクティブの「オペランド」で行われ、結果は他の2つの形式のいずれかと一致すると予想されます。


50
+1、これはおそらくここで最も簡潔で正しい答えです。標準(piCookieが彼の回答で引用している)によると、唯一の真の違いは「ヘッダー」と「ソースファイル」です。検索メカニズムは、いずれかの方法で実装定義されています。二重引用符を使用すると、「ソースファイル」を含めるつもりですが、山かっこは、「ヘッダー」を含めるつもりであることを意味します。
ダン成形

3
Quest49の回答に対するDan Mouldingのコメントを参照してください。標準ヘッダーはファイル形式である必要はなく、組み込みにすることができます。
aib

10
この「標準ヘッダーはファイル形式である必要はありません」を10年間読んでいます。実世界の例を提供したいですか?
Maxim Egorushkin、2011

12
@Maxim Yegorushkin:既存の現実世界の例も思いつきません。ただし、ヘッダーがファイルである必要がない限り、MS-DOS用の完全なC11コンパイラは存在できません。これは、一部のC11ヘッダー名が「8.3」のMS-DOSファイル名制限と互換性がないためです。
Dan Molding

18
@MaximEgorushkin:VAX / VMS Cコンパイラは(UNIXアーカイブと同様に)単一のテキストライブラリファイル内のすべてのCランタイムライブラリのヘッダを保持し、間の文字列を使用<して>、ライブラリへのインデックスのキーとして。
エイドリアンマッカーシー

117

ここでいくつかの良い答えはC標準を参照していますが、POSIX標準、特にc99(Cコンパイラなど)コマンドの特定の動作を忘れています。

The Open Group Base Specifications Issue 7によれば、

-I ディレクトリ

絶対パス名ではない名前のヘッダーを検索するアルゴリズムを変更して、通常の場所を検索する前に、ディレクトリパス名で指定されたディレクトリを検索します。したがって、名前が二重引用符( "")で囲まれたヘッダーは、最初に#include行のあるファイルのディレクトリで検索され、次に-Iオプションで指定されたディレクトリで検索され、通常の場所で最後に検索されます。山括弧( "<>")で名前が囲まれているヘッダーの場合、ヘッダーは-Iオプションで指定されたディレクトリでのみ検索され、その後、通常の場所で検索されます。-Iオプションで指定されたディレクトリは、指定された順序で検索されます。c99コマンドの呼び出し。

したがって、POSIX準拠の環境では、POSIX準拠のCコンパイラ#include "file.h"を使用すると、./file.h最初に検索が行われる可能性.があります。ここで、は、#includeステートメントが含まれるファイルのディレクトリです。は、最初#include <file.h>に検索され、システムが定義されている/usr/include/file.h場所/usr/includeですヘッダーの通常の場所(POSIXでは定義されていないようです)。


1
テキストの正確なソースは何ですか?それは、IEEE Std 1003.1、2013の規範的な部分からのものですか?
osgx 2015年

7
@osgx:その表現(または非常に類似したもの)は、POSIX仕様(c99CコンパイラのPOSIX名)にあります。(POSIX 2008標準ではC11をほとんど参照できません。POSIX2008への2013年の更新では、参照されているC標準は変更されませんでした。)
Jonathan Leffler

1
これも私の最初の考えでした。gccのマンページには、他のマニュアルと同様にこれが含まれています。ライブラリにも同様のものがあります- -L
プリフタン

50

GCCのドキュメントでは、2つの違いについて次のように述べています。

ユーザーとシステムの両方のヘッダーファイルは、前処理ディレクティブを使用してインクルードされ‘#include’ます。これには2つのバリアントがあります。

#include <file>

このバリアントは、システムヘッダーファイルに使用されます。システムディレクトリの標準リストからfileという名前のファイルを検索します。-Iオプションを使用して、このリストの前にディレクトリを追加できます(呼び出しを参照)。

#include "file"

このバリアントは、独自のプログラムのヘッダーファイルに使用されます。最初に現在のファイルを含むディレクトリで、次にquoteディレクトリで、次にfileと同じディレクトリでfileという名前のファイルを検索します<file>-iquoteオプションを使用して、引用ディレクトリのリストの前にディレクトリを追加できます。の引数は‘#include’、引用符または山括弧で区切られているかどうかに関係なく、コメントが認識されず、マクロ名が展開されないという点で文字列定数のように動作します。したがって、#include <x/*y>という名前のシステムヘッダーファイルを含めることを指定しますx/*y

ただし、バックスラッシュがファイル内で発生した場合、それらは通常のテキスト文字と見なされ、エスケープ文字とは見なされません。Cの文字列定数に適した文字エスケープシーケンスは処理されません。したがって、#include "x\n\\y"3つの円記号を含むファイル名を指定します。(システムによっては、「\」をパス名の区切り文字として解釈します。これらのすべても‘/’同じように解釈します‘/’。のみを使用するのが最も移植性があります。)

ファイル名の後の行に(コメント以外の)何かがあると、エラーになります。


46

します:

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

.ファイルのディレクトリのいずれかであること#includeに含まれ、および/またはコンパイラの現在の作業ディレクトリ、および/またはdefault_include_paths

そして

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

場合./であり<default_include_paths>、それは違いはありません。

Ifはmypath/myfile、別のディレクトリを含んで、動作は未定義です。


12
いいえ、#include "mypath/myfile"と同等ではありません#include "./mypath/myfile"。piCookieの回答にあるように、二重引用符は、コンパイラーに実装定義の方法で検索するように指示し#include <...>ます。これには、で指定された場所での検索が含まれます。(実際には、それはおそらく同等ですが、たとえば、少なくともUnixライクなシステムで/usr/include/mypath/myfileは、これを次のように参照できるため/usr/include/./mypath/myfileです。)
Keith Thompson

1
@キース・トンプソン:そうです、私は自分のLinuxボックスを考えていました。明らかにそれは異なる可能性があります。実際には、非PosixオペレーティングシステムとしてのWindowsも/をパス区切り文字として解釈し、。/も存在します。
Stefan Steiger 14

1
次に、-L dirpathオプションを使用すると、(上記のように)に別の意味を与えるのではなく、dirpathをに追加します。これは、dirpathでの検索と検索の両方で予想される結果になりますdefaultincludepaths.#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
この-Iビジネスが指定されているC標準の場所への参照を提供できますか?
juanchopanza 2014

1
への参照はありません-I
juanchopanza 14

2
それは「実装定義」の部分です。

28

#include <file.h>「includes」ディレクトリでヘッダーを検索するようコンパイラーに指示します。たとえば、MinGWの場合、コンパイラーはfile.hC:\ MinGW \ include \またはコンパイラーがインストールされている場所で検索します。

#include "file"現在のディレクトリ(つまり、ソースファイルが存在するディレクトリ)でを検索するようコンパイラーに指示しますfile

-IGCC のフラグを使用して、山かっこを含むインクルードを検出した場合、の後のディレクトリでヘッダーも検索する必要があることを通知できます-I。GCCは、フラグの後のディレクトリを、それがincludesディレクトリであるかのように扱います。

たとえばmyheader.h、自分のディレクトリにファイルが呼び出された#include <myheader.h>場合、フラグ-I .(現在のディレクトリでインクルードを検索する必要があることを示す)を指定してGCCを呼び出したかどうかを確認できます。

なければ-Iフラグ、あなたが使用する必要があります#include "myheader.h"ファイル、または移動含めることmyheader.hへのincludeあなたのコンパイラのディレクトリを。


22

標準では-はい、それらは異なります:

  • 次の形式の前処理ディレクティブ

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

    は、実装で定義された場所のシーケンスを検索して、<>区切り文字の間の指定されたシーケンスで一意に識別されるヘッダーを探し、そのディレクティブをヘッダーのコンテンツ全体で置き換えます。場所の指定方法またはヘッダーの識別方法は実装定義です。

  • 次の形式の前処理ディレクティブ

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

    "区切り文字の間の指定されたシーケンスで識別されるソースファイルの内容全体でそのディレクティブを置き換えます。名前付きソースファイルは、実装定義の方法で検索されます。この検索がサポートされていない場合、または検索が失敗した場合、ディレクティブは次のように再処理されます

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

    >元のディレクティブからの同一の含まれるシーケンス(存在する場合は文字を含む)。

  • 次の形式の前処理ディレクティブ

    #include pp-tokens new-line

    (前の2つの形式のいずれとも一致しない)は許可されます。includeディレクティブの後の前処理トークンは、通常のテキストと同じように処理されます。(現在マクロ名として定義されている各識別子は、前処理トークンの置換リストに置き換えられます。)すべての置換の後に生成されるディレクティブは、前の2つの形式のいずれかと一致します。<>前処理トークンのペアまたは"文字のペアの間の前処理トークンのシーケンスを単一のヘッダー名前処理トークンに組み合わせる方法は、実装によって定義されます。

定義:

  • h-char:改行文字を除くソース文字セットの任意のメンバーと >

  • q-char:改行文字を除くソース文字セットの任意のメンバーと "

この標準は、実装で定義された方法間のいかなる関係も伝えていないことに注意してください。最初の形式は、1つの実装定義の方法で検索し、もう1つは(おそらく他の)実装定義の方法で検索します。この規格では、特定のインクルードファイルが存在することも指定されています(たとえば、<stdio.h>)。

正式にはコンパイラのマニュアルを読む必要がありますが、通常は(伝統的に)#include "..."フォームは#include最初にが見つかったファイルのディレクトリを検索し、次にフォームが検索するディレクトリ#include <...>(インクルードパス、システムヘッダーなど)を検索します。 )。


2
これはほとんど7年前のpiCookieの回答と同じテキストです。
カイルストランド

5
@KyleStrand同じテキストが規格の関連セクションの引用であるためです-そのテキスト同一でなければなりません。実際の答えは同じテキストではなく、多少異なります-私はそれが実装のドキュメントにも書かれることを認識していますが、これらが解釈される伝統的な方法もあることに注意します(ほとんどまたはすべてのコンパイラが尊敬していた) 。
16

2
IMOこれは、標準が言うこととほとんどのコンパイラが実際に行うことの両方をカバーするため、ここでの最良の答えです。
plugwash 2016

17

すばらしい回答をありがとう、特に。Adam StelmaszczykとpiCookie、およびaib。

多くのプログラマーと同様に"myApp.hpp"、アプリケーション固有のファイルの<libHeader.hpp>フォーム、およびライブラリーとコンパイラーのシステムファイル(つまり、/IINCLUDE環境変数で指定されたファイル)のフォームは、標準であると長年考えてきました。

ただし、C標準では、検索順序は実装固有であり、移植性が複雑になる可能性があるとされています。さらに悪いことに、私たちはインクルードファイルがどこにあるかを自動的に判断するjamを使用します。インクルードファイルには相対パスまたは絶対パスを使用できます。すなわち

#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
はい-依存関係を生成する方法はいくつかあります。それはそのうちの1つですが、それだけではありません。
プリフタン

15

#include ""コンパイラーの場合、通常、そのインクルードを含むファイルのフォルダーを検索してから、他のフォルダーを検索します。以下のために#include <>、コンパイラ、現在のファイルのフォルダを検索しません。


1
人々が反対する理由がわかりません。
Maxim Egorushkin 2012年

ほとんどの人がCWDのファイルのみをコンパイルするためだと思います。ディレクトリfooにいて、foo / unittest / bar.cをコンパイルしていて、そこにbar.hが含まれている場合、「bar.h」は機能しますが、<bar.h>は機能しません。

1
あなたが記述動作が標準C.はないので@Maximの人が同意
osvein

2
@Spookbusterそうです、標準は両方<filename>を述べ"filename"、実装定義の場所を検索します。
Maxim Egorushkin 2016

14

#include <filename>を使用すると、プリプロセッサはC \ C ++ヘッダーファイル(stdio.h \ cstdio、文字列、ベクターなど)のディレクトリでファイルを探します。しかし、#include "filename"を使用する場合:最初に、プリプロセッサは現在のディレクトリでファイルを探し、ここにない場合は、C \ C ++ヘッダーファイルのディレクトリで探します。


1
完全な回答が何年もの間利用可能であった後、なぜそれを提出するか、それは明らかに露骨に間違っていますか?一般的ですが、#includeディレクティブはファイルに厳密に関連しているわけではありません。
IInspectable 2018年

@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

規格で指定されていないために認識できないと単に述べるのではなく、規格一般的な実装規則の両方がここで関連していることを認めていただき、ありがとうございます。
カイルストランド

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ジョンソン

9

ここでの回答の多くは、ファイルを見つけるためにコンパイラーが検索するパスに焦点を当てています。これはほとんどのコンパイラーが行うことですが、準拠するコンパイラーは、標準ヘッダーの効果を使用して事前にプログラムでき、たとえば#include <list>スイッチとして扱うことができ、ファイルとして存在する必要はまったくありません。

これは純粋に仮説ではありません。そのように機能するコンパイラが少なくとも1つあります。#include <xxx>標準ヘッダーでのみ使用することをお勧めします。


9
#include <abc.h>

標準ライブラリファイルを含めるために使用されます。そのため、コンパイラは標準ライブラリヘッダーが存在する場所をチェックインします。

#include "xyz.h"

ユーザー定義のヘッダーファイルを含めるようコンパイラーに指示します。そのため、コンパイラーは、現在のフォルダーまたは-I定義されたフォルダーでこれらのヘッダーファイルをチェックします。


7

C ++では、次の2つの方法でファイルをインクルードします。

1つ目は#includeで、事前定義されたデフォルトの場所でファイルを探すようにプリプロセッサに指示します。この場所は、多くの場合、インクルードファイルへのパスを示すINCLUDE環境変数です。

2番目のタイプは#include "filename"です。これは、最初に現在のディレクトリでファイルを検索し、次にユーザーが設定した定義済みの場所で検索するようにプリプロセッサに指示します。


7

フォーム1-#include <xxx>

最初に、ディレクティブが呼び出された場所から現在のディレクトリにヘッダーファイルが存在するかどうかを調べます。見つからない場合は、事前構成された標準システムディレクトリのリストを検索します。

フォーム2-#include "xxx"

これは、ディレクティブが呼び出された場所から現在のディレクトリにヘッダーファイルの存在を探します。


正確な検索ディレクトリリストは、ターゲットシステム、GCCの構成方法、およびGCCのインストール場所によって異なります。-vオプションを付けて実行すると、GCCコンパイラの検索ディレクトリリストを見つけることができます。

-I dirを使用すると、検索パスにディレクトリを追加できます。これにより、dirは、現在のディレクトリ(ディレクティブの引用形式の場合)の後、標準のシステムディレクトリの前に検索されます。


基本的に、「xxx」という形式は、現在のディレクトリでの検索にすぎません。フォームのフォールバックが見つからない場合


3
十分に確立された正しい回答のある古い質問に回答することにした場合、その日の後半に新しい回答を追加しても、クレジットを得られない可能性があります。特徴的な新しい情報がある場合、または他の回答がすべて間違っていると確信している場合は、必ず新しい回答を追加してください。あなたに多くの信用を与えます。
ジョナサンレフラー

1
@ジョナサン・レフラーダーシャンの答えと同じくらい簡潔で正確だと感じている「定評のある」答えを教えてくれませんか?
personal_cloud

1
#include "header.h"フォームの説明は正確ではありません、@ personal_cloud。piCookieYann Droneaudの回答は、情報の出所を特定しているため、最も関連性が高いと思います。私もトップ投票の答えが完全に満足できるとは思いません。
ジョナサンレフラー

なぜこの回答が一番上に表示されているのに、さらに下に2つの回答があるのに、650票以上が投票されているのですか?この回答は、私が観察した行動と一致しないため、混乱しました。山かっこがエスケープされていないため、最後の文が壊れている可能性があります。どういう意味かはわかりません。
Neonit

6

#include <filename>システムファイルが参照されているときに使用されます。これは、/usr/includeまたはなどのシステムのデフォルトの場所にあるヘッダーファイルです/usr/local/include。別のプログラムに含める必要がある独自のファイルについては、#include "filename"構文を使用する必要があります。


6

"<filename>"は標準Cライブラリの場所を検索します

一方、「filename」は現在のディレクトリも検索します。

理想的には、標準Cライブラリには<...>を使用し、作成して現在のディレクトリに存在するライブラリには "..."を使用します。


4
他の情報にこの答えを追加する新しい情報はどれですか。
Daniel Langr 2018年

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:Library / Developer / CommandLineTools / usr / bin
"/ライブラリ/ Developer / 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 -stack-protector 1 -fblocks -fencode-extended-block-signature -fobjc-runtime = macosx-10.14。0 -fmax-type-align = 16 -fdiagnostics-show-option -fcolor-diagnostics -traditional-cpp -o--xc / dev / null
clang -cc1バージョン10.0.0(clang-1000.10.44.2)デフォルトのターゲットx86_64-apple-darwin18.0.0は存在しないディレクトリを無視します "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/local/include"存在しないを無視しますディレクトリ「/ライブラリ
/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/Library/Frameworks」#include "..."検索開始:
#include <...>検索開始:
/ usr / local / include
/ライブラリ/Developer/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(framework directory)
検索リストの終わり。


1
#include <file> 

デフォルトのインクルードディレクトリがあるファイルをインクルードします。

#include "file" 

コンパイルされた現在のディレクトリにファイルを含めます。


-2

#include文を書く方法は2つあります:

#include"filename"
#include<filename>

各フォームの意味は

#include"mylib.h"

このコマンドは、mylib.h設定されている可能性のあるインクルード検索パスで言及されているように、現在のディレクトリおよび指定されたディレクトリのリストでファイルを検索します。

#include<mylib.h>

このコマンドはmylib.h、指定されたディレクトリリストのみでファイルを検索します。

インクルード検索パスは、インクルードされるファイルを検索するディレクトリのリストにすぎません。異なるCコンパイラを使用すると、検索パスをさまざまな方法で設定できます。


1
十分に確立された正しい回答のある古い質問に回答することにした場合、その日の後半に新しい回答を追加しても、クレジットを得られない可能性があります。特徴的な新しい情報がある場合、または他の回答がすべて間違っていると確信している場合は、必ず新しい回答を追加してください。あなたに多くの信用を与えます。
ジョナサンレフラー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.