インクルードガード
CoddyのCジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 2/61。
プロジェクト内でヘッダーファイルが複数回インクルードされると、コンパイラーは同じ宣言を繰り返し認識し、エラーが発生します。これは、複数のファイルが同じヘッダーをインクルードする場合や、ヘッダー同士が互いにインクルードする場合によく起こります。インクルードガードを使えば、この問題を解決できます。
インクルードガードは、ヘッダーの内容が一度だけ処理されるように、3つのプリプロセッサディレクティブを使用します。
// math_utils.h
#ifndef MATH_UTILS_H
#define MATH_UTILS_H
int add(int a, int b);
#endif
仕組みは次のとおりです。#ifndef MATH_UTILS_Hは、シンボルMATH_UTILS_Hがまだ定義されていないかどうかを確認します。定義されていなければ、プリプロセッサは処理を続け、直ちに#define MATH_UTILS_Hで定義します。この時点から#endifまでのすべてがコンパイルに含まれます。
このヘッダーが2回目にインクルードされるとき、MATH_UTILS_Hはすでに定義されているため、ブロック全体がスキップされます。ガード名には通常、ファイル名を大文字にし、ドットや特殊文字をアンダースコアに置き換えたものを使います。
作成するすべてのヘッダーファイルにはインクルードガードを付けましょう。これは、コンパイルエラーを防ぎ、プロジェクト内のどこからでも安全にインクルードできるようにする標準的な慣習です。
チャレンジ
簡単インクルードガードを追加して、ヘッダーファイルが二重にインクルードされないようにしましょう。前のレッスンで作成した挨拶ユーティリティを基にしますが、今回はヘッダーを複数回インクルードしても安全なようにします。
次の2つのファイルを作成します。
greet.h:greet関数の宣言を含むヘッダーファイルです。今回は、シンボルGREET_Hを使ったインクルードガードで内容全体を囲みます。main.c:ヘッダーをインクルードし、greet関数を実装して、main()から呼び出すメインファイルです。
greet関数は、名前を受け取るconst char*型のパラメーターを受け取り、次の内容を出力します。
Hello, Alice!ヘッダーファイルは次の構造にしてください。
#ifndef GREET_H
#define GREET_H
// function declaration here
#endif入力は1つです。名前(文字列)が与えられます。
上記の形式で、挨拶メッセージを正確に出力してください。その際、Aliceを与えられた名前に置き換えてください。
自分で試してみよう
#include <stdio.h>
#include "greet.h"
// TODO: "Hello, <name>!" を出力する greet 関数を実装する
int main() {
char name[100];
scanf("%s", name);
// TODO: name を引数にして greet 関数を呼び出す
return 0;
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Cオンラインコンパイラ