第18章 プリプロセッサ

「プリプロセッサ」とはコンパイル前にソースプログラムに対して行われる前処理のことです。
この章では、プリプロセッサとして、「#define」と「#include」を説明します。

1. #define

(1) 基本的な使い方

#define は 文字列1 を文字列2 で置き換える(これを「マクロ定義」と呼びます)ことができます。
つまり、ある文字列を別の文字列で置き換えたいときに用います。

【書き方】
#define 文字列1 文字列2  (文字列1 を記号定数とも呼ぶ)

// コンパイル時にソースプログラム中の NINZU がすべて 6 に置き換わる
#include <stdio.h>

#define NINZU 6    // 学生数

int main(void)
{
    int goukei = 0;    // 合計点
    double heikin;     // 平均点
    int ten[NINZU] = { 86, 67, 46, 96, 54, 72 }; // 点数
    
    for (int i = 0; i < NINZU; i++) {
        goukei += ten[i];
    }
    heikin = (double) goukei / NINZU;

    printf("学生数 = %d\n", NINZU);
    printf("合計 = %d\n", goukei);
    printf("平均 = %.1f\n", heikin);
    
    return 0;
}

【実行結果例】
学生数 = 6
合計 = 421
平均 = 70.2

(2) メリット

  • 単に定数の「6」を用いるよりも、「NINZU」とマクロ定義した方が意味がわかりやすくなる
  • プログラムの変更が生じ、学生数が「6」から他の数値になったときに、#define 定義を修正するだけで対応できる

(3) 使用上の注意

  • 記号定数は他の変数と区別するために大文字で記述するとよい。
  • 文字列2 の部分には、既にマクロ定義されている記号定数を用いることもできる。
    #define FALSE 0 
    #define TRUE !FALSE
    
  • 文字列2 の部分に、計算式を用いる場合には注意が必要である。
    #define CNT 100
    #define MAX CNT + 50
    
    data = MAX / 2; ==> data = 100 + 50 / 2; と解釈されてしまいます。
  • これは、( ) を用いて次のようにマクロ定義しましょう。
    #define CNT 100
    #define MAX (CNT + 50)
    
    data = MAX / 2; ==> data = (100 + 50) / 2; と正しく解釈されます。

このサイトでは引数を持つ関数型の #define については説明しません。

2. #include

(1) 基本的な使い方

#include は指定したヘッダを読み込み、この位置に挿入します。

【書き方】
#include <標準ヘッダ>
#include “自作のヘッダ”

#include <stdio.h>
#include "my.h"

int main(void)
{
	:

これを、図に表すと以下のようになります。

(2) 標準ヘッダとは

第5章第7章第8章で学習した標準ライブラリ関数は、コンパイラメーカがよく使う機能をオブジェクトライブラリとして提供してくれた関数群です。 この標準ライブラリ関数をプログラムで使用するには、必ずそれぞれの関数に対応する「標準ヘッダ」をインクルードしなければなりません。

このサイトでプログラムを記述する際には、必ずといってよいほどプログラムの先頭で #include <stdio.h> と記述しましたね。 これは、プログラム中で「print」や「scanf」などの「標準入出力関数」を使用していたからです。 この標準入出力関数を使用するためにインクルードしなければならないヘッダが「stdio.h」だったわけです。

この「stdio.h」には

などが記述されています。

標準のヘッダは標準のディレクトリ(「include」というディレクトリ名が一般的です)に格納されています。 試しにあなたの環境で「stdio.h」をエディタを用いて開いて確認してみてください。(書き換えないように注意してくださいね。)

(3) 自作のヘッダとは

関数のプロトタイプ宣言やマクロ定義などの情報は、小さなプログラムではそのままソースプログラムの先頭で宣言しますが、プログラムが大きくなってくると、これらの情報もかなりの量になってきます。 その場合、自作のヘッダ(拡張子は「.h」)を作成して、それらの情報をヘッダに記述し、ソースプログラムでそのヘッダをインクルードします。

この自作のヘッダには

を記述するのが一般的です。

また、ヘッダはソースファイルと同じ場所に保存するか、自作のヘッダ用のディレクトリを新たに作成し(この場合はコンパイル時にディレクトリの場所をオプション指定する必要があります)、そこに保存するのが一般的です。

これは、標準ディレクトリを特別扱いし、標準ヘッダの誤った変更や削除を防止するためです。

コメント