20章 プリプロセッサ

http://www.geocities.jp/ky_webid/c/020.html

コンパイルする前に行われる前処理のような物。

ソースフィルタのような物といえばしっくりくるかな。

とりあえずここでは三つのディレクティブが紹介されている。覚えておこう。

#include
#define
#undef

includeはヘッダファイルを読み込むのに使用する。

defineはマクロ変換するのに使用する。

undefはdefineで定義されたマクロを削除する。

といった感じだろうか。

問題1

次のプログラムは何をしているのでしょう?

#define DAY 365

int main(void){
    int day;
    
    printf( "日数を入力して下さい\n" );
    scanf( "%d", &day );
    
    if( day != 0 ) {
        printf( "%d\n", day / DAY );
    }

    return 0;
}

defineで定義されたDAYが展開され、day / 356が実行される。

見たままだね。

問題2

次のように「main.c」と「main.h」という2つのファイルを作って、これをコンパイル&実行させてみて下さい。

例のように試してみた。

main.hの方でプロトタイプ宣言されていれば、main.cの方でしなくても順序に関係なくmain関数で使えるというわけですね。

問題3

キーボードから整数を入力させて、それをそのまま出力するプログラムを作ります。500未満あるいは1000より大きい整数が入力されたときはエラーメッセージを表示させて下さい。出力処理はmain関数とは別の関数にして、その関数の関数プロトタイプはヘッダファイルに記述して下さい。また、できるだけマクロ置換を使うように作って下さい。

だんだん問題が複雑になってきました。誤読しないように慎重に読み進めながら実装していきます。

// main.h
#define MIN 500
#define MAX 1000

void output(int num);
// main.c
#include <stdio.h>
#include "main.h"

int main () {
    int num;
    
    scanf("%d",&num);
    
    if ( num < MIN || num > MAX ) {
        printf("error %d\n",num);
        return 0;
    }
    
    output(num);
    return 0;
}

void output (int num) {
    printf("%d\n",num);
}
$ main
500
500

$ main
1000
1000

$ main
1001
error 1001

$ main
499
error 499

うまくいってるようです。

答え合わせ

解答例の方ではエラーメッセージもdefineで定数かしていました。なるほどこういう使い方もありなんですね。