C言語には、**「#define(ディファイン)」という「コンパイルする前に文字を置き換える命令」があります。
今回は、この#defineの基本的な使い方を解説します。
#defineとは
#(シャープ)で始まる命令は、プリプロセッサ命令と呼ばれます。
これは、コンパイルの前に実行される特別な命令で、ソースコードをコンパイルしやすい形に“準備”するためのものです。
その中のひとつである #define は、「特定の文字を別の文字列に置き換える」命令です。
#defineの構文は次の通りです。
#define マクロ名 置換する文字列または数値プログラムで使用する例は次の通りです。
#include <stdio.h>
#define PI 3.141592
int main(void)
{
printf("円周率は %f です。\n", PI);
return 0;
}printf 関数の PI の箇所は、実際には、コンパイルのときに次のように変換されます。
printf("円周率は %f です。\n", 3.141592);これだと、直接数値を記述して変わらないように感じますが、PI を複数個所で使用した場合、値の修正が必要になった場合、#defineの値を直すだけ済みます。
マクロ名の付け方
C言語では、定数の名前(マクロ名)は、大文字で書くのが一般的です。
ひと目見て、定数なのか、変数なのかがわかるためです。
また、次のように、複数の単語をつなぐときは、アンダースコア( _ )区切ります。
#define TAX_RATE 0.1
#define MAX_SPEED 120
#define BUFFER_SIZE 256マクロ関数とは
#define は「定数」だけでなく、「式」も登録できます。
そのときに、まるで関数のように使える形をマクロ関数といいます。
わかりにくいので、次に例を示します。
#define SQUARE(x) ((x) * (x))SQUARE(x) の(x) の部分は、関数でいう引数のようなものです。SQUARE(5)のように使うと、x が 5 に置き換えられます。
つまり、関数に見えますが、実際には、文字の置き換えをしているだけです。
このマクロ関数を使用するときは、次のようになります。
printf("%d\n", SQUARE(5)); // 25
printf("%d\n", SQUARE(2+3)); // 25これは内部では次のように置き換えられます。
SQUARE(5) → ((5) * (5))
SQUARE(2+3) → ((2+3) * (2+3))マクロ関数の注意点
マクロはただの文字の置き換えなので、カッコを忘れると変な結果になります。
悪い例:
#define SQUARE(x) x * x
printf("%d\n", SQUARE(2+3)); // 2+3*2+3 = 11 (本当は25にしたい)このように、本当なら、(2+3) * (2+3)としたいのに、2+3*2+3 となってしまいます。
良い例:
#define SQUARE(x) ((x) * (x))このように、マクロを書くときは、引数には (x)、全体も ((x) * (x))のように必ずカッコで囲むようにしましょう。
まとめ
#defineは「コンパイル前に文字を置き換える命令」- 定数をまとめるのに便利(例:
#define TAX 0.1) - 関数のように書ける「マクロ関数」もある(例:
#define SQUARE(x) ((x)*(x))) - カッコの付け忘れで思わぬ動作になることがある
- 複雑な処理は、マクロよりも普通の関数を使うほうが安全