質問: このサイトでダウンロードできる「libjpeg」のソースコードを見て、 > > cjpegとdjpeg - JPEGと、他の一般的な画像フォーマットとの変換を行う。 > > > と記述されていたので、`cjpeg.c`のソースを見ました。 すると、1~22行あたりまでは利用の規約などが記載されており、24行目あたりからコードが書かれていると思います。 ``` #include "cdjpeg.h" /* cjpeg / djpegアプリケーションの共通デッキ */ #include "jversion.h" /* for version message */ #ifdef USE_CCOMMAND /* Macintosh用のコマンドラインリーダー */ # ifdef __MWERKS__ # include /* Metrowerksはこれを必要とします */ # include /* ... この */ # endif # ifdef THINK_C # include /* ここでそれを宣言してください */ # endif #endif ``` > > 質問 > > 1. `include "cdjpeg.h"` これは、`cdjpeg.h`のファイルを読み込んでという意味ですよね? > > 2. `#ifdef USE_CCOMMAND` は使い方を調べたんですが、#ifdef <識別子名> <処理> となっていて、<識別子名>が定義済みなら<処理>を実行するというコードですよね? > > `USE_CCOMMAND` は、読み込んだファイルで定義されている場合も実行するんですか? > > 3. `#include "cdjpeg.h"`先の`cdjpeg.h`で`cdjpeg.h`と定義されているんですが、`#define`って、`#define A B`という記述でコードのAをすべてBと置き換えて実行しなさいという意味ですよね?今回の場合、Bにあたる部分がないのですが、どういう解釈をすればよいですか? > > >
回答: 質問への回答は以下になるでしょうか。 1. はい。`#include "cdjpeg.h"は、ファイル`cdjpeg.h`を読み込む、の意味です。 2. はい。マクロ変数(識別子)`USE_CCOMMAND`を定義しています。 なお、マクロ変数はそれが参照される時点で定義されている必要があるので、読み込んだファイルで定義されている場合、参照前に読み込むよう記述する必要があります。 例 ``` #include "macro.h" /* この中で #define A と記述されている */ #ifdef A /* マクロ変数 A を参照するのは macro.h をインクルードした後である必要がある */ (処理) #endif ``` 3. `#define A`と記述した場合、`B`は「空」を指定したものと考えるとよいと思います。 例 ``` #define A /* マクロ変数Aを空で定義 */ printf(A "Hello, World\n"); /* printf("Hello, World\n"); と同じ */ #define STR "Hey, " /* マクロ変数STRを"Hey, "で定義 */ printf(STR "Hello, World\n"); /* printf("Hey, Hello, World\n"); と同じ */ ``` 追記 == 内容が空で定義するマクロ変数を使う場合ですが、大きく分けて2種類あります。 1つは、内容は不要で定義の有無だけが必要な場合です。質問の例にもありますが、`#ifdef USE_CCOMMAND`によるプリプロセスの分岐がそれにあたります。 もう一つは、`#ifdef`による分岐との組み合わせで、ログ出力等の実行文を生成しないようにする場合です。例えば、次のようなソースコードを書いた場合、マクロ変数`TRACE`を定義しないと、`LOG`部分が「空」に置換されて`func`関数内の`LOG`部分は何も実行文がなくなります。 ``` 例 #ifdef TRACE #define LOG printf("TRACE: %s:%d\n", __FILE__, __LINE__) #else #define LOG #endif void func() { LOG; /* 処理 */ LOG; } このコードの前に`#define TRACE`がある場合に生成されるfunc関数の内容 void func() { printf("TRACE: %s:%d\n", __FILE__, __LINE__); /* 処理 */ printf("TRACE: %s:%d\n", __FILE__, __LINE__); } マクロ変数 TRACE が定義されていない場合に生成されるfunc関数の内容 void func() { /* 処理 */ } ```