Cplusplus-cpp-preprocessor

提供:Dev Guides
移動先:案内検索

C ++プリプロセッサ

プリプロセッサはディレクティブであり、実際のコンパイルが開始される前に情報を前処理するようコンパイラに指示します。

すべてのプリプロセッサディレクティブは#で始まり、行のプリプロセッサディレクティブの前には空白文字のみが表示されます。 プリプロセッサディレクティブはC ++ステートメントではないため、セミコロン(;)で終了しません。

すべての例で、すでに*#include *ディレクティブを見ています。 このマクロは、ソースファイルにヘッダーファイルを含めるために使用されます。

#include、#define、#if、#else、#lineなど、C ++でサポートされるプリプロセッサディレクティブが多数あります。 重要な指令を見てみましょう-

#defineプリプロセッサ

  1. defineプリプロセッサディレクティブは、シンボリック定数を作成します。 記号定数は*マクロ*と呼ばれ、指令の一般的な形式は次のとおりです-
#define macro-name replacement-text

この行がファイルに表示されると、プログラムがコンパイルされる前に、そのファイル内の後続のすべてのマクロがreplacement-textに置き換えられます。 たとえば-

#include <iostream>
using namespace std;

#define PI 3.14159

int main () {
   cout << "Value of PI :" << PI << endl;

   return 0;
}

次に、このコードの前処理を行って、ソースコードファイルがあると仮定して結果を確認します。 -Eオプションを付けてコンパイルし、結果をtest.pにリダイレクトしましょう。 さて、あなたがtest.pをチェックした場合、それは多くの情報を持っているでしょうし、下部に、次のように置き換えられた値を見つけるでしょう-

$gcc -E test.cpp > test.p

...
int main () {
   cout << "Value of PI :" << 3.14159 << endl;
   return 0;
}

関数のようなマクロ

あなたは次のように引数を取るマクロを定義するために#defineを使用することができます-

#include <iostream>
using namespace std;

#define MIN(a,b) (((a)<(b)) ? a : b)

int main () {
   int i, j;

   i = 100;
   j = 30;

   cout <<"The minimum is " << MIN(i, j) << endl;

   return 0;
}

上記のコードをコンパイルして実行すると、次の結果が生成されます-

The minimum is 30

条件付きコンパイル

プログラムのソースコードの選択部分をコンパイルするために使用できるディレクティブがいくつかあります。 このプロセスは条件付きコンパイルと呼ばれます。

条件付きプリプロセッサ構造は、「if」選択構造によく似ています。 次のプリプロセッサコードを考慮してください-

#ifndef NULL
   #define NULL 0
#endif

デバッグ目的でプログラムをコンパイルできます。 また、次のように単一のマクロを使用してデバッグをオンまたはオフにすることができます-

#ifdef DEBUG
   cerr <<"Variable x = " << x << endl;
#endif

これにより、ディレクティブ#ifdef DEBUGの前にシンボリック定数DEBUGが定義されている場合、 cerr ステートメントがプログラムでコンパイルされます。 あなたは次のようにプログラムの一部をコメントアウトするために#if 0文を使用することができます-

#if 0
   code prevented from compiling
#endif

私たちは次の例を試してみましょう-

#include <iostream>
using namespace std;
#define DEBUG

#define MIN(a,b) (((a)<(b)) ? a : b)

int main () {
   int i, j;

   i = 100;
   j = 30;

#ifdef DEBUG
   cerr <<"Trace: Inside main function" << endl;
#endif

#if 0
  /*This is commented part*/
   cout << MKSTR(HELLO C++) << endl;
#endif

   cout <<"The minimum is " << MIN(i, j) << endl;

#ifdef DEBUG
   cerr <<"Trace: Coming out of main function" << endl;
#endif

   return 0;
}

上記のコードをコンパイルして実行すると、次の結果が生成されます-

The minimum is 30
Trace: Inside main function
Trace: Coming out of main function

#および##演算子

#および##プリプロセッサ演算子は、C ++およびANSI/ISO Cで使用できます。 #演算子は、置換テキストトークンを引用符で囲まれた文字列に変換します。

次のマクロ定義を考慮してください-

#include <iostream>
using namespace std;

#define MKSTR( x ) #x

int main () {

   cout << MKSTR(HELLO C++) << endl;

   return 0;
}

上記のコードをコンパイルして実行すると、次の結果が生成されます-

HELLO C++

どのように機能したか見てみましょう。 C ++プリプロセッサが行を変えることを理解するのは簡単です-

cout << MKSTR(HELLO C++) << endl;

上記の行は次の行に変わります-

cout << "HELLO C++" << endl;
    1. 演算子は、2つのトークンを連結するために使用されます。 ここに例があります-
#define CONCAT( x, y )  x ## y

CONCATがプログラムに表示されると、その引数が連結され、マクロを置き換えるために使用されます。 たとえば、次のように、プログラムではCONCAT(HELLO、C )は「HELLO C 」に置き換えられます。

#include <iostream>
using namespace std;

#define concat(a, b) a ## b
int main() {
   int xy = 100;

   cout << concat(x, y);
   return 0;
}

上記のコードをコンパイルして実行すると、次の結果が生成されます-

100

どのように機能したか見てみましょう。 C ++プリプロセッサが変換することを理解するのは簡単です-

cout << concat(x, y);

上記の行は次の行に変換されます-

cout << xy;

定義済みのC ++マクロ

C ++は、以下に示す事前定義されたマクロの数を提供します

Sr.No Macro & Description
1

LINE

これには、コンパイル中のプログラムの現在の行番号が含まれます。

2

FILE

これには、コンパイル中のプログラムの現在のファイル名が含まれます。

3

DATE

これには、ソースファイルをオブジェクトコードに変換した日付である月/日/年の形式の文字列が含まれます。

4

TIME

これには、時間:分:秒という形式の文字列が含まれます。これは、プログラムがコンパイルされた時刻です。

上記のすべてのマクロの例を見てみましょう-

#include <iostream>
using namespace std;

int main () {
   cout << "Value of __LINE__ : " << __LINE__ << endl;
   cout << "Value of __FILE__ : " << __FILE__ << endl;
   cout << "Value of __DATE__ : " << __DATE__ << endl;
   cout << "Value of __TIME__ : " << __TIME__ << endl;

   return 0;
}

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Value of __LINE__ : 6
Value of __FILE__ : test.cpp
Value of __DATE__ : Feb 28 2011
Value of __TIME__ : 18:52:48