C言語ホーム > define前ページ次ページ
サイト内検索:

C言語のdefineについて

C言語のdefineについて、主なdefineの使い方、記号定数のdefine、関数マクロ、条件付き取り込みについて解説しています。

主なdefineの使い方

defineはC言語でのプリプロッセッサへの指示のひとつです。プリプロッセッサとは、コンパイルの前に前処理を行うプログラムのことです。下記の構文で記述すると、コンパイル時に前処理として、文字列1を文字列2に変換します。このような変換をマクロ置換と呼びます。


#define 文字列1 文字列2

C言語でのdefineの使い方でよく使われるものは、次の3つです。

これらを順に説明します。



記号定数の定義

ソース上に、意味のある定数を10や25など直接の数値、いわゆるマジック・ナンバーとして書いてしまうのはよいことではありません。後でプログラムを読む人がこの数値の意味を理解できませんし、数値が変更になった場合、ソースのいたるところを修正しなければなりません。

これを避けるために、defineをよく使用します。例えば、下記のように上限値と下限値を記号定数として定義し、使用すれば、ソースを読む時にその意味がわかりますし、上限値、下限値が変更になった場合、defineしたところだけ変えれば、変更が全てのソースに反映されます。


#define LOWER 12
#define UPPER 348

関数マクロ

defineによるマクロ置換は、引数付きにすることができます。これは関数マクロと呼ばれています。一見すると関数を呼び出しているように見えます。以下の書式で定義します。


#define マクロ名(引数) 処理

実際の例を見てみましょう。次のマクロは、2つの引数を取り小さい方を返します。


#define MIN(a, b) ((a) < (b) ? (a) : (b))

ソース中にMIN()が現れると、プリプロセッサが自動的に変換します。変換前と変換後の例を示します。

<defineによる関数マクロ、変換前の例>

x = MIN(n1, n2);
<defineによる関数マクロ、変換後の例>

x = ((n1) < (n2) ? (n1) : (n2));

一般的に、関数マクロは、関数呼び出しのオーバーヘッドを避けるために使用します。

関数マクロを使用する際には、注意が必要です。例えば、上記のMIN()で引数にn1++, n2++を渡すと小さい方の数が2回インクリメントされてしまいます。

また、次の例のように括弧をつけないと、意図したとおりに動かないことになります。


#define CALC_TRIANGLE_AREA(b, a) b*a/2

/* 中略 */

x = CALC_TRIANGLE_AREA(base+100, altitude-50);

/*

展開結果が、x = base+100*altitude-50/2;
となり、意図した結果とならない。

*/

条件付き取り込み

ヘッダ・ファイルの二重読み込みを防ぐために、ヘッダ・ファイル内に読み込み条件をつける場合があります。この時によくdefineが使われます。

例えばsample.hというヘッダ・ファイルを次のような内容にすると二重読み込みを防げます。


#ifndef SAMPLE
#define SAMPLE

/* sample.hの内容をここに書く */

#endif

#ifndefは「もしdefineされていなければ」の意味です。このように記述しておけば、最初にsample.hを取り込んだ時にSAMPLEがdefineされ、次にsample.hを取り込む時は既にSAMPLEがdefineされているので#endifまで読み込みがスキップされ、二重読み込みが回避されます。これで複数のファイルでsample.hをインクルードしても実際に読み込まれるのは1回だけとなり、たいへん便利です。

C言語ホーム > define前ページ次ページ
© 2009 C言語サイト管理人