質問: ### インクルードガードとは... マクローリン級数展開を利用しsin(x)の関数を作成しました。 そしてこのsin(x)などの関数をまとめてヘッダファイルとして新しく作成したいです。 ### 試したこと 呼び出し元 ``` #include #include #define PI 3.14159265 int main(void){ //Original.hの中にある関数を呼び出して実験しています } ``` ``` //Original.h #include #define PI 3.1415 double sine(double deg){ //マクローリンのアルゴリズムがあります。 } ``` このときエラーが出ます。当たり前ですが。。。 これらについて調べてみたところ#ifndef - #Endif というマクロがあるのまでは分かったのですが、理解ができません。 この場合であればstdio.hがすでにインクルードされているか。されていなかったときのみインクルードする方法。PIについてもすでに定義されているか調べ、されていなかったらPIについて定義する方法をご示唆お願いします。 ### 環境 Visual Studio 2015 ### 余談 余談ですがVisual Studio 使うときになぜstdafx.hをインクルードしないといけないのですか? またstdafx.hをインクルードしないで使用する方法とかございましたら教えてください。
回答: > > これらについて調べてみたところ#ifndef - #Endif というマクロがあるのまでは分かったのですが、理解ができません。 > > > インクルードガードは、だいたいこんな感じで書きます。 ``` #ifndef MYPROJECT_ORIGINAL_H_ #define MYPROJECT_ORIGINAL_H_ //Original.h #include #define PI 3.1415 double sine(double deg){ //マクローリンのアルゴリズムがあります。 } #endif // MYPROJECT_ORIGINAL_H_ ``` インクルードガードは同じヘッダーファイルを何度も読み込ませないための仕組みです。 コンパイラーによって初めてそのファイルを読もうとするときには`MYPROJECT_ORIGINAL_H_`が定義されていないので、`#ifndef`に合致し、対応する`#endif`までが読み込まれます。その際、`#ifndef`の次の行の`#define MYPROJECT_ORIGINAL_H_`が実行されます。 2度目に同じファイルを読もうとしたときは、すでに`MYPROJECT_ORIGINAL_H_`マクロが定義されているため、`#ifndef`に合致せず、`#endif`まで読み飛ばされます。 > > この場合であればstdio.hがすでにインクルードされているか。されていなかったときのみインクルードする方法。 > > > stdio.hはすでにインクルードガードが施されているので気にする必要はありません。 > > PIについてもすでに定義されているか調べ、されていなかったらPIについて定義する方法をご示唆お願いします。 > > > マクロ単体でそのようにすることは通常はあまりありません。異なる値が定義されると、どれが使われるかによって結果が変わってしまうからです。Original.hの中で使うためのPIなら`#define ORIGINAL_PI 3.14......`という具合に、名前を変えて区別する方が良いです。 それと、ヘッダーの中に関数を書く場合はインライン関数にしてください。 ``` inline double sine(double deg){ ``` > > 余談ですがVisual Studio 使うときになぜstdafx.hをインクルードしないといけないのですか? > > またstdafx.hをインクルードしないで使用する方法とかございましたら教えてください。 > > > いけないわけではなく、「プリコンパイル済みヘッダー」の機能が使えるようにプロジェクト作成時にデフォルトで組み込まれているのです。プロジェクトのプロパティのC/C++の「プリコンパイル済みヘッダー」の設定で「プリコンパイル済みヘッダー」を「プリコンパイル済みヘッダーを使用しない」に変更するとstdafx.hをインクルードしなくても良くなります。