サイトマップ / C言語講座>出入り口>総目次>目次:流れの制御>マクロ処理
[三項演算子(2)]←このソース→[gotoとlabel]
/* マクロ処理について学びます。ソースプログラムがコンパイルされる前にプリプロセッサが働きます。マクロ処理とは、マクロ名で指定した文字列をプリプロセッサによって置き換えることをいいます。具体例を挙げます。
#define abs(a) ((a) < 0 ? - (a) : (a))
abs(a)の後ろに、スペースが一つ入っています。マクロ処理はつぎの形式で指定します。
#define マクロ名 パターン
上記の例では、マクロ名は abs(a)です。パターンは ((a) < 0 ? - (a) : (a)) です。マクロ名とパターンの間にはスペースかタブが必要です。
重要:マクロ名の中にスペースやタブを入れてはならない。
ソースプログラムの中にこの1行があると、以後、指定したマクロ名があるとパターンに置き換えます。このような手法をマクロ置換、または単に、マクロといいます。上記の例では、ソースプログラムの中にabs(a) があると、((a) < 0 ? - (a) : (a)) に書き換えます。これは、a の絶対値になります。
次の例は、x の2乗を求めるマクロ処理です。カッコが2重になっていることに注目してください。
#define square(x) ((x) * (x))
ソースプログラム中に、square(a + b); というコードがあると、プリプロセッサは、次にように書き替えます。
((a + b) * (a + b))
ところが、カッコが少ないと次のように変換されてしまい、期待通りの動作をしません。マクロ処理では、カッコの使い方に注意をはらう必要があります。
#define square(x) (x * x) (a + b * a + b)
重要:念には念を入れて、注意深くカッコを使用する。
マクロ処理の例を幾つかあげます。最後の例では、プリプロセッサはThis を削除します。
#define max(a, b)max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#define This
#define を使う記号定数について説明します。記号定数は伝統的に英大文字が使われてきました。0と1以外の数字をプログラムの中に、それが他の人が見ても直感的に理解できる場合を除いて、直接書き込むのは避けましょう。その数字がプログラムの中に複数回出てくると、数字を直す必要が出た時苦労します。特に、作った人と直す人が違うと大問題になります。そこで、数字を直接書かず、記号定数を使います。記号定数もマクロです。下記のように記述します。
#define YES 1 #define NO 0 #define BLACK 2 #define WHITE 3
記述する場所は、プログラムの前の方か、最初に置換が行われる直前が一般的です。下に示すのは、ヘッダーファイルの中で宣言されている記号定数です。ヘッダーファイルをインクルードすれば使えます。なお、それぞれの値はシステムによって違う可能性があります。
<math.h> #define PI 3.1415926535897932386 円周率 <stdlib.h> #define RAND_MAX 32767 rand( )で発生する乱数の最大値 <stddef.h> #define NULL (0L) <limits.h> #define CHAR_BIT 8 (char型は 8 ビット) #define CHAR_MAX UCHAR_MAX (char型の最大値は unsigned char型の最大値) #define CHAR_MIN 0 (char型の最小値 ) #define INT_MAX +32767 (int型の最大値) #define INT_MIN -32768 (int型の最小値) #define LONG_MAX +2147483647L (long型の最大値) #define LONG_MIN -2147483648L (long 型の最小値) #define SCHAR_MAX +127 (signed char型の最大値) #define SCHAR_MIN -127 (signed char型の最小値) #define SHRT_MAX +32767 (short型の最大値) #define SHRT_MIN -32768 (short型の最小値)
今日のソースプログラムは n の値を表示し、マクロでその2乗を求めます。 */
#include <stdio.h> /* 2乗を求めるマクロ処理 */ #define square(x) ((x) * (x)) void main(void); void main(void) { int n = 8; printf("n =%d\tn * n = %d\n", n, square(n)); } |
/* 重要:マクロで定義すると、形式上は関数と見分けがつきません。注意が必要です。 */
[三項演算子(2)]←このソース→[gotoとlabel]
/* (C) 2000- YFプロ. All Rights Reserved. */ 提供:C言語講座−それ自体コンパイルできる教材を使った講座です−