Latest web development tutorials

Cプリプロセッサ

Cプリプロセッサの一部はコンパイラではありませんが、それは別のステップをコンパイルするプロセスです。要するに、Cプリプロセッサは、彼らが実際に必要とする前に、完全な前処理をコンパイルするようにコンパイラに指示するだけでテキスト置換ツールです。 我々は、Cプリプロセッサ(Cプリプロセッサ)は、CPPと略記されます。

すべての注文は、先頭にシャープ記号(#)で前処理されています。 それは、最初の非空白文字でなければなりません可読性を高めるために、プリプロセッサディレクティブは、最初の列で開始する必要があります。 以下に記載されているすべての重要なプリプロセッサ命令になります。

指令描述
#define定义宏
#include包含一个源代码文件
#undef取消已定义的宏
#ifdef如果宏已经定义,则返回真
#ifndef如果宏没有定义,则返回真
#if如果给定条件为真,则编译下面代码
#else#if 的替代方案
#elif如果前面的 #if 给定条件不为真,当前条件为真,则编译下面代码
#endif结束一个 #if……#else 条件编译块
#error当遇到标准错误时,输出错误消息
#pragma使用标准化方法,向编译器发布特殊的命令到编译器中

前処理の例

次の例に異なる命令を理解するための分析。

#define MAX_ARRAY_LENGTH 20

このディレクティブは、すべてのMAX_ARRAY_LENGTH 20を交換するCPPに指示します。 読みやすさを向上させるための定数を定義するための#defineを使用してください。

#include <stdio.h>
#include "myheader.h"

これらの命令は、システムライブラリから取得し現在のソースファイルにテキストを追加stdio.hのCPPを教えてください。次の行では、ローカルディレクトリから取得し、現在のソース・ファイルにコンテンツを追加myheader.h CPPに指示します。

#undef  FILE_SIZE
#define FILE_SIZE 42

このコマンドは、CPPが定義されFILE_SIZEをキャンセル、および42として定義伝えます。

#ifndef MESSAGE
   #define MESSAGE "You wish!"
#endif

このコマンドは、メッセージを定義したときMESSAGEのみ未定義CPPときにのみ通知します。

#ifdef DEBUG
   /* Your debugging statements here */
#endif

このコマンドは、DEBUGを定義する場合は、処理文を実行するCPPに指示します。 あなたはGCCコンパイラに-DDEBUGスイッチを渡すと、コンパイル時に、このコマンドは便利です。 それはあなたが常にオンまたはコンパイル時にデバッグをオフにすることができ、DEBUGを定義します。

定義済みマクロ

ANSI Cは、マクロの数を定義します。 プログラミングでは、あなたは、これらのマクロを使用できますが、別の直接これらの定義済みマクロを変更します。

描述
__DATE__当前日期,一个以 "MMM DD YYYY" 格式表示的字符常量。
__TIME__当前时间,一个以 "HH:MM:SS" 格式表示的字符常量。
__FILE__这会包含当前文件名,一个字符串常量。
__LINE__这会包含当前行号,一个十进制常量。
__STDC__当编译器以 ANSI 标准编译时,则定义为 1。

それでは、次の例を試してみましょう:

#include <stdio.h>

main()
{
   printf("File :%s\n", __FILE__ );
   printf("Date :%s\n", __DATE__ );
   printf("Time :%s\n", __TIME__ );
   printf("Line :%d\n", __LINE__ );
   printf("ANSI :%d\n", __STDC__ );

}

(ファイルtest.cの中で上記のコードをコンパイルして実行すると、次の結果が得られます。

File :test.c
Date :Jun 2 2012
Time :03:36:24
Line :8
ANSI :1

プリプロセッサ演算子

Cプリプロセッサは、マクロの作成を支援するために、次の演算子が用意されています。

マクロオペレータの継続(\)

マクロは通常、単一の行に書かれています。 しかし、マクロは、マクロ演算子(\)の継続を使用し、単一の行に収まらないほど長い場合。 例えば:

#define  message_for(a, b)  \
    printf(#a " and " #b ": We love you!\n")

文字列リテラルの量子化演算子(#)

マクロ定義では、文字列定数にマクロ引数を配置する必要がある場合、文字列定数の量子化演算子(#)。 演算子を使用したマクロは、特定のパラメータまたはパラメータのリストを持っています。 例えば:

#include <stdio.h>

#define  message_for(a, b)  \
    printf(#a " and " #b ": We love you!\n")

int main(void)
{
   message_for(Carole, Debra);
   return 0;
}

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

Carole and Debra: We love you!
トークンの貼り付け演算子(##)

マクロの定義内のトークン貼り付け演算子(##)は、2つのパラメータをマージします。 これは、2つの独立したマクロ定義タグは、タグに組み合わされることができます。 例えば:

#include <stdio.h>

#define tokenpaster(n) printf ("token" #n " = %d", token##n)

int main(void)
{
   int token34 = 40;
   
   tokenpaster(34);
   return 0;
}

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

token34 = 40

これは、この例では、コンパイラから次の実際の出力を生成しますので、それは、起こったのかです。

printf ("token34 = %d", token34);

この例では、トークンを示している##のnここでtoken34に接続し、我々は文字列定数の量子化演算子(#)、およびトークン演算子(##)を使用します

定義された()演算子

定義されたプリプロセッサ演算子は、識別子の#defineを使用して定義されているかどうかを決定するために使用される定数式で使用されています。指定した識別子が既に定義されている場合、値は(ゼロ以外)が真です。 指定した識別子が定義されていない場合、値が偽(ゼロ)です。 次の例では、定義された()演算子の使用方法を示しています。

#include <stdio.h>

#if !defined (MESSAGE)
   #define MESSAGE "You wish!"
#endif

int main(void)
{
   printf("Here is the message: %s\n", MESSAGE);  
   return 0;
}

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

Here is the message: You wish!

パラメータ化されたマクロ

CPPは、パラメータ化されたマクロ機能をシミュレートするために使用できる強力な機能です。 たとえば、次のコードでは、数の二乗を計算することです。

int square(int x) {
   return x * x;
}

次のように私たちは、上記のコードを書き換えるマクロを使用することができます。

#define square(x) ((x) * (x))

パラメータを使用してマクロを使用する前に、の#defineディレクティブを使用する必要があります。パラメータリストは括弧で囲まれ、マクロ名の直後でなければなりません。 マクロ名と左括弧の間にスペースは許可されていません。 例えば:

#include <stdio.h>

#define MAX(x,y) ((x) > (y) ? (x) : (y))

int main(void)
{
   printf("Max between 20 and 10 is %d\n", MAX(10, 20));  
   return 0;
}

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

Max between 20 and 10 is 20