第37章 プリプロセッサ  


今回は、プリプロセッサ(preprocessor)について よく使うものだけ解説します。前処理(preprocessing)とは ソースファイルの一部を条件により、加工、読み飛ばし、 他のソースファイルの読み込みなどを行うことを言います。 これは、翻訳の前に行われるので前処理といわれます。 厳密にいうと、ちょっと違うようですが超初心者のうちは このように覚えておいて間違いはないでしょう。 何も難しいことはありません。すでにいくつかは暗黙のうちに 登場してきています。#includeとか#defineとかですね。

#define マクロ名 文字列

とすれば、マクロ名をさがして、「文字列」に置き換えます。 「#」の記号は行の一番最初に置かなくてはいけません。 しかし最近の処理系では行の最初でなくとも 文句を言わずに作業をしてくれるようです。 でも原則的には「#」は行の最初に書いてください。 また、#define以降に書かれていることは1行にまとめます。 1行にまとまらないときはその行の最後に、バックスラッシュ をつけます。これがない機種では「\」記号をつけます。


マクロ定義が1行で収まらないときは、バックスラッシュそれが ないものでは「\」を行の最後につけます。

きちんと表示されました。

それと、これもウスウス気づいていることと思いますが、 マクロ名が定義されていても" "の中は置き換えが起こりません。

最初のprintf中のPAIはそのまま表示されます。 次のprintf中のPAIは置き換えが起こります。

あたかも、PAIという変数を宣言なしに使っているような 錯覚に陥りませんか?

次に引数を持ったマクロについて解説します。 あたかも関数のように振る舞います。

#define KAKEZAN(x, y)   ((x) * (y)) 
のように使います。((x)*(y))のように必ずカッコをつけます。 カッコをつけないと間違いの元になります。 また当たり前ですがKAKEZANと(x,y)の間をあけてはいけません。

このような例の場合マクロにするのか、関数にしたらよいのか 難しいですね。書く人の好みで決めるのでしょうか。



実行結果は予想通りですね。

さて、これはある人から教えてもらったのですが、

#define KAKEZAN(x, y) (x * y)

としたらどうでしょうか。一見大丈夫そうに見えます。 上の例題のときもうまくいきます。しかし

int a = 2, b = 3, c = 4, d = 1, e; e = KAKEZAN(a + b, c + d); printf(" %d * %d = %d\n", a + b, c + d, e);

とするとどうでしょうか。一見うまくいきそうに見えますが 実行結果は
「5 * 5 = 15」
となり、おかしなことになります。なぜこうなるかというと マクロは単なる置き換えだからです。 上の例の場合
e = KAKEZAN(a + b, c + d);
は、マクロで置き換えると
e = a + b * c + d;
となってしまいます。マクロであんまり複雑なことをしないのが無難です。

さて、次は#ifdef #endifです。 #ifdef XXXとあれば「もしXXXが定義されているならば #endifまでを翻訳しなさい」とでも読めばよいでしょう。 厳密には違うのかもしれませんがこのように覚えておいて 特に支障はありません。どんな時使うのかというと、たとえば いくつかのバージョンをもつプログラムを作るときバージョンごとに少しずつ プログラムが異なる場合などです。

このようにプログラムを書いておけば、後で#define TESTの行を コメントにしてしまえば「これは、テストバージョンです」 を表示しなくすることができます。

同じ行で他の条件も定義されているかどうかを チェックするには#if definedを使います。

#if defined(TEST1 && TEST2)

などのように使います。この場合「TEST1とTEST2がともに定義されて いれば」と読めばよいですね。このほかに#ifndefというのもあります。 「もしXXXが定義されていなければ」と読めばよいでしょう。

次に毎度おなじみの#includeです。これは、ファイルの取り込みですね。

#include "filename" #include <filename>

の2つの書き方があります。最初の書き方はまず、filenameという名前の ファイルをこれが記述されているファイルのあるディレクトリを探します。 次にシステムのディレクトリを探します。従って、自分でヘッダーファイルを 作ったときなどに使用します。下の例は、システムのディレクトリのみを 探します。ですから、全部上の書き方でも間違いではありません。 でも、コンパイルに少しだけ時間がよけいにかかるでしょう。 ところでいつも出てくる#include <stdio.h>の

stdio.hって何て読むんだ?

という疑問がわきませんか。(久しぶりです) 筆者は、stdio.hはヘッダー・ファイルなので 「スタンダード・アイ・オー・ヘッダー」と読んでおりました。 ところが、あることでマイクロソフトのサポートに電話を したところサポートの方は、「***エイチ」と言っておりました。 windows.hなら「ウィンドウズ・エイチ」です。 マイクロ・ソフトのサポートの方は女性で 電話の応対も丁寧で好感が持てます。 まー、こんなことはどうでもいいことですね。


[Index][総合Index] [Previous Chapter] [Next Chapter]

Update Dec/02/1996 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。