next up previous contents
Next: 17. 配列 I Up: 16. プリプロセッサ Previous: 16.3 プリプロセッサ cpp

16.4 課題 16

cd c を実行した後で( ~/c に移動した後で )、以下の課題を やってみよ。

課題 16.1

マクロ sq(x) について、本文に示した誤った例2つについて実際に cppを用いて、展開結果が間違っていることを確認しなさい。

課題 16.2

プログラムの開発過程ではバグを出す作業をデバッグと呼んでいる。 デバッグの手法にはいろいろなものが考えられているが、最も 原始的でありながら古来より使われている手法に、cout 攻撃 と呼ばれるものがある。これは、怪しいとにらんだ主要な変数や 関数の呼び出しなどを、しつこく cout 文を使って表示する ものである。これが本文で紹介した以下のような使い方で、 当然、大量に導入した cout 文をデバッグが終った後に、 わざわざ削除するのも面倒なので、ifdef-endif を 用いて処理している訳である。

    #ifdef DEBUG
        cout << "debug: hensuu is " << hensuu << endl;
    #endif

さて、そうは言ってもいちいち上記のように #ifdef#endif で囲むのも面倒であるので、これをマクロに置き換え ることを考えよう。このマクロを Debug() とし、 プログラム先頭に #define DEBUG があれば、上の ifdef と 同じように働く cout が呼ばれ、なければ何も起こらないような マクロを考えなさい(勿論、この場合引数は2個のみの場合であるが)。

    Debug("hensuu is ", hensuu);

課題 16.3
課題 15.2 について、グローバルな外部変数を各々のモジュールに宣言したが、 これをヘッダファイルに移して、2つのモジュールは各々この一つのヘッダ ファイルを取り込むだけで良いように改造せよ。 但し、main()関数が定義された方のモジュールの先頭部分は以下のように なっているものとする。

    /* main module */
    ...
    #define MAIN
    #include "dansion.h"

作成したプログラムをメイルで creport まで送りなさい。題は、kadai16 とする事。

前回の復習
プリプロセッサ

Cのコンパイラは、コンパイル作業の前に一連の作業を行う。これはプリプロセッサ と呼ばれているが、プリプロセッサに命令するためのコマンドの一つが #include 命令である。この命令の意味は、指定したファイルをその場所に 取り込む事である。従って、モジュール間で共有したいファイルなどを取り込むた めに使われ、標準ライブラリなどの部品の関数宣言やその他の定義もこれを用いて ソースに埋めこまれるようになっている。

<>でファイル名を括った場合には標準のパスからしか読み込まない が、

    #include <stdio.h>
"" で括った場合には、カレントディレクトリを探してから標準パスを 探すようになっているので、自作のファイルを取り込む際にはこちらを使う。
    #include "mylist.h"

こうした取り込まれるファイルはヘッダーファイルと呼ばれ、拡張子に .h を用いるのが慣例となっている。

記憶クラス

変数の有効範囲や、寿命は変数の記憶クラスによって決まる。 記憶クラスと寿命の関連を再掲すると以下のようになっている。

変数 宣言場所 記憶クラス指定子 有効範囲 寿命
レジスター変数 関数(ブロック)内部 register 関数(ブロック)内部 消滅
自動変数 関数(ブロック)内部 auto 関数(ブロック)内部 消滅
静的変数 関数(ブロック)内部 static 関数(ブロック)内部 永続
外部変数の引用 関数内部 extern 関数内部 永続
外部変数の引用 関数外部 extern モジュール内部 永続
外部変数 関数外部 無し モジュール全域 永続
静的外部変数 関数外部 static モジュール内部 永続


next up previous contents
Next: 17. 配列 I Up: 16. プリプロセッサ Previous: 16.3 プリプロセッサ cpp
Noriyo Kanayama