サンプルコード集
引数のないマクロ
#include <iostream>
using namespace std;
#define EPS (1e-7)
#define INF 1e9
int main() {
cout << EPS << endl;
cout << INF << endl;
return 0;
}
引数のあるマクロ
#include <iostream>
using namespace std;
#define REP(i,n) for(int i = 0; i < (int)n; ++i)
// #define REP(i, n) for(int i = 0; i < (int)n; ++i) // 引数括弧内の空白は問題ないですが
// #define REP (i,n) for(int i = 0; i < (int)n; ++i) // それ以外だと意図しない置換が行われます
#define rep(n) REP(i,n)
int main() {
REP(i,10) {
cout << i << endl;
}
rep(10) {
cout << i << endl;
}
return 0;
}
引数のあるマクロの注意点
閉じ括弧の後のセミコロンは置換後の文字列として扱われます。
#include <iostream>
using namespace std;
#define MyMacro(expr); expr; //「MyMacro(expr)」→「; expr;」
int main() {
MyMacro(cout << "macro" << endl);
//==> こうはならず:
// cout << "macro" << endl;
//==> こうなります:
// ; cout << "macro" << endl;
return 0;
}
括弧を付与しないことによる不具合
#include <iostream>
using namespace std;
#define MyMacro(expr) expr // 不適切
// #define MyMacro(expr) (expr) // 可能な限り多くの括弧で囲みましょう
int main() {
cout << MyMacro(1 + 1) * 2 << endl; //=> 3 (← 意図した 4 にはならない)
return 0;
}
複数行にわたるマクロ
バックスラッシュを使用するとマクロ内で改行できます。最後の行のバックスラッシュは不要です。
#include <iostream>
using namespace std;
#define MyMacro(expr) \
{ \
while(true) { \
(expr); \
} \
}
int main() {
MyMacro(cout << "infinite loop" << endl);
return 0;
}
コメント
プリプロセッサによるマクロの置換時にバックスラッシュ改行部分が一行にまとめられてしまうため、「// コメント」ではなく「/* コメント */」形式を使用する必要があります。
#include <iostream>
using namespace std;
#define MyMacro(expr) \
{ \
while(true) { /* コメント */ \
(expr); \
break; \
} \
}
int main() {
MyMacro(cout << "infinit" << endl);
return 0;
}
マクロの無効化
#include <iostream>
#include <cmath>
using namespace std;
#define PI (acos(-1))
int main() {
cout << PI << endl; //=> 3.14159
#undef PI
// cout << PI << endl; // ← マクロ定義がないためエラー
return 0;
}
デバッグ時にのみ有効なコード
#include <iostream>
using namespace std;
#ifdef NDEBUG
#define DEBUG(body) /* 空文化 */
#else
#define DEBUG(body) body
#endif
// 参考:
// #ifdef NDEBUG // これは
// #if defined(NDEBUG) // と同じ
// #ifndef NDEBUG // これは
// #if ! defined(NDEBUG) // と同じ
int main() {
DEBUG(cerr << "DEBUG" << endl);
return 0;
}
動的な typedef
#include <iostream>
#include <climits>
using namespace std;
#define UINT32_MAX 0xFFFFFFFF
#if UINT_MAX == UINT32_MAX
typedef unsigned int UInt32;
#elif ULONG_MAX == UINT32_MAX
typedef unsigned long UInt32;
#elif USHRT_MAX == UINT32_MAX
typedef unsigned short UInt32;
#elif UCHAR_MAX == UINT32_MAX
typedef unsigned char UInt32;
#else
#error 32ビットの符号なし型が定義できません
#endif
int main() {
cout << hex;
cout << UINT_MAX << endl; //=> ffffffff
cout << ULONG_MAX << endl; //=> ffffffff
cout << USHRT_MAX << endl; //=> ffff
cout << UCHAR_MAX << endl; //=> ff
return 0;
}
組み込みマクロ
#include <iostream>
using namespace std;
#define MY_MACRO __LINE__
int main() {
cout << __FILE__ << endl; //=> main.cpp
cout << __LINE__ << endl; //=> 9
cout << MY_MACRO << endl; //=> 10
cout << MY_MACRO << endl; //=> 11 (展開された位置の行が取得できる
cout << __DATE__ << endl; //=> Dec 21 2014 (コンパイル日付
cout << __TIME__ << endl; //=> 17:43:49 (コンパイル時刻
cout << __cplusplus << endl; // C++でのコンパイル時に定義される
return 0;
}
0
低レイヤーのプログラミングとOS開発が趣味。C言語を使っています。
記事の執筆者にステッカーを贈る
有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。
さらに詳しく →Feedbacks
ログインするとコメントを投稿できます。


