Categories: C言語

【C言語】プリプロセッサの種類と使い方

この記事では、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言語のプリプロセッサの種類と使い方を解説しました。

プリプロセッサを使うことでソースコードをコンパイルする前に前処理を施すことができました。

コンパイルされる際には既に前処理されたソースコードが渡されるので実行ファイルの速度に影響を与えません。

それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ

ゆうまる

独学でプログラミングを勉強しているおじさん。いろんな言語を勉強したが浅く広くなためあまり仕事につながらない。また忘れっぽいため自分のブログを備忘録としても使っている。産まれてこのかたずっとネコを飼ってる生粋のネコ派。最近お腹が出てきて筋トレに奮闘中!

Recent Posts

【Python】任意の秒数だけ処理を一時停止する方法【sleep()関数】

この記事では、Pythonで任意の秒数だ…

7か月 ago

【Python】Wordの文書の新規作成と読み書き

この記事では、Pythonを使ってWor…

7か月 ago

【Python】メタクラスって結局なんなの?

この記事では、Pythonのメタクラスに…

7か月 ago

【Unity】割合から数値に数値から割合に変換する

この記事では、割合から数値に変換する関数…

7か月 ago

【Python】抽象クラスを定義する方法

この記事では、Pythonで抽象クラスを…

7か月 ago