9.プリプロセッサとメイクファイル

9-10. デバッグモードの追加

残りのプリプロセッサ
#ifdef
#ifndef
の解説をして実際にプログラムにデバッグモードを追加します。

#ifdef 識別子

識別子が定義されていたら以下をコンパイル。

#ifndef 識別子

識別子が定義されていないなら以下をコンパイルです。
#if と違うのは定数式でなく識別子であることです。
識別子として宣言されたもの以外、具体的には数字の1などは使えません。

そしてこれらは#ifの代わりに最初に書きます。
書式については前回と同じになります。

例:
#ifdef 識別子 (または#ifndef 識別子)

識別子が定義されている(いない)とコンパイルする。

#elif 定数式

上記がコンパイルされなかったとき定数式が真であればコンパイル。

#else

上記のどれもがコンパイルされなければここをコンパイル

#endif

となります。

それでは、最後にデバッグモードとしてプログラムの実行状態をトレースするプログラムを書きます。

開発環境にはデバッグツール(デバッガ)が用意されていますが、説明書に使い方が載っていなかったりで実際使わない方のほうが多いと思います。
また、ソースファイルそのものでトレースできるように加工すれば、開発環境が変わったり、デバッガのないフリーコンパイラでも開発の手助けになります。

#include<stdio.h>
int fadd(int, int);

main()
{
  int i,j,k;
  for(i=0;i<3;i++){
    for(j=0;j<3;j++){
      k=fadd(i,j);
      printf("i + j = %d\n",k);
    }
  }
}

int fadd(int x, int y)
{
  return (x + y) ;
}

上のプログラムに関数実行と変数の状態のトレースを追加します。

#include<stdio.h>
#define ON  1
#define OFF 0
#define DEBUG    /* DEBUG mode 不可にする時はコメントアウト*/
#define TRACE ON /* OFFにすると変数のトレースを無効にします */

int fadd(int, int); /* 2つの値の和を求める関数 */

main()
{
  int i,j,k;

/* C言語ではオブジェクトの宣言を最初に書かないと
  エラーになるので#ifdefを次に書きました。 */

  #ifdef DEBUG /* メインの始まりを知らせる */
    printf("Start main function\n");
  #endif

  for(i=0;i<3;i++){
    for(j=0;j<3;j++){
      k=fadd(i,j);
      #if TRACE
        printf("i = %d, j = %d\n",i,j);
      #endif
      printf("i + j = %d\n",k);
    }
  }
  #ifdef DEBUG /* メインの終了を知らせる */
    printf("End main function\n");
  #endif
}

int fadd(int x, int y)
{
  #ifdef DEBUG /* faddが呼び出された事を通知 */
    printf("Call fadd function\n");
  #endif

  return (x + y) ;
}

今回は出力の量が多いのでファイルへ出力しましょう。
リダイレクトといいます。

filename > ans.txt

ウィンドウズをお使いの方でDOS窓を使うのが面倒な方はバッチファイルを作ることでDOS窓を起動する手間が省けます。内容は上記そのままにして拡張子は.batにしてください。

またLSI-CなどのDOSコンパイラを利用されている方はファイルの実行時に.pifファイルが作られます。これを右クリックし出てきたダイアログから「プログラム」タブをクリックしその中の「コマンドライン」の.exeの後に > res.txt と追加して次回からpifのアイコンの方をダブルクリックしてみてください。

次章
10.ポインタ