この記事では、C言語のプリプロセッサについて解説します。
プログラム言語において プリプロセッサとは、ソースコードがコンパイラなどに渡される前に前処理を施すプログラムのことです。
C言語では以下のようなプリプロセッサが用意されています。
- インクルード(#include)
- デファイン(#define, #undef)
- 条件コンパイル(#ifdef, #else, #elif, #endif, #ifndef)
それでは、プリプロセッサについて見ていきましょう!
インクルード
インクルードとは、ファイルを読み込むための機能です。
#includeキーワードの後ろに<ファイル名>でファイルを指定することで標準ライブラリ(言語によってあらかじめ用意されているファイル)を読み込むことできます。
#include <ファイル名>
自作ファイルを読み込みたい場合は、"ファイル名"でファイルを指定します。
#include "ファイル名"
例えば、いつも使っているprintf()関数は、stdio.hから読み込んでいました。なので、ソースコードの#include <stdio.h>をコメントアウトして実行してみてください。
// #include <stdio.h> int main() { printf("出力\n"); }
インクルードをコメントアウトした時にコンパイルするとエラーが発生します。
デファイン
ディファインとは、定数や式に名前を付ける機能です。マクロとも呼ばれます。定数や式に名前を付けることでコンパイラに渡される前にその名前が指定した定数や式に置換されます。
#defineキーワードの後ろに名前を指定し、続けて定数や式を記述します。
#define 名前 定数や式
例えば、以下のように#define NUM 3と定義することで、それ以降に記述されている NUMが 3に置換された状態でコンパイラに渡されます。
#include <stdio.h> #define NUM 3 int main() { printf("%d\n", NUM); }
実行結果
3
関数形式マクロ
関数なんかも定義することができます。これは関数マクロと呼ばれたりします。
#define 関数名(引数) (処理)
以下のコードでは、引数を 2つ取る ADDという名前の関数マクロを定義しています。
#include <stdio.h> #define ADD(a, b) (a + b) int main() { int a = 1, b = 2; printf("%d\n", ADD(a, b)); }
実行結果
3
複数の文を含むマクロ
複数の文を含む関数マクロは、do-while文を使って以下のように定義します。
#define 関数名(引数) do {処理1; 処理2; ...; } while(0)
以下のコードでは、受け取った値の和を計算し、その結果を出力してくれる複数文のマクロを定義しました。
#include <stdio.h> #define ADD_PRINT(a, b) do {int r = a + b; printf("%d\n", r);} while(0) int main() { ADD_PRINT(1, 2); }
実行結果
3
マクロの削除
ちなみに、#undefを使うことで定義したマクロを削除できます。
#include <stdio.h> #define NUM 3 #undef NUM int main() { printf("%d\n", NUM); }
上記コードを実行すると「NUMなんて宣言されていないよ」というエラーが発生します。#undefによって NUMを削除したのでこのようなエラーが発生しました。
条件コンパイル
条件コンパイルとは、指定したディファイン(マクロ)が定義されているかどうかで分岐し、コンパイルするコードを変更することができます。
#include <stdio.h> int main() { #ifdef DEBUG printf("デバッグ\n"); #elif TEST printf("テスト"); #else printf("本番\n"); #endif }
実行結果
本番
コンパイルする際に -Dオプションを渡すことでマクロを定義することができる。それを使うことでコンパイルするソースコードをコンパイル時に変更することができる。
ターミナル
% gcc main.c -o main -D DEBUG % ./main デバッグ
#ifndefを使うことで指定したマクロが定義されていない場合に分岐させることができる。
#include <stdio.h> int main() { #ifndef DEBUG printf("デバッグ\n"); #else printf("本番\n"); #endif }
実行結果
% gcc main.c -o main -D DEBUG % ./main 本番
ソースコードを書き換えることなくコンパイルするコードを変更できるため便利です。
まとめ
この記事では、C言語のプリプロセッサの種類と使い方を解説しました。
プリプロセッサを使うことでソースコードをコンパイルする前に前処理を施すことができました。
コンパイルされる際には既に前処理されたソースコードが渡されるので実行ファイルの速度に影響を与えません。
それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ


