52章 プリプロセッサディレクティブ

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

前にもプリプロセッサの話はありましたが、今回はさらに詳しくディレクティブについての説明があります

ざーっと読んだところで練習問題に入りましょう。

問題1

#ifをソースをコメントアウトする目的で使えます。やってみてください。

さっそく試してみます。

int main () {
        
    puts("A");
    
#if 0
    コメントです
#endif
    
    puts("B");

    return 0;
}

ちゃんとコンパイルが通りました。#if〜#endifの部分が無視されてるということがわかります。

問題2

あるマクロが定義されていたら#undefで無効化し、定義されていなければ定義するような、前処理を書いてみて下さい。

これは簡単にできると思います。

#ifdef FOO
#    undef FOO
#else
#    define FOO 10
#endif

int main () {
    printf("%d",FOO);
    return 0;
}
$ main
10

うまくいっています。

では逆にFOOが定義されていた場合はどうなるでしょうか。

#define FOO 99

#ifdef FOO
#    undef FOO
#else
#    define FOO 10
#endif

int main () {
    printf("%d",FOO);
    return 0;
}
main.c(16) : error C2065: 'FOO' : 定義されていない識別子です。

ちゃんとundefによって削除されていますね。

問題3

デバッグ段階での実行時には、画面に現在の処理内容を詳細に表示しながら実行を進め、本番の実行時には、余計な表示を一切しないようにプログラムを書きたいと思います。デバッグ段階と本番との切り替えを簡単に行うために、プリプロセッサディレクティブを使って、プログラムを書いてみて下さい。どんなことをするプログラムかは自由に決めて下さい。

こんな感じでしょうか。まずはデバッグ表示ONの場合

#define DEBUG 1

int main () {
#if DEBUG
    puts("A");
#endif

    puts("10");

#if DEBUG
    puts("B");
#endif

    puts("20");

#if DEBUG
    puts("C");
#endif
    
    return 0;
}
$ main
A
10
B
20
C

そしてOFFの場合

#define DEBUG 0

int main () {
#if DEBUG
    puts("A");
#endif

    puts("10");

#if DEBUG
    puts("B");
#endif

    puts("20");

#if DEBUG
    puts("C");
#endif
    
    return 0;
}
$ main
10
20
答え合わせ
#ifdef DEBUG
#define DEBUG_PUT(str) (puts(str))
#else
#define DEBUG_PUT(str)
#endif

なるほど。出力だけするんであればこういうマクロを定義しておけば可読性はかなりあがりますね。

僕のやったやり方だと#ifが要所要所に入り込んでるせいでかなり見難いですし。