C マクロ 新しいページはコチラ
提供: yonewiki
(→#define) |
|||
1行: | 1行: | ||
+ | [[C PlusPlus#Cにもあった技術|C++]]へ戻る | ||
+ | |||
+ | |||
※このページではC言語にも存在していたという意味で記事タイトルがC マクロになっていますが、<br /> | ※このページではC言語にも存在していたという意味で記事タイトルがC マクロになっていますが、<br /> | ||
[[C PlusPlus|C++]]でも同様です。[[C PlusPlus|C++]]だけの機能がある場合は明記します。<br /> | [[C PlusPlus|C++]]でも同様です。[[C PlusPlus|C++]]だけの機能がある場合は明記します。<br /> | ||
5行: | 8行: | ||
− | マクロはC++言語においては、プリプロセッサの中での変数を使ったプログラム全体のテキスト文字列の一括置換処理を行う処理のための命令を意味していて、#define ディレクティブによってマクロ変数を定義できます。 簡単な使い方から複雑な使い方であるものまで種々のマクロが存在するため、最初の基礎の理解だけに留めていると、複雑なマクロ変数や変数の定義であるマクロ宣言に出くわしたとき、理解に苦しむことになります。 | + | マクロはC++言語においては、プリプロセッサの中での変数を使ったプログラム全体のテキスト文字列の一括置換処理を行う処理のための命令を意味していて、#define ディレクティブによってマクロ変数を定義できます。 簡単な使い方から複雑な使い方であるものまで種々のマクロが存在するため、最初の基礎の理解だけに留めていると、複雑なマクロ変数や変数の定義であるマクロ宣言に出くわしたとき、理解に苦しむことになります。[[VC PlusPlus:マクロ定義を展開した後のプログラムを確認する方法|こういう方法]]もあるので、VisualStudio利用者の人ならば、参考にしてみて下さい。 |
11行: | 14行: | ||
==='''#define'''=== | ==='''#define'''=== | ||
+ | |||
まず、マクロの基本ですが、マクロ変数を定義するだけで、変数の中に入れる値を意識しない使い方は以下のとおりです。プログラム全体に関わる定数値処理や定型文法処理の切り替えが必要な時に活用することができます。サンプルでは一回だけの変換につかっているので実用的ではありませんが、変換の具体例を示すための強引なマクロ利用サンプルになっていることに留意して下さい。 | まず、マクロの基本ですが、マクロ変数を定義するだけで、変数の中に入れる値を意識しない使い方は以下のとおりです。プログラム全体に関わる定数値処理や定型文法処理の切り替えが必要な時に活用することができます。サンプルでは一回だけの変換につかっているので実用的ではありませんが、変換の具体例を示すための強引なマクロ利用サンプルになっていることに留意して下さい。 | ||
83行: | 87行: | ||
int main(){ | int main(){ | ||
int nMacroValue; | int nMacroValue; | ||
− | int | + | int nMacroValue1; |
− | int | + | int x = 20; |
− | nMacroValue = __MY_MACRO_ADD_( | + | int y = 30; |
+ | nMacroValue = __MY_MACRO_ADD_(x, y) * 10; | ||
nMacroValue1 = __MY_MACRO_ADD_(90, 110) * 10; | nMacroValue1 = __MY_MACRO_ADD_(90, 110) * 10; | ||
} | } | ||
93行: | 98行: | ||
int main(){ | int main(){ | ||
int nMacroValue; | int nMacroValue; | ||
− | int | + | int x = 20; |
− | int | + | int y = 30; |
− | nMacroValue = (20 + 30) * 10 | + | int nMacroValue; |
− | nMacroValue1 = (90 + 110) * 10; | + | int nMacroValue1; |
+ | nMacroValue = ( x + y ) * 10;// x = 20,y = 30, | ||
+ | //( 20 + 30 ) *10 → 500 | ||
+ | nMacroValue1 = ( 90 + 110 ) * 10; | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
108行: | 116行: | ||
int main(){ | int main(){ | ||
int nMacroValue; | int nMacroValue; | ||
− | int | + | int x = 20; |
− | int | + | int y = 30; |
− | nMacroValue = __MY_MACRO_ADD_( | + | int nMacroValue; |
+ | int nMacroValue1; | ||
+ | nMacroValue = __MY_MACRO_ADD_(x, y) * 10; | ||
nMacroValue1 = __MY_MACRO_ADD_(90, 110) * 10; | nMacroValue1 = __MY_MACRO_ADD_(90, 110) * 10; | ||
} | } | ||
118行: | 128行: | ||
int main(){ | int main(){ | ||
int nMacroValue; | int nMacroValue; | ||
− | int | + | int x = 20; |
− | int | + | int y = 30; |
− | nMacroValue = ( | + | int nMacroValue; |
− | nMacroValue1 = ( | + | int nMacroValue1; |
+ | nMacroValue = ( x + y + x + y ) * 10;//a = 20,b = 30,(20 + 30 + 20 + 30) * 10 → 1000 | ||
+ | nMacroValue1 = ( 90 + 110 + 90 + 110 ) * 10;// 4000 | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
132行: | 144行: | ||
int main(){ | int main(){ | ||
int nMacroValue; | int nMacroValue; | ||
− | int | + | int x = 20; |
− | int | + | int y = 30; |
− | nMacroValue = __MY_MACRO_MAX__( | + | int nMacroValue; |
+ | int nMacroValue1; | ||
+ | int nMacroValue2; | ||
+ | int nMacroValue3; | ||
+ | nMacroValue = __MY_MACRO_MAX__(x, y) * 10; | ||
nMacroValue1 = __MY_MACRO_MAX__(90, 110) * 10; | nMacroValue1 = __MY_MACRO_MAX__(90, 110) * 10; | ||
− | nMacroValue2 = __MY_MACRO_SWAP__( | + | nMacroValue2 = __MY_MACRO_SWAP__(x, y) * 10; |
nMacroValue3 = __MY_MACRO_SWAP__(90, 110) * 10; | nMacroValue3 = __MY_MACRO_SWAP__(90, 110) * 10; | ||
} | } | ||
144行: | 160行: | ||
int main(){ | int main(){ | ||
int nMacroValue; | int nMacroValue; | ||
− | int | + | int x = 20; |
− | int | + | int y = 30; |
− | nMacroValue = ( ( | + | int nMacroValue; |
+ | int nMacroValue1; | ||
+ | int nMacroValue2; | ||
+ | int nMacroValue3; | ||
+ | nMacroValue = ( (x) > (y) ? (x) : (y) ) * 10;//x = 20, y = 30, | ||
//( (20) > (30) ? (20) : (30) ) * 10 → 300 | //( (20) > (30) ? (20) : (30) ) * 10 → 300 | ||
− | nMacroValue1 = ( ( | + | nMacroValue1 = ( (90) > (110) ? (90) : (110) ) * 10;// |
− | + | //( (90) > (110) ? (90) : (110) ) * 10 → 1100 | |
− | nMacroValue2 = {int c; c = | + | nMacroValue2 = {int c; c = x; x = y; y = c;} * 10;//x = 20, y = 30 |
− | //{int c; c ← 20; | + | //{int c; c ← 20; x ← 30; y ← c(20);} * 10 |
− | nMacroValue3 = {int c; c = | + | // → {…} * 10 → 0(xとy)の値は入れ替わる。 |
− | + | nMacroValue3 = {int c; c = 90; 90 = 110; 110 = c;} * 10;//{int c; c ← 90; 90 ← 110; 110 ← c(90);} * 10 → 0 | |
//コンパイル エラー | //コンパイル エラー | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | + | といった具合に複雑な計算式を当て込むことで、最大値や値の入れ替えした値を返却するマクロとしての機能を持つ置換処理をプログラムソース全体にわたって処理してくれます。。ただしトークンの置き換えでMAXに一致すると処理が変わる可能性があるため、マクロ名が重複しないようにする必要があることと、引数付きの複雑なプログラムソースを組み込んだマクロ定義によって使い方を間違えるとエラーになるケースが生じることにも注意が必要になります。マクロの定義によっても、無意識のうちに構文エラーになるような使い方になってしまうような間違いも発生しやすいです。汎用性の高いマクロになっているか、よく確かめる必要があります。計算の優先度の入れ替わりや置き換え後の;や}の利用によって構文エラーになっていないか?意図した計算結果がいつでも得られるマクロになっているかを確実なものにする技術が必要です。 | |
+ | |||
+ | |||
+ | あまり、ややこしいマクロは組み込まない方が分かりやすいですが、使わざるを得ないプロジェクトがあれば、使ってプログラムのメンテナンス性を向上させることができます。自分ではあまりマクロを組み込まないという人でも、少なくとも他人が組んだマクロの展開結果が何を意図しているか読み解く力があれば、問題ないと思います。 | ||
==='''#undef'''=== | ==='''#undef'''=== | ||
+ | <nowiki>#</nowiki>defineディレクティブで定義したマクロ変数を解放するためのディレクティブです。#undefディレクティブの後ろに半角スペースを挿入し、続けて解放したいマクロ変数名を記述し、以下のような形式で記述します。 | ||
+ | |||
+ | |||
+ | '''<nowiki>#</nowiki>undef 解放するマクロ変数名''' | ||
+ | |||
+ | |||
+ | 具体的には以下のように記述します。 | ||
+ | <syntaxhighlight lang="cpp" line start="1"> | ||
+ | #define __MY_MACRO__ | ||
+ | #ifdef __MY_MACRO__ | ||
+ | #define __MY_MACRO1(a,b)__ ( 5000 + (a) + (b)) | ||
+ | #endif | ||
+ | |||
+ | #ifdef __MY_MACRO__ | ||
+ | #undef __MY_MACRO1__ | ||
+ | #undef __MY_MACRO__ | ||
+ | #endif | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | 上記のように引数付きマクロ変数でも、解放するときは引数の記述を省略できます。定義されていないマクロ変数を#undefディレクティブで解放する指示をしてもエラーにはなりません。もちろん、#ifdefディレクティブを使って、定義されているマクロ変数だけを解放するように組み込むこともできます。 | ||
+ | |||
+ | |||
+ | [[C PlusPlus#Cにもあった技術|C++]]へ戻る |