目次
低レイヤーのプログラミングとOS開発が趣味。C言語を使っています。
工作HardwareHubからのお知らせ
サンプルコード集
引数のないマクロ
#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
記事の執筆者にステッカーを贈る
有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。
さらに詳しく →Feedbacks
ログインするとコメントを投稿できます。
関連記事
- ダウンキャスト (C++をもう一度)実行時型情報 RTTI #include <iostream> #include <typeinfo> using namespace std; class MyClass { public: virtual ~MyClass() {} // typeid で正しい RTTI // (RunTime Type Information; 実行時型情報) ...
- 競技プログラミングの基本処理チートシート (C++)限られた時間の中で問題を解くために必要となる、競技プログラミングにおける基本的な処理のチートシートです。競プロにおけるメジャー言語 C++ を利用します。その際 C++11 の機能は利用せず C++03 の機能の範囲内で記述します。 頻度高く定期的に開催されるコンテスト AtCoder Codeforces main.cpp #include <iostream>
- 構造体と列挙体 (C++をもう一度)構造体 #include <iostream> using namespace std; struct MyStruct { char charval; int intval; }; void Show(MyStruct* obj) { cout << obj->intval << endl; } int main() { ...
- Valgrind による C/C++ メモリリーク検出JVM メモリリークでは JDK の jstat や jmap で原因を調査できます。C/C++ では valgrind の Memcheck ツールが利用できます。valgrind には複数のツールが含まれており既定のツールが Memcheck です。他のツールを利用する場合は --tool オプションで指定します。 [簡単な利用例](h
- クラスの基本/初期化 (C++をもう一度)構造体のように初期化する (非推奨) #include <iostream> using namespace std; const int MAX_STR = 16; class MyClass { public: int m_integer; char m_str[MAX_STR + 1]; void Show(); }; void MyClass::Show...