CおよびC ++プログラミング言語では、include
次のように、山かっこを使用することとステートメントで引用符を使用することの違いは何ですか?
#include <filename>
#include "filename"
CおよびC ++プログラミング言語では、include
次のように、山かっこを使用することとステートメントで引用符を使用することの違いは何ですか?
#include <filename>
#include "filename"
回答:
実際には、プリプロセッサがインクルードされたファイルを検索する場所が異なります。
ために #include <filename>
、通常の検索ディレクトリで実装依存的にプリプロセッサを検索し、コンパイラ/ IDEによって指定事前。このメソッドは通常、標準ライブラリヘッダーファイルを含めるために使用されます。
#include "filename"
プリプロセッサの場合、最初にディレクティブを含むファイルと同じディレクトリを検索し、次に、#include <filename>
フォームに。このメソッドは通常、プログラマー定義のヘッダーファイルを含めるために使用されます。
#include <...>
、システムにインストールされているパッケージを#include "..."
使用し、近くのリポジトリバージョンを使用しました。私はそれらを後方に持っているかもしれません。どちらの方法でも、パッケージ化されたヘッダーのインクルードガードの前にはアンダースコアが付けられます。(バージョンの修飾子は私にはより理にかなっていますが、それはパッケージの規則または2つを意図的に混在させない方法である可能性があります。)
知る唯一の方法は、実装のドキュメントを読むことです。
で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:改行文字を除くソース文字セットの任意のメンバーと
"
<と>の間の文字シーケンスは一意にヘッダーを参照しますが、これは必ずしもファイルである必要はありません。実装では、文字シーケンスを自由に使用できます。(ただし、ほとんどの場合、それをファイル名として扱い、他の投稿の状態と同様に、インクルードパスで検索を行います。)
#include "file"
フォームが使用されている場合、サポートは、指定された名前のファイルを最初に検索します(サポートされている場合)。サポートされていない場合、または検索が失敗した場合、実装は他の(#include <file>
)形式が使用されているかのように動作します。
また、3番目の形式が存在し、#include
ディレクティブが上記のいずれの形式とも一致しない場合に使用されます。この形式では、いくつかの基本的な前処理(マクロ展開など)が#include
ディレクティブの「オペランド」で行われ、結果は他の2つの形式のいずれかと一致すると予想されます。
<
して>
、ライブラリへのインデックスのキーとして。
ここでいくつかの良い答えは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では定義されていないようです)。
c99
CコンパイラのPOSIX名)にあります。(POSIX 2008標準ではC11をほとんど参照できません。POSIX2008への2013年の更新では、参照されているC標準は変更されませんでした。)
-L
。
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つの円記号を含むファイル名を指定します。(システムによっては、「\」をパス名の区切り文字として解釈します。これらのすべても‘/’
同じように解釈します‘/’
。のみを使用するのが最も移植性があります。)ファイル名の後の行に(コメント以外の)何かがあると、エラーになります。
します:
"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
、別のディレクトリを含んで、動作は未定義です。
#include "mypath/myfile"
と同等ではありません#include "./mypath/myfile"
。piCookieの回答にあるように、二重引用符は、コンパイラーに実装定義の方法で検索するように指示し#include <...>
ます。これには、で指定された場所での検索が含まれます。(実際には、それはおそらく同等ですが、たとえば、少なくともUnixライクなシステムで/usr/include/mypath/myfile
は、これを次のように参照できるため/usr/include/./mypath/myfile
です。)
defaultincludepaths
.
#include "..."
#include <...>
<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>
。残りは実装定義です。
-I
ビジネスが指定されているC標準の場所への参照を提供できますか?
-I
。
#include <file.h>
「includes」ディレクトリでヘッダーを検索するようコンパイラーに指示します。たとえば、MinGWの場合、コンパイラーはfile.h
C:\ MinGW \ include \またはコンパイラーがインストールされている場所で検索します。
#include "file"
現在のディレクトリ(つまり、ソースファイルが存在するディレクトリ)でを検索するようコンパイラーに指示しますfile
。
-I
GCC のフラグを使用して、山かっこを含むインクルードを検出した場合、の後のディレクトリでヘッダーも検索する必要があることを通知できます-I
。GCCは、フラグの後のディレクトリを、それがincludes
ディレクトリであるかのように扱います。
たとえばmyheader.h
、自分のディレクトリにファイルが呼び出された#include <myheader.h>
場合、フラグ-I .
(現在のディレクトリでインクルードを検索する必要があることを示す)を指定してGCCを呼び出したかどうかを確認できます。
なければ-I
フラグ、あなたが使用する必要があります#include "myheader.h"
ファイル、または移動含めることmyheader.h
へのinclude
あなたのコンパイラのディレクトリを。
標準では-はい、それらは異なります:
次の形式の前処理ディレクティブ
#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 <...>
(インクルードパス、システムヘッダーなど)を検索します。 )。
すばらしい回答をありがとう、特に。Adam StelmaszczykとpiCookie、およびaib。
多くのプログラマーと同様に"myApp.hpp"
、アプリケーション固有のファイルの<libHeader.hpp>
フォーム、およびライブラリーとコンパイラーのシステムファイル(つまり、/I
とINCLUDE
環境変数で指定されたファイル)のフォームは、標準であると長年考えてきました。
ただし、C標準では、検索順序は実装固有であり、移植性が複雑になる可能性があるとされています。さらに悪いことに、私たちはインクルードファイルがどこにあるかを自動的に判断するjamを使用します。インクルードファイルには相対パスまたは絶対パスを使用できます。すなわち
#include "../../MyProgDir/SourceDir1/someFile.hpp"
以前のバージョンのMSVSでは二重のバックスラッシュ(\\)が必要でしたが、現在は不要です。いつ変わったのかわかりません。'nixとの互換性のためにスラッシュを使用してください(Windowsはこれを受け入れます)。
本当に心配な場合は"./myHeader.h"
、ソースコードと同じディレクトリにあるインクルードファイルを使用してください(私の現在の非常に大きなプロジェクトには、重複したインクルードファイル名が散らばっています-本当に構成管理の問題です)。
引用フォーム
プリプロセッサは、次の順序でインクルードファイルを検索します。
- #includeステートメントを含むファイルと同じディレクトリ内。
- 現在開かれているインクルードファイルのディレクトリに、開かれたときとは逆の順序で含まれます
。検索は、親インクルードファイルのディレクトリから始まり、
祖父母のインクルードファイルのディレクトリを上方向に進みます。- 各
/I
コンパイラオプションで指定されたパスに沿って。INCLUDE
環境変数で指定されたパスに沿って。山かっこ形式
プリプロセッサは、次の順序でインクルードファイルを検索します。
- 各
/I
コンパイラオプションで指定されたパスに沿って。- コマンドラインで、
INCLUDE
環境変数で指定されたパスに沿ってコンパイルが行われる場合。
少なくともGCCバージョン<= 3.0の場合、山かっこ形式では、インクルードファイルとインクルードファイルの間に依存関係が生成されません。
したがって、依存関係ルールを生成する場合(例としてGCC -Mオプションを使用)、依存関係ツリーに含める必要のあるファイルには引用符で囲まれた形式を使用する必要があります。
(http://gcc.gnu.org/onlinedocs/cpp/Invocation.htmlを参照してください)
#include ""
コンパイラーの場合、通常、そのインクルードを含むファイルのフォルダーを検索してから、他のフォルダーを検索します。以下のために#include <>
、コンパイラ、現在のファイルのフォルダを検索しません。
<filename>
を述べ"filename"
、実装定義の場所を検索します。
#include <filename>を使用すると、プリプロセッサはC \ C ++ヘッダーファイル(stdio.h \ cstdio、文字列、ベクターなど)のディレクトリでファイルを探します。しかし、#include "filename"を使用する場合:最初に、プリプロセッサは現在のディレクトリでファイルを探し、ここにない場合は、C \ C ++ヘッダーファイルのディレクトリで探します。
#include
ディレクティブはファイルに厳密に関連しているわけではありません。
山かっこを含む#includeは、「実装に依存する場所のリスト」(「システムヘッダー」を言う非常に複雑な方法です)を検索して、ファイルを含めます。
引用符付きの#includeは、ファイルを検索するだけです(そして、「実装に依存する方法で」、blehを実行します)。つまり、通常の英語では、あなたが投げたパス/ファイル名を適用しようとし、システムパスを付加したり、それ以外の方法で改ざんしたりしません。
また、#include ""が失敗した場合、標準では#include <>として再読み取りされます。
GCCのドキュメントでは、 gccとない標準に特異的であるが、(コンパイラ固有の)説明は、ISO規格の弁護士スタイルの話よりも理解することがはるかに簡単ですしています。
zlib.h
、「ユーザー」の検索パスにあり、システムの検索パスに別のバージョンが存在する場合#include <zlib.h>
、システムのバージョンと#include "zlib.h"
自分のバージョンを含めますか?
#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"
#include <>
事前定義されたヘッダーファイル用ですヘッダーファイルが事前定義されている場合は、山かっこでヘッダーファイル名を記述するだけで、次のようになります(事前定義されたヘッダーファイル名iostreamがある場合)。
#include <iostream>
#include " "
プログラマーが定義するヘッダーファイル用あなた(プログラマー)が独自のヘッダーファイルを作成した場合は、ヘッダーファイル名を引用符で囲みます。したがって、と呼ばれるヘッダーファイルmyfile.h
を作成した場合、次の例はincludeディレクティブを使用してそのファイルをインクルードする方法の例です。
#include "myfile.h"
最初に、ディレクティブが呼び出された場所から現在のディレクトリにヘッダーファイルが存在するかどうかを調べます。見つからない場合は、事前構成された標準システムディレクトリのリストを検索します。
これは、ディレクティブが呼び出された場所から現在のディレクトリにヘッダーファイルの存在を探します。
正確な検索ディレクトリリストは、ターゲットシステム、GCCの構成方法、およびGCCのインストール場所によって異なります。-vオプションを付けて実行すると、GCCコンパイラの検索ディレクトリリストを見つけることができます。
-I dirを使用すると、検索パスにディレクトリを追加できます。これにより、dirは、現在のディレクトリ(ディレクティブの引用形式の場合)の後、標準のシステムディレクトリの前に検索されます。
基本的に、「xxx」という形式は、現在のディレクトリでの検索にすぎません。フォームのフォールバックが見つからない場合
#include "header.h"
フォームの説明は正確ではありません、@ personal_cloud。piCookieとYann Droneaudの回答は、情報の出所を特定しているため、最も関連性が高いと思います。私もトップ投票の答えが完全に満足できるとは思いません。
"<filename>"は標準Cライブラリの場所を検索します
一方、「filename」は現在のディレクトリも検索します。
理想的には、標準Cライブラリには<...>を使用し、作成して現在のディレクトリに存在するライブラリには "..."を使用します。
単純な一般的な規則は、山かっこを使用して、コンパイラに付属するヘッダーファイルを含めることです。他のヘッダーファイルを含めるには、二重引用符を使用します。ほとんどのコンパイラはこの方法でそれを行います。
1.9 —ヘッダーファイルでは、プリプロセッサディレクティブについて詳しく説明しています。あなたが初心者プログラマーであるなら、そのページはそれらすべてを理解するのに役立つはずです。私はここからそれを学び、仕事でそれを追跡しています。
#include <filename>
C / C ++システムまたはコンパイラライブラリのヘッダーファイルを使用する場合に使用します。これらのライブラリには、stdio.h、string.h、math.hなどがあります。
#include "path-to-file/filename"
プロジェクトフォルダーまたは他の場所にある独自のカスタムヘッダーファイルを使用する場合に使用します。
プリプロセッサとヘッダーの詳細については。C-プリプロセッサを読んでください。
#include <filename>
#include "filename"
#include <filename>
は、システムヘッダーファイルが格納されている場所と同じように動作し、そのヘッダーファイルを検索します。#include <filename>
。現在の設定に基づいて、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)
検索リストの終わり。
#include文を書く方法は2つあります:
#include"filename"
#include<filename>
各フォームの意味は
#include"mylib.h"
このコマンドは、mylib.h
設定されている可能性のあるインクルード検索パスで言及されているように、現在のディレクトリおよび指定されたディレクトリのリストでファイルを検索します。
#include<mylib.h>
このコマンドはmylib.h
、指定されたディレクトリリストのみでファイルを検索します。
インクルード検索パスは、インクルードされるファイルを検索するディレクトリのリストにすぎません。異なるCコンパイラを使用すると、検索パスをさまざまな方法で設定できます。