C言語ホーム > その他、C言語の詳細について > マクロのサンプル前ページ次ページ
サイト内検索:

C言語のマクロのサンプル

C言語のマクロはとても便利ですが、落とし穴も多くあります。このページはマクロのサンプル集です。



マクロのサンプル

マクロのサンプル集です。詳細はソースのコメントをご参照ください。


/**
 * @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言語ホーム > その他、C言語の詳細について > マクロのサンプル前ページ次ページ
© 2009-2013 C言語サイト管理人