next up previous contents
Next: 26. キュー・スタック・バイナリーツリー Up: 25. main 関数の引数 Previous: 25. main 関数の引数

1. 課題 24

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

課題 24.1

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

課題 24.2

ファイルのオープンに際して、


(fp=fopen(file_name,"r"))==NULL
は定型 文であるので、これをマクロにして、read_fopen() というマクロを 作る事を考えよう。このマクロは以下のように使う事を想定している。


    FILE *fp;
    char *file_name="myfile.h";
    ...
    if( read_fopen(fp, file_name ) ){
        /* ファイルのオープンに失敗した場合 */
        printf("Error: cannot open %s\n", file_name);
        exit(1);
    }
    ...

こうなるようなマクロ定義を作成し、展開結果を確かめよ。

同様に、write_fopen()append_open() を 作成せよ。

課題 24.3

標準入力から読み込み、オプションに指定されたファイルと、標準出力 に結果を書き込む mytee コマンドを作成しなさい。 つまり、mytee は以下のように使います。


    > cat kadai24_5.c | mytee mycopy.data | more

この結果、kadai24_3.c はmoreによって画面に順に出ると同時に、 ファイル mycopy.data にも出力される。

但し、読み込みは fgets() を使い、24.2 で作成したマクロも 使わなければならない。更に、定数は全てマクロ定義でなければならない。

作成したプログラムをメイルで creport まで送りなさい。題は、kadai24 とする事。 但し、モジュール別に開発した場合には、それぞれのモジュールが 分かるようにして送りなさい。

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

コンパイルされる以前にソースに自動的に施される処理をプリプロセス( 前処理)という。#include もプリプロセスの機能の一つであった。

#define 文

    #define  マクロ定義名  [値]
によって、これ以降マクロ定義名で参照したものはプリプロセッサに よって値に置き換えられる。


    #define マクロ定義名(引数並び)  引数を含む文字列

引数を含んだ置き換え機能であるが、副作用などがある点に注意が必要。 引数は括弧で囲んだ上に、引数を含む文字列自体も括弧で囲むのが安全だが、 それでも回避出来ない問題もある。

#ifdef #else #endif文

C の if とほぼ同じ意味であるが、マクロ定義がされていれば真となる。


    #ifdef マクロ定義
    ...
    #else
    ...
    #endif

逆の意味で #ifndef は定義されていなければ真である。

#if #else #endif文

より一般の #if 文も用意されている。

cpp コマンド

プリプロセッサのコマンドは通常 cc から自動的に呼び出されるが、 cpp コマンドを使って明示的に呼び出すことも出来る。

main 関数の引数

プログラムに渡された引数はコマンド自体の名前を含めて、main関数の 引数に渡される。


       main( int argc,  char *argv[]){

argc にコマンド自体も含む引数の個数が、argv[]にそれらの 一つ一つの引数へのポインタが入っている。



Noriyo Kanayama 平成14年11月26日