詳細なifndef
#ifndefは、「if not defined」の省略形です。前処理関数(マクロ定義、ファイルインクルード、条件付きコンパイル)での条件付きコンパイルです。ブランチの選択は、変数が定義されているかどうかに応じて行うことができます。その関数は次のとおりです。
- ヘッダーファイルの繰り返しのインクルードとコンパイルを防ぎます。
- プログラムのデバッグと移植を容易にします。
例を以下に説明します。
1.ヘッダーファイルの繰り返しのインクルードとコンパイルを防止します。
以下はエラーのデモンストレーションです。
headfile_1.h
1 #include <iostream>
2 class CTest_1 {
3 CTest_1() {
4 //do something,eg:init;
5 }
6 ~CTest_1() {
7 //do something ,eg:free;
8 }
9 void PrintScreen()
10 {
11 std::cout << "this is Class CTest_1!" << std::endl;
12 }
13 };
headfile_2.h
1 #include "headfile_1.h"
2 class CTest_2 {
3 CTest_2() {
4 //do something,eg:init;
5 }
6 ~CTest_2() {
7 //do something,eg:free;
8 }
9 void PrintScreen()
10 {
11 std::cout << "this is Class CTest_2!" << std::endl;
12 }
13 };
sourcefile.cpp
1 #include <iostream>
2 #include "headfile_1.h"
3 #include "headfile_2.h"
4
5 int main()
6 {
7 return 0;
8 }
コンパイル時にプロンプトの再定義エラー:
上記は、headfile_1.hのクラスCTest_1が再定義されたことを示しています。
一般に、2つのヘッダーファイル(headfile_1.hとheadfile_2.hなど)を含むCソースファイル(sourcefile.cppなど)があり、ヘッダーファイルheadfile_2.hにheadfile_1.hが含まれている場合、最終的な効果は次のようになります。ソースファイルにはheadfile_1.hが2回含まれています。ヘッダーファイルで構造またはクラスタイプを定義すると、問題が発生し、コンパイル中に重複した定義エラーが報告されます。
条件付きコンパイル「ifndef」を追加すると、問題を解決できます。次のように、headfile_1.hに条件付きコンパイルを追加します。
headfile_1.h
1 #ifndef _HEADFILE_1_H
2 #define _HEADFILE_1_H
3 #include <iostream>
4 class CTest_1 {
5 CTest_1() {
6 //do something,eg:init;
7 }
8 ~CTest_1() {
9 //do something ,eg:free;
10 }
11 void PrintScreen()
12 {
13 std::cout << "this is Class CTest_1!" << std::endl;
14 }
15 };
16
17 #endif //end of _HEADFILE_1_H
コンパイルして合格!
分析:headfile_1.hが初めて含まれる場合、_HEADFILE_1_Hが定義されておらず、条件がtrueであるため、#ifndef _HEADFILE_1_Hと#endifの間のコードが実行されます。headfile_1.hが2回目に含まれる場合、前の時間はDefine_HEADFILE_1_Hであり、条件はfalseであり、#ifndef _HEADFILE_1_Hと#endifの間のコードは再び含まれないため、再定義が回避されます。
概要:ヘッダーファイルの内容を#ifndefと#endifに入れます。ヘッダーファイルが複数のファイルによって参照されているかどうかに関係なく、これを追加することをお勧めします。一般的な形式は次のとおりです。
#ifndef <标识>
#define <标识>
......
......
#endif
<Identification>は理論的には自由に名前を付けることができますが、各ヘッダーファイルの「ID」は一意である必要があります。識別の明確なルールは、通常、ヘッダーファイル名を大文字にし、その前にアンダースコアを追加し、ファイル名の「。」を次のようにアンダースコアに変更することです。stdio.h
#ifndef _STDIO_H
#define _STDIO_H
......
......
#endif
注:#ifndef起到的效果是防止一个源文件多次包含同一个头文件
2つのソースファイルに同じヘッダーファイルが含まれないようにする代わりに。実際、同じヘッダーファイルが2つの異なるソースファイルにインクルードされるのを防ぐのは無理です。ヘッダーファイルの値は、異なるソースファイルにインクルードされます。
2.
プログラムのデバッグと移植が簡単プログラムをデバッグする場合、プログラムの内容を選択的にコンパイルする必要があることがよくあります。つまり、特定の条件に従ってコンパイルするかどうかを選択できます。
主に次のカテゴリに分類されます。
1、
#ifndef 标识符
程序段 1
#else
程序段 2
#endif
その機能は、「識別子」が#defineによって定義されていない場合、「ブロック1」をコンパイルし、そうでない場合は「ブロック2」をコンパイルすることです。
2、
#ifndef 标识符
#define 标识符
程序段 1
#else
程序段 2
#endif
その機能は、「識別子」が#defineによって定義されていない場合、「ブロック1」をコンパイルし、そうでない場合は「ブロック2」をコンパイルすることです。
3、
#if 表达式
程序段 1
#else
程序段 2
#endif
その機能は、「expression」値がtrueの場合は「block1」をコンパイルし、それ以外の場合は「block2」をコンパイルすることです。
注:上記の3つの形式の#elseは必須ではなく、省略できます。もちろん、#elseの後に#ifをネストする必要がある場合は、前処理コマンド#elifを使用できます。これは#else#ifと同等です。
概要:プログラムでの条件付きコンパイルの使用は、主にプログラムのデバッグと移植を容易にするためです。
転載元:https://www.cnblogs.com/codingmengmeng/p/7221295.html