C プリプロセッサ演算子

提供:yonewiki
2022年9月26日 (月) 10:38時点におけるYo-net (トーク | 投稿記録)による版 (ページの作成:「C++へ戻る ※このページではC言語にも存在していたという意味で記事タイトルがC プリプロセッサ演算子になっていますが、<br /> C++でも同様です。C++だけの機能がある場合は明記します。<br /> <br /> <big><big>'''C プリプロセッサ演算子'''</big></big> マクロで引数付きのマクロが定義できることを紹介し…」)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)

C++へ戻る


※このページではC言語にも存在していたという意味で記事タイトルがC プリプロセッサ演算子になっていますが、
C++でも同様です。C++だけの機能がある場合は明記します。

C プリプロセッサ演算子


マクロで引数付きのマクロが定義できることを紹介しましたが、引数をどのように扱うかを変更するための演算子3つと、主に#ifディレクティブの条件記述のために利用される定義済マクロ判定を行う演算子1つで、プリプロセッサ演算子は全部で4種類あります。理解を助ける情報として、こういったモノもあるので、VisualStudio利用者の人ならば、参考にしてみて下さい。


  • #     文字列化演算子 2重引用符" "
  • #@    文字列定数化演算子 1重引用符' '
  • ##    トークン連結演算子
  • defined() defined演算子


#     文字列化演算子 2重引用符" "

マクロ引数を2重引用符のついた文字列として扱う演算子です。マクロ引数に2重引用符を使うわけですから、プログラムとしても2重引用符を使うような部分の置き換えのために利用するものです。したがって、文字列リテラルによる初期化やprintf命令や、文字列操作関数の引数といった文字列リテラルを必要とするようなプログラムソースコードのマクロ置換のために使われると考えればよいと思います。


具体的には以下のように利用します。

#define __MY_MACRO__( parameter ) printf(#parameter "\n")

int _tmain(arg,arg[]){
  __MY_MACRO__( output: );
  __MY_MACRO__( "output" ":" );
  __MY_MACRO__( \ );
}

int _tmain(arg,arg[]){
  printf("output:" "\n");
  printf("\"output\" \":\"" "\n");
  printf("\\" "\n");
}

のように置き換えられます。


引数の中で2重引用符中ではエスケープシーケンスが必要な文字が使われている場合は自動的にエスケープシーケンスによって文字列リテラルとして扱われるようにマクロによる置き換え処理をします。したがって、引数の中で\がつかわれていれば、自動で\\にしてくれるし、"が付かれていれば、\"とします。引数全体は2重引用符に囲われた文字列リテラルとして挿入されますので、引数で定義した文字列がマクロ定義によって置き換えるべき値が定義されていなくても、定義値に置き換えるような処理をしないため、動作に問題は生じません。


#@    文字列定数化演算子 1重引用符' '

マイクロソフト固有のディレクティブ演算子です。二重引用符の#ディレクティブ演算子とほぼ同じ動作として、一重引用符で文字列定数を扱うものになります。マクロ変数の引数に対して利用される点でも同じような利用方法になります。


具体的な利用例は以下のとおりです。

#define __MY_MACRO_SINGLE_QUART_( parameter ) #@parameter

int _tmain(arg,arg[]){
  char cSingleChar = __MY_MACRO_SINGLE_QUART_(&);
}

int _tmain(arg,arg[]){
  char cSingleChar = '&';
}

と置き換えられる。


##    トークン連結演算子

マクロ引数を利用する際、トークンとして独立していなければ引数として扱われない性質をもっていますが、このトークン連結演算子を使えば、この演算子に続く文字列がマクロ引数の文字列と一致した場合、トークンとしての独立していなくても引数値への置き換え処理を実施し、プログラムソースの文字列と連結することを実現します。


例えば以下のように利用することができます。

#define __MY_MACRO_TOKEN__( parameter ) int nDigit_##parameter = parameter

int _tmain(arg,arg[]){
  __MY_MACRO_TOKEN__(1);
}

int _tmain(arg,arg[]){
  int nDigit_1 = 1;
}

のように置き換えられます。


defined() Defined演算子

#if や #elif のようなディレクティブのあとの条件やその他のマクロ定義の返却値として利用することができる演算子で引数に記述した文字列がマクロ定義されていれば返却値は1で定義がなければ返却値は0となる演算子です。マクロ定義がされているかされていないかの結果を数値と返却した値に置き換えてくれる演算子です。


具体的には以下のように利用することができます。

#define __MY_MACRO__

int _tmain(arg,arg[]){
  int Macro;
#if defined(__MY_MACRO__)
  Macro = 1 
#else
  Macro = 0 
#endif
}

int _tmain(arg,arg[]){
  int Macro;
#if 1
  Macro = 1 
#else
  Macro = 0 
#endif
}

のように置き換えられ、最終的には

int _tmain(arg,arg[]){
  int Macro;
  Macro = 1 
}

となります。


C++へ戻る