マクロ (C++をもう一度)
[最終更新] (2019/06/03 00:51:20)
最近の投稿
注目の記事

サンプルコード集

引数のないマクロ

#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;
}

デバッグ時にのみ有効なコード (関連: アサーション)

この続きが気になる方は
関連ページ
    サンプルコード メルセンヌ・ツイスタなど、C言語で記述されたライブラリをC++から利用するためには extern "C" を利用します。その際、組み込みマクロ __cplusplus を利用するとC言語からもC++からも利用できるヘッダファイルを作成できます。 sub.h #ifndef SUB_H_ #define SUB_H_ #ifdef __cplusplus extern "C"
    ポインタ関連 参照とポインタの違い ポインタと参照の決定的な違いの一つは、指す先を後から変更できるかどうかというところにあります。 #include <iostream> using namespace std; int main() { // 参照 int m = 1; int n = 2; int& intref = m; intref = n;