0

この質問によると、それをどのように書くことができるかにはある程度の柔軟性があるようです--

#ifndef _HEADER_H

また:

#ifndef __HEADER___H__

など 決まったものではありません。

しかし、そもそもアンダースコアを使用する理由がまったくわかりません。なぜ私はただ書くことができないのですか:

#ifndef header.h

それの何がいけないの?あらゆる場所にアンダースコアを配置し、すべてを大文字にするのはなぜですか? プリプロセッサはアンダースコアで何をしますか?

4

2 に答える 2

6

header.hは有効な識別子ではありません。マクロ名にピリオドを含めることはできません。

つまり、インクルード ガード マクロに付ける名前は完全に任意です。結局のところ、それは単なる別の変数です。ファイルにちなんで名前を付けるのは、純粋に慣例です (衝突を避けるために合理的です)。

ヘッダー構造を大声で表現して、プリプロセッサが何をするかを確認することをお勧めします。

#ifndef MY_HEADER_H    /* If the macro MY_HEADER_H is not defined (yet)... */
#define MY_HEADER_H    /* ... then define it now ... */

...                    /* ... and deal with all this stuff ... */

#endif                 /* ... otherwise, skip all over it and go here. */

MY_HEADER_Hこのメカニズムは、またはその他で置き換えても同様に機能することがわかりますI_REALLY_LIKE_BANANAS。唯一の要件は、それが有効なマクロ識別子であり、他のインクルード ガードの名前と衝突しないことです。

上記の例では、マクロは空で定義されています。それは問題ありませんが、それが唯一の選択肢ではありません。2行目も同様に読むことができます

#define MY_HEADER_H 1

次に、マクロを に定義します1。これを行う人もいますが、実際には何も追加されず、値1はかなり恣意的です。私は一般的にこれをしません。唯一の利点は、 に定義すると、に加えて1も使用できることです。#if#ifdef

最後の注意事項: アンダースコアで始まる識別子、または 2 つ以上の連続したアンダースコア文字を含む識別子は実装用に予約されており、ユーザー コードでは使用しないでください。したがって、_MY_HEADER_H__MY_HEADER__H__はどちらも不幸な選択です。

あなたが言うなら、プリプロセッサが正しいヘッダーファイルを見つけるロジック

#include <myheader.h>

はまったく無関係です。ここでmyheader.hファイルに名前を付けると、プリプロセッサは多くのディレクトリ (通常は-Iコマンド ライン オプションで構成できます) でそれを検索します。ファイルを見つけて開いた後でのみ、ファイルの解析に進み、それによって、以前に解析したことがある場合は本質的にファイルをスキップするインクルード ガードを最終的に見つけます (したがって、インクルード ガード マクロはすでに定義されているため、最初のチェックで false と評価されます)。

于 2015-01-13T19:46:46.857 に答える