目次→その他→
プリ・プロセッサ→メタ・コマンド→
#DEFINE←オリジナル・サイト
マクロを定義する、プリ・プロセッサ指示文
構文:
#define identifier body
#define identifier( [ parameters ] ) body
#define identifier( [ parameters, ] variadic_parameter... ) body
説明:
#define は、テキスト・ベースのプリ・プロセッサー・マクロを宣言することを可能にします。
一旦コンパイラーが
#define を見たら、コンパイラーは、
identifier のさらなる発生を
body と入れ替え始めます。
body は空かもしれません。
拡張は、拡張することがさらに何もなく、コンパイラーが結果として生じるコードを分析し続けることができるまで、再帰的に行われます。
#undef は、コンパイラーを
#define について忘れさせるために使うことができます。
Parameters は、定義を関数のようなマクロに変換し、テキスト引数をマクロに渡すことができます。
body 内のパラメーター名は、展開時に、指定された引数テキストに置き換えられます。
リテラルがマクロに渡される場合、マクロ本体の、対応するパラメーターの名前は、手続き本体にあるようローカル変数としては使えません。
手続きと同じ機能をエミュレートするには、ユーザーは、マクロの本体でローカル変数(別の名前)を明示的に宣言し、渡されたパラメーター名(渡されたリテラルによって前処理で置き換えられる)で初期化する必要があります。
# stringize 演算子を、マクロ・パラメーターで使って、文字列リテラルに変換できます。
また、
## concatenate 演算子を使って、トークンを合わせて連結できます。
注意:関数のような
#define 宣言では、
identifier の直後に空白を入れずに開き括弧 (
() を付ける必要があります。そうしないと、コンパイラーはそれを
body の一部として扱います。
定義は、
scoped;
定義は、定義された範囲の中だけで目に見えます。
モジュール・レベルで定義されれば、定義はモジュールの中にわたって目に見えます。
identifier が、範囲(
Sub,
For..Next,
While..Wend,
Do..Loop,
Scope..End Scope など)がある複合文の中で定義される場合、
identifier 定義は、その範囲内だけで目に見えます。
一方、名前空間は、定義の可視性には、なにも効果ありません。
Identifier は、
#ifdef 他でチェックできます。これは、コンパイラー(条件付きコンパイル)から、コードの一部を隠すために使うことができます。
マクロ展開の結果は、
-pp コンパイラ・オプションを使ってチェックできます。
#define は、しばしば定数を宣言するために使われます。
Const 命令文は、型安全な代替手段です。
警告: 定義本体に、1つ以上の演算子を含む式が含まれている場合、演算子の不要な優先順位の変更が発生しないように、一部の用語(パラメーター、本体全体)を括弧で囲む必要がある場合があります。
(引数として演算子も含む式を渡す場合や、演算子も含むメイン式で定義を使う場合)。
例:
'' 定義とチェック
#define DEBUGGING
#ifdef DEBUGGING
' ... 命令文
#endif
'' 簡単な定義/テキスト交換
#define FALSE 0
#define TRUE (Not FALSE)
'' 関数のような定義
#define MyRGB(R,G,B) (((R)Shl 16) Or ((G)Shl 8) Or (B))
Print Hex( MyRGB(&hff, &h00, &hff) )
'' 定義の中の、継続行と命令文
#define printval(bar) _
Print #bar; " ="; bar
'' #defines は、それが定義された scope の中だけで、見えます
Scope
#define LOCALDEF 1
End Scope
#ifndef LOCALDEF
# Print LOCALDEF Is Not defined
#endif
'' 名前空間は、定義の可視性に影響を及ぼしません
Namespace foo
# define NSDEF
End Namespace
#ifdef NSDEF
# Print NSDEF Is defined
#endif
QBとの違い:
参照: