プリプロセッサとは、Preprocessor(前処理系)つまり、C言語ではコンパイルの前に行う処理の事で、ここで処理させる命令をプリプロセッサ命令またはプリプロセッサディレクティブといいます。
プリプロセッサ命令は次のものがあります。
ファイルの読込みは次の命令を使用します。
「#include」ディレクティブの書式は次の通りです。
Cコンパイラに用意されている標準関数のとき
#include <ファイル名>
自作関数のとき
#include "ファイル名"
・サンプルソース1(sample1301.c)
#include <stdio.h> /* printf関数の定義ファイルを読込み */ #include "sample1301.h" /* 構造体Bookの定義ファイルを読込み */ int main() { struct Book book = {"プログラミング言語C", 2800}; printf("名前:%s\t価格:%d円\n", book.name, book.price); return 0; }
・サンプルソース2(sample1301.h)
struct Book { char name[30]; /* 名前 */ int price; /* 価格 */ };
・実行結果
C:\dev\c>sample1301 [Enter]
名前:プログラミング言語C 価格:2800円
定数やマクロを定義するときは次の命令を使用します。
「#define」ディレクティブの書式は次の通りです。
定数に名前を付けるとき
#define 定数名 定数
マクロを定義するとき
#define マクロ名(引数) 処理
マクロの定義で処理が複数行になる場合
#define マクロ名(引数) 処理1 \ 処理2
・サンプルソース(sample1302.c)
#include <stdio.h> #define CNT 10 /* 定数CNTを定義 */ #define PRINT(count) printf("%d\n", count) /* マクロPRINT(count)を定義 */ int main() { PRINT(CNT); return 0; }
・実行結果
C:\dev\c>sample1302 [Enter]
10
「#define」で定義した定数やマクロを無効にします。これにより同じ定数名やマクロ名で異なる値や処理を再定義する事が出来ます。
#undef 定数名またはマクロ名
マクロを使用するにあたって、特に算術の優先順位などに関して注意する必要があります。
次に示す例のようにマクロはプリプロセッサ処理で、単に処理の置き換えを行っているに過ぎないということを覚えておいてください。
・間違い例
#include <stdio.h> #define ADD(num1, num2) num1+num2 /* 2つの引数を足し算するマクロ */ int main() { printf("ADD(1, 2)*10=%d\n", ADD(1, 2)*10); /* 加算した数を10倍する(つもり) */ return 0; }
・実行結果
C:\dev\c>sample1303 [Enter] ADD(1, 2)*10=21 ← 「3*10=30」ではなく「1+2*10=21」となる。 つまりマクロは処理の置き換えに過ぎない!!
・修正例(sample1303.c)
#include <stdio.h> #define ADD(num1, num2) (num1+num2) /* 2つの引数を足し算するマクロ計算の優先順位を考慮し”()”(括弧)で囲む */ int main() { printf("ADD(1, 2)*10=%d\n", ADD(1, 2)*10); /* 加算した数を10倍する */ return 0; }
・実行結果
C:\dev\c>sample1303 [Enter] ADD(1, 2)*10=30 ← 「(1+2)*10=30」となる。
次のディレクティブを使用することで、コンパイルする対象を制御することができます。
#if 条件 ソースコード; #endif
#if 条件 ソースコード1; #else ソースコード2; #endif
#if 条件1 ソースコード1; #elif 条件2 ソースコード2; #else ソースコード3; #endif
#ifdef(#ifndef) 定数またはマクロ ソースコード; #endif
#ifdef(#ifndef) 定数またはマクロ ソースコード1; #else ソースコード2; #endif
#ifdef(#ifndef) 定数1またはマクロ1 ソースコード1; #elif 定数2またはマクロ2 ソースコード2; #else ソースコード3; #endif