LoginSignup
3
3

More than 1 year has passed since last update.

C言語マクロサンプル

Posted at
/**
 * @file macro.h
 * @brief マクロのサンプル集.
 */
#ifndef MACRO_H
#define MACRO_H

/*
        SWAP - 変数入替 -
*/
/**
 * 2つの変数の内容を入れ替える.
 * 変数の型は引数typeで指定可能.
 * @param [in] type     入れ替え対象の変数の型
 * @param [in] a        入れ替え対象の変数1
 * @param [in] b        入れ替え対象の変数2
 * @retval なし
 * @attention 引数は複数回評価される.
 */
#define SWAP(type, a, b) \
        do {type tmp = a; a = b; b = tmp;} while (0)


/*
        XOR_SWAP - 変数入替(XOR交換) -
*/
/**
 * 2つの変数の内容をXOR交換アルゴリズムで入れ替える.
 * @param [in] a        入れ替え対象の変数1
 * @param [in] b        入れ替え対象の変数2
 * @retval なし.
 * @attention 交換対象の変数は整数(char含む)のみ可.
 * @attention 同じ変数を指定すると結果は0となる.
 * @attention 一時変数を用いて交換する方法よりも,
 * @attention 高速に動作する可能性があるため,
 * @attention 処理速度に問題がある際には検討の価値がある.
 */
#define XOR_SWAP(a, b) \
        do {a ^= b; b ^= a; a ^= b;} while (0)


/*
        MAX - 最大値取得 -
*/
/**
 * 指定された2つの引数のうち,最大のものを返す.
 * @param [in] a        最大値を選ぶ対象の変数1
 * @param [in] b        最大値を選ぶ対象の変数2
 * @retval 最大値
 * @attention 引数は複数回評価される.
 */
#define MAX(a, b) ((a) > (b) ? (a) : (b))


/*
        MAX3 - 最大値取得 -
*/
/**
 * 指定された3つの引数のうち,最大のものを返す.
 * @param [in] a        最大値を選ぶ対象の変数1
 * @param [in] b        最大値を選ぶ対象の変数2
 * @param [in] c        最大値を選ぶ対象の変数3
 * @retval 最大値
 * @attention 引数は複数回評価される.
 */
#define MAX3(a, b, c) ((a) > (MAX(b, c)) ? (a) : (MAX(b, c)))


/*
        MIN - 最小値取得 -
*/
/**
 * 指定された2つの引数のうち,最小のものを返す.
 * @param [in] a        最小値を選ぶ対象の変数1
 * @param [in] b        最小値を選ぶ対象の変数2
 * @retval 最小値
 * @attention 引数は複数回評価される.
 */
#define MIN(a, b) ((a) < (b) ? (a) : (b))


/*
        MIN3 - 最小値取得 -
*/
/**
 * 指定された3つの引数のうち,最小のものを返す.
 * @param [in] a        最小値を選ぶ対象の変数1
 * @param [in] b        最小値を選ぶ対象の変数2
 * @param [in] c        最小値を選ぶ対象の変数3
 * @retval 最小値
 * @attention 引数は複数回評価される.
 */
#define MIN3(a, b, c) ((a) < (MIN(b, c)) ? (a) : (MIN(b, c)))


/*
        IN4 - 集合要素判定 -
*/
/**
 * 指定の集合に属する要素かを判定する.
 * 判定対象xがa〜dのいずれかなら真を返却.
 * @param [in] x        判定対象
 * @param [in] a        集合要素1
 * @param [in] b        集合要素2
 * @param [in] c        集合要素3
 * @param [in] d        集合要素4
 * @retval 要素なら真.要素でなければ偽
 * @attention 引数は複数回評価される.
 */
#define IN4(x, a, b, c, d) ((x) == a || (x) == b || (x) == c || (x) == d)


/*
        INSIDE - 範囲内判定 -
*/
/**
 * 指定の範囲内かを判定する.
 * 判定対象xがa〜bの範囲内なら真を返却.
 * @param [in] x        判定対象
 * @param [in] a        範囲(小)
 * @param [in] b        範囲(大)
 * @retval 範囲内なら真.範囲外なら偽
 * @attention 範囲の引数はa<=bであること.
 * @attention 引数は複数回評価される.
 */
#define INSIDE(x, a, b) ((x) >= a && (x) <= b)


/*
        INCREMENT - インクリメント -
*/
/**
 * 引数に1を足す.その際,指定の最大値になったら0に戻す.
 * @param [in] a        インクリメント対象の変数
 * @param [in] max      最大値
 * @retval 1足された数
 * @attention 返却値はmaxにはならない.
 * @attention 1足した後の値がmaxなら0が返却される.
 */
#define INCREMENT(a, max) ((a) = ((a) + 1) % (max))


/*
        DECREMENT - デクリメント -
*/
/**
 * 引数から1を引く.0以下が渡された場合は,指定の最大値を返す.
 * @param [in] a        デクリメント対象の変数
 * @param [in] max      最大値
 * @retval 1引かれた数
 * @attention 返却値はmax未満.
 * @attention 1引いた後の値が負ならmax-1を返却.
 */
#define DECREMENT(a, max)       \
        (((a) = (a) - 1) < 0 ? ((a) = (max) - 1) : (a))


/*
        PRINT_VARIABLE - 変数内容出力 -
*/
/**
 * 変数名とその内容を指定のフォーマットで出力する.
 * @param [in] a        出力対象の変数
 * @param [in] f        フォーマット文字列
 * @retval 出力した文字数。エラー発生の場合は負数
 */
#define PRINT_VARIABLE(a, f) printf(#a " : " f "\n", a)


/*
        ELEMENT_NUM - 配列要素数取得 -
*/
/**
 * 配列の要素数を取得する.
 * @param [in] array    配列名
 * @retval 配列の要素数
 * @attention 引数にポインタは指定不可.
 */
#define ELEMENT_NUM(array) (sizeof(array) / sizeof((array)[0]))


/*
        MEMBER_SIZE - 構造体メンバサイズ取得 -
*/
/**
 * 指定された構造体のメンバのサイズを返す.
 * @param [in] type             構造体
 * @param [in] member   構造体のメンバ
 * @retval 指定された構造体のメンバのサイズ
 */
#define MEMBER_SIZE(type, member) (sizeof(((type*)0)->member))


/*
        BEEP - 警告音 -
*/
/**
 * 警告音を鳴らす.
 * @param なし
 * @retval 出力文字数.失敗の場合EOF
 */
#define BEEP() (fputc('\a', stderr))


/*
        CALC_CLOCK - 処理時間表示 -
*/
/**
 * 処理にかかったプロセッサ時間を出力する.
 * 引数にはソースコードとループ回数を指定する.
 * 使用例:CALC_CLOCK(a = sin(a), 1000000UL);
 * @param [in] code     ソースコード
 * @param [in] n        ループ回数
 * @retval なし
 */
#define CALC_CLOCK(code, n) do {        \
        int i;                                                  \
        clock_t t = clock();                    \
        for (i=0;i<(n);i++) { code; }   \
        printf("%d\n", clock() - t);    \
} while (0)


/**
 * 静的アサートで使用するテンポラリのマクロ1.
 */
#define STATIC_ASSERT_JOIN(x, y) STATIC_ASSERT_JOIN_AGAIN(x, y)


/**
 * 静的アサートで使用するテンポラリのマクロ2.
 */
#define STATIC_ASSERT_JOIN_AGAIN(x, y) x ## y


/*
        STATIC_ASSERT - 静的アサート1 -
*/
/**
 * 与えられた定数式が偽ならば,コンパイルエラーを発生させる.
 * 与えられた式が偽ならば,配列を要素数が負でtypedef,
 * コンパイルエラーを発生させることにより静的アサートを実現する.
 * 識別子に行数を加えているのは,複数のtypedefを可能にするため.
 * @param [in] e        判定対象の定数式
 * @retval なし
 */
#define STATIC_ASSERT(e) \
        typedef char STATIC_ASSERT_JOIN(ASSERTION_AT_LINE_, __LINE__) [(e) ? 1 : -1]


/*
        STATIC_ASSERT_2 - 静的アサート2 -
*/
/**
 * 与えられた定数式が偽ならば,コンパイルエラーを発生させる.
 * 関数のextern宣言を利用しての静的アサート.
 * @param [in] e        判定対象の定数式.
 * @retval なし.
 */
#define STATIC_ASSERT_2(e) \
        extern void STATIC_ASSERT_DUMMY_FUNCTION(int ASSERTION_FAILED[(e) ? 1 : -1])


/*
        STATIC_ASSERT_3 - 静的アサート3 -
*/
/**
 * 与えられた定数式が偽ならば,コンパイルエラーを発生させる.
 * enumを利用しての静的アサート.
 * @param [in] e        判定対象の定数式.
 * @retval なし.
 */
#define STATIC_ASSERT_3(e) \
        enum { STATIC_ASSERT_JOIN(ASSERTION_AT_LINE_,__LINE__) \
                = sizeof(struct { char STATIC_ASSERT_JOIN(ASSERTION_AT_LINE_,__LINE__) [(e) ? 1 : -1]; }) }


/*
        UNUSED_PARAMETER - 未使用引数の警告回避 -
*/
/**
 * 未使用の仮引数に対するワーニングを回避する.
 * @param [in] p        未使用の仮引数.
 * @retval なし.
 */
#define UNUSED_PARAMETER(p) ((void)(p))


/*
 *      ALIGN_64 - 64アライメント -
 */
/**
 * 指定された値を64毎にアライメントして返す.
 * @param [in] n        アライメント対象の数.
 * @retval      アライメントされた値.
 * @attention   63を加え、63のビット反転値で論理積をとることによりアライメントする.
 *                              この方式はアライメントの単位が2の累乗数であれば使用可能.
 *                              例えば32単位でアライメントするなら31を加え、31のビット反転値で論理積をとる.
 */
#define ALIGN_64(n) (((n) + 63U) & ~63U)


/*
 *      ALIGN_N - 汎用アライメント -
 */
/**
 * 指定された値をアライメントして返す.
 * @param [in] n        アライメント対象の数.
 * @param [in] a        アライメント単位.
 * @retval      アライメントされた値.
 * @attention   アライメントの単位が2の累乗数でない場合に使用する.
 */
#define ALIGN_N(n, a) (((n) % (a)) ? ((n) + ((a) - (n) % (a))) : (n))


#endif /* MACRO_H */

[C言語マクロサンプル][http://www.c-lang.org/detail/macro_sample.html]

3
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3