マクロ - みる会図書館


検索対象: 月刊 C MAGAZINE 1991年1月号
29件見つかりました。

1. 月刊 C MAGAZINE 1991年1月号

五ロ はしめて学ぶプロクラー ニンク だけなのて、 , プログラムのある部分だけを マクロにすることがて、きます。 無限ループのマクロ化 たとえば無限ループを表すマクロを Fig. 10 ー①のように定義し , Fig. 10 ー②のように 使用すれば , このプロックが無限ループだ ということがよくわかるかと思います。 引数つき main 関数定義部のマクロ化 引数つきの mai n 関数のお決まりの書式 Fig. 1 ト①もマクロにて、きます 0Fig. 11 ー② のように定義すれば Fig. 1 ト③のように簡潔 に表現て、きます。 arg_main( ) は Fig. 11 ー④ のように展開されます。 ファイルオープンのマクロ化 ファイルのオープンやクローズなどもお る部分を意味がよくわかるように名づけた るという規則があるのて、 , Fig. 9 ー④のよう マクロにすることが , 基本的な技法だと思 決まりのパターンなのて、 , マクロにしたほ になります。 List 8 を実行して確かめてくだ うがよいて、しよう。たとえば Fig. 12- ー①のよ います。マクロは関数と違い置換している Fig. 10 無限ループのマクロ #define LOOP fO 「 ( : : ) LOOP { ひととおりプリプロセッサの文法の説明 をしたのて、 , 実際の応用について簡単に説 明しましよう。 何度も強調しますが , マクロは置換をし ているにすぎないのて、 , かなり柔軟な , あ るいはトリッキーな記法がて、きます。した がって , その使い方はプログラマの趣味に よるところが大きいものて、す。これから紹 介することも , 自分が納得するものだけを 採用して , 自分専用のマクロを集めたヘッ ダファイルを作ればよいて、しよう。 バターンが決まった表現のマクロ化 いつもパターンが決まった記述をしてい Fig. 9 マクロの使用例と展開例② #define ロ「 int_data(data) p 「 intf( #data " : %d*n"' data) data_print(x) ; ①②③④ 引数つきのマクロの例 List 8 1 : #include く stdio. h> 2 : 3 : #define print-data( data ) 4 : 5 : i nt ma i n ( VO i d ) 7 : i nt X 8 : print-data( 9 : print_data( return 0 : 13 : } data printf( #data " = %d%n" / * 変数 x の出力 * / / * 変数 y の出力 * / b 「 eak: Fig. 1 1 引数っき main 関数定義部のマクロ ① int main(int a 「 gc, cha 「 *a 「 gv [ ] ) #define a 「 g_main( ) int main(int a 「 gc, cha 「 *a 「 gv [ ] ) a 「 g_main( ) int main(int a 「 gc, Cha 「 *a 「 gv ロ はしめて学ぶ C プログラミング 125

2. 月刊 C MAGAZINE 1991年1月号

なるような定義は , 一度しか評価されませ ん。たとえば , #define A B #define B A を実行するとプログラム中の A は B に置換さ れ , B は A に置換されます。つまり , printf()A = 0/od*n", A) ; 0/od*n ” printf("B は以下のように置換されます。 printf()A = 0/od*n" printf("B List 5 を見てください。このプログラムは 多重定義した定数を出力するだけのプログ ラムて、す。期待どおり動作するかどうか確 訒してください ロ心、 Fig. 6 マクロの書式 ・・①記号定数マクロの書式 #define identifie 「 token-sequence #define identifie 「 (identifie 「 -list) token-sequence ・・②引数付きマクロの書式 引用符つきの文字列の中 identifie 「と同名のトークンがどうなるか List 4 1 : # i nc I ude く std i 0. h > 2 : 3 : / * 記号定数の定義 * / 4 : #define TEST 10 5 : 6 : i nt ma i n ( VO i d ) printf("This is a TEST( %d )Yn", TEST ) : 8 : return 0 ; 9 : 10 : } 引数つきマクロ 置換されます。 それて、は真打ち , 引数っきマクロの説明 多前定義て、はどちらが先に定義されてい 多重定義 ( マクロの入れ子 ) に進みましよう ( 以下引数つきマクロもマク るかは関係ありません。たとえば , 上記の ロと略します ) 。 # define 文はたんなる文字列 定義の順番が逆て、 , プリプロセッサは多亜定義 ( 人れ子 ) て、き の置換だけて、はなく , マクロを定義可能な #define B C ます。たとえば , ことが非常に強力な武器となるのて、す。前 #define A B #define A B 号と重なる部分がありますが復習も兼ねて となっていても A は C に置換されます。プリ #define B C 基本的なことから説明します。マクロの書 プロセッサは置換の際の不整合が生じない と定義されていたとします。このときプロ 式は Fig. 6 ー②のようになります。 ように何回もスキャンしてくれるからて、す。 グラム中の A はまず B に置換されます。しか もっとも簡単なマクロの例として 2 乗を求 しかし , 無限ループ ( 自分自身に戻る ) に し , その B は C に置換されるのて、結局 A は C に めるマクロ square を定義してみます。 多重定義した定数を出力するプログラム #define square(x) (x) * (x) このように記述することによって 2 乗を求め るマクロが簡単に定義て、きます。たとえば , square(5) : とするとプリプロセッサによって , と展開されて 2 乗が求まります。このような プリプロセッサの働きをちょっと難しい 葉て、いうとインライン展開といいます。 マクロの効用 2 乗を求めるマクロの例を見れば気がつく かと思いますが , マクロのよい点は関数の List 5 子 れ 0 入 の 0 1 よ ^ し【し 数 + し十》十 ) 十》↓し 定 11 ワ〕っ 0 -4 ・ 0 ^ 0 ー 8 0 11 ワつ 0 -4 ・ L.O ^ 0 7 ー 8 1 ・よ 1 ーよ 1 ーよ、ーム 1 ・よ、ー・、ー・ 1 ー 4 1 ーよ 1 ー・ Y = %dYn ” ニ %dYn ” ニ %dYn ” = %dYn ” ニ %dYn ” return 0 : 122 CMAGAZINE 1991 1

3. 月刊 C MAGAZINE 1991年1月号

カンマ演算子で記述した場合 List 7 10 : { 5 : char -tmpC MAXTMP ] : / * 作業領域 * / 4 : #define MAXTMP 80 2 : #include く stdlib. h> # i ncl ude く std i 0. h 〉 1 : 3 : 6 : 7 : 9 : #define input_int( msg, i ) #define output-int( msg, i ) printf("%s" msg printf("%s%dYn" atOi ( gets( _tmp msg, i nt ma i n ( VO i d ) i nt X : wh i I e ( i nput- i nt ( " I nput X ニ output-int( "X = return 0 : のような計算をしたとします。 プリプロセッサは , 2 十 3 * 2 十 3 ; Y この場合 , と展開してしまいます。これて、は正しい値 が求まりませんね。この場合 , 最初のよう #define square(x) (x) * (x) とするとプリプロセッサは , ( 2 + 3 ) * ( 2 十 3 ) : Y と展開し , 正しい式になります。このよう 124 CMAGAZINE 1991 1 グラマが注意してマクロを正しく使用する な問題なのて、す。この問題は , 私たちプロ いう性質のものて、はなく , マクロの本質的 上手に書き換えれば避けることがて、きると て、きないことがあります。これはマクロを 義てはインクリメントなどを行う式が代入 されてしまいますね。このようにマクロ定 これて、は , y の値も x の値もまちがえて計算 Y ( 十十 x) * ( 十十 x) ; に展開します。 この場合 , プリプロセッサは , 以下のよう Y square( 十十 x ) : うなときにはどうなるて、しようか。 の使い方が正しかったとしても , 以下のよ 十分気をつけてくださいね。また , カッコ 要になってきます。プログラムをするとき に関数マクロを使うとカッコの使い方が重 / * 入力部 * / / * 出力部 * / ほか , 避けることがて、きません。 List 6 の動 作を確認してください ためて、す。このような配慮も行うようにし は , ほかの変数名と衝突しないようにする のようにアンダースコア、、〃をつけているの tmp 変数名に , ボラリ用の変数を使うということをします。 なマクロを定義する場合 , このようにテン 用の配列を用意しています。ちょっと複雑 この例て、は , まず tmp というテンボラリ int を定義してみましよう (Fig. 7 ) 。 るマクロ input int と , 出力するマクロ output プロンプトを出力して int 型の値を入力す てください こて、重要なことはカンマ演 算子の働きて、す。カンマ演算子によって , ふたつの式をひとつの文にまとめることが て、きるのて、す。たとえばマクロ input int を Fig. 8 ー①のように使用したとします。これは , Fig. 8 ー②のように展開されます。 カンマ演算子て複数式を並べて記述した 場合 , 式は左から右に評価されていきます。 そして結果の型と値は , 最後の式のものに なります。したがってこの wh ⅱ e 文の条件式 は , 正しく記述されていることになります。 List 7 を実行して動作を確認してください もしマクロ定義て、カンマて、はなくセミコ ロンを用いていたらどうなるて、しようか ? れます。 C 言語は隣あった文字列は連結され す。このマクロは Fig. 9 ー③のように展開さ したとし , Fig. 9 ー②のように使ったとしま たとえば , Fig. 9 ー①のようにマクロを定義 の引用符つき文字列に置き換えるのて、す。 ていればその引数を実引数て、置き換える形 換テキストの中て、仮引数の前に # 記号がつい の置換を行うことがて、きます。マクロの置 引数っきのマクロて、は , 引用符っき文字列 数マクロて、はて、きませんてしたね。しかし , 引用符つき文字列の中の置換は , 記号定 文字列へのマクロ とつの文にしたほうがよいて、しよう。 ください 一般的にはカンマて、区切ってひ コロンて、区切るか , よく考えてから行って を記述する場合 , カンマて、区切るか , セミ をお勧めします。ひとつのマクロて複数式 使う場合は中力ッコと一緒に使用すること しよう。少し入り組んだところて、マクロを を使ってプロック文にしてしまえばよいて、 このようなバグ、を防ぐには中力ッコ { } なバグが起こってしまいます。 て別々の文にしたいときこのような潜在的 どうしても式と式とをセミコロンて、区切っ は発見て、きないバグになってしまいます。 的なエラーて、はありません。コンパイラて、 結果は得られませんね。しかしこれは文法 の関数 p 「 intf のみになってしまい , 意図した 開されます。これて、は if 文の制御範囲は初め うなるて、しようか ? Fig. & - ⑥のように展 もしカンマて、はなくセミコロンだったらど は , もちろん正しくコンパイルされます。 きは Fig. 8 ー⑤のように展開されます。これ します。 Fig. 8 ー④のような使い方をしたと もうひとつマクロの使用例と展開例を示 すね。 るのて、明かにシンタックスエラーになりま て、は w e 文の条件式の中にセミコロンがあ Fig. 8-- ③にその展開結果を示します。これ

4. 月刊 C MAGAZINE 1991年1月号

のが多いものて、す。 13 ) 。 し マクロ mem a Ⅱ oc の第 1 引数 pt 「は , 確保し のて、マクロにしたくなってきます ta(Fig. リを確保するときもお決まりの処理が続く マクロ mem alloc を定義してみます。メモ て、はこの記法を使ってメモリを確保する 領域確保のマクロ化 去みやすくなると思います。 この記法を前の記法と比較すると格段に わりません。 に Y がついているほかは , 普通の C 言語と変 きます。このように記述すれば行の終わり 直すと Fig. 12 一②のように定義することカイ す。この機能を使い , 上記のマクロを書き 後に Y を置けば次の行に続けることカイきま # define 文て、定義が長くなる場合は行の最 これはなんとかならないのかと考えてみ 1991 1 た領域の先頭ポインタて、す。第 2 引数 type は 126 CMAGAZINE うに定義したとします。このマクロ file open は , ファイルポインタ fp, ファイル名 fname, モード mode を引数としています。 ファイル名が fname のファイルをモード mode て、オープンし , ファイルポインタを fp に代入 します。ファイルオープンに失敗した場合 , メッセージを出力させた後に関数 exit を用い て強制終了させています。 この処理はファイルをオープンするとき には必す行うのて、 , マクロにする価値があ ります。 お勧め , マクロを読みやすくする記法 しかし , Fig. 12 ー①のマクロはとても読み にくいて、すね。プログラムを保守という面 から考えると , 読みやすさも重要なファク ターになってきます。読みやすさが重要て、 あるにも関わらず , 世の中の C 言語の参考書 に瞽かれているマクロの例は読みにくいも 12 : } 19 : } 24 : { #define file_open(fp, fname, mode) if((fp ニ fopen(fname, mode)) = NIJLL) Fig. 12 ファイルオープンのマクロ fp 「 intf(stde 「「 , " % s がオープンてきません。 *n", fname) : exit( 1 ) #define file_open(fp, fname, mode)* exit( 1 ) : \ fp 「 intf(stde 「「 , " メモリーか確保できません。 *n つ : ¥ if((pt 「ニ (type*)malloc(sizeof(type) * ( size ) ) ( #define mem alIoc()t 「 , type, size)* Fig. 13 領域確保のマクロ exit( 1 ) : \ fp 「 intf(stde 「「 , " % s がオープンできません。 *n", fname) , ¥ if((fp ニ fopen(fname, mode)) = NIJLL) { \ ) = NULL) List 9 テキストファイルを連結して標準出力に出力するプログラム int main( int argc, char *argv ロ ) 5 : #define arg_main() 4 : / * 引数付き main 関数定義部のマクロ * / 2 : # i nc I ude く std I i b. h > 1 : # i ncl ud e く std i 0. h> ① 3 : 6 : 9 : 10 : 13 : 15 : 17 : 20 : 21 : 22 : 23 : 25 : 26 : 28 : 29 : 30 : 32 : 33 : 34 : 35 : 36 : 38 : 39 : 40 : 41 : #define mem_alloc( ptr, type, size ) \ 14 : / * メモリに領域確保を行うマクロ * / ex i t ( 1 ) ; \ ” %s がオープンできません。 Yn ” fprintf( stderr, ニ NUL し ) { \ if ( ( fp = fopen( fname, mode ) ) 8 : #define file_open( fp, fname, mode ) \ 7 : / * ファイルオープンを行うマクロ * / fname ) : \ 16 : i f ( ( ptr (type* ) ma Ⅱ oc ( s i 2 eof ( type ) * ( s i z e ) ) ) fprintf( stderr, " メモリーが確保できません。 Yn");Y = NULL ) { \ ex i t ( 1 ) : \ #define MAXBUF 512 arg-main() if ( argc く 2 ) { FILE **fp_ptr; i nt i : char buf[ MAXBUF ] : "Usage ex i t ( 1 ) : fprintf( stderr, mem for -alloc( fp_ptr, FI し E * , argc ー ( i 0 : i く argc fputs( buf, stdout ) : while ( fgets( buf, MAXBUF, fp_ptr[ file-open( fp_ptrC i ] , argv[ i + 1 ] , / * 引数付き main 関数定義部 * / / * ファイルポインタのポインタ宣言 * / / * ファイルオープン / * ファイルポインタ型の領域確保 * / . く ret>Yn ” argv [ 0 ] ) : / * 引数のチェック * / : %s f i 1 e 1 f i 1 e2 . / * 行入力 * / / * 行出力 * /

5. 月刊 C MAGAZINE 1991年1月号

五ロ 一三ロ ニ : 0 はしめて学ぶプロクラー ニンク ように引数の型に依存しないということが 挙げられます。 squa 「 e は int 型て、も dou 団 e 型 て、も使うことがて、きます。あまり意味がな いかもしれませんが cha 「型て、も使うことが て、きます。 int 型て、同じ動作をする関数を作 ると以下のようになります。 int square( int x ) らそれにともなう副作用もあるのて、す。 た とえば , マクロの副作用 #define sqr(x) x * x マクロはいいことずくめかというと世の のように定義してしまったとします。 この 中そんなに甘くありません。マクロはテキ とき , たとえば , ストの置換をしているにすぎないのて、すか sqr(2 十 3 ) : 正しい定義と間違った定義の確認 1 : #include く stdio. h> 2 : 3 : / * 正しい定義 * / 4 : #define square( x ) ( x ) * ( x ) 5 : 6 : / * 間違った定義 * / 7 : #define sqr( x ) x * x 8 : 9 : int main( VOid ) 10 : { int X, y; ニ sqr( 2 + 3 ) : / * 間違った定義での使用 * / 13 : Y printf("sqr( 2 + 3 ) = %dYnYn ” 15 : square ( 2 + 3 ) : / * 正しい定義での使用 * / printf("square( 2 十 3 ) = %dYnYn ” square( 十十 x ) : / * 間違った使用方 * / 20 : printf("x 2Ynsquare( + + x ) %dYnx ニ %dYn ” 22 : 23 : return 0 : 24 : } Y List 6 return( x * x ) ; 「自分は , 普通の関数のほうが慣れている し , int 型しか使わないからこのほうがいい や」と思っている方 , ちょっと考えてみてく ださい。このような小さな関数を書く場合 はマクロて、書いたほうが簡潔に表現て、きま すね。 て、もそれだけて、はありません。それ以上 に重要なことがあるのて、す。 この関数 squa 「 e が頻繁に呼び出されるよ うなプログラムを書いたとします。前月号 て、お話したように関数を呼び出すとき , 引 数はスタック領域を介してやり取りされま す。さらに関数を呼び出す場合 , レジスタ の退避なども行われます。 関数呼び出して、はこのようにオーバヘッ ドが生じるのて、す。 squa 「 e などの小さい関 数は相対的にオーバヘッドが大きくなって しまいます。 つまり関数が実際に行うべき計算に比べ て , 関数呼び出しのオーバヘッドの比重が 大きくなってしまいます。 マクロて、記述した場合はたんに展開され 置換されるだけなのて、オーバヘッドがなく , 関数て、記述されたものより高速なオプジェ クトになります ( その代わりオプジェクトの サイズは大きくなってしまいます ) 。 たとえば何重にもネストしたループの内 側て、 squa 「 e を使っているとすると , 関数て、 定義されていればループの中て呼び出され るたびにオーバヘッドが生じますが , 関数 マクロて、定義してあればそのようなことは ありませんね。 Fig. 7 int 型の値を入力するマクロ input. ー int と , 出力するマクロ 0UtPUt_int #define MAXTMP 80 cha 「 _tmp [ MAXTMP ] : #define inout—int(msg, i) P 「 intf("%s", msg)' (i : atoi(gets(_tmp))) #define output_int(msg, i) P 「 intf("%s%d*n", msg,(i ) ) Fig. 8 マクロの使用例と展開例 (l) ①②③④⑤⑥ while(input_int("lnput X : " , x) ド while(printf("%s". "lnput X = つ , ( x : atoi(gets(_tmp)) ド whiIe(D 「 intf("%s",'"lnput X = つ : (x ニ atoi (gets(-tmp)))l: input. 」 nt("lnput X : ",x) : if(a = 1 ) p 「 intf("%s", "lnput X : つ , (x : atoi( gets(_tmp))) : ロ「 intf("%s", "lnput X : つ : (x : atoi(gets(_tmp))) ・ はしめて学ぶ C プログラミング 123

6. 月刊 C MAGAZINE 1991年1月号

株式社ア勤コト バーソナルソフトウェア営業部 アス 統合型表計算ソフト「アシストカルク」、 U N I X の領域へ。 IJN Ⅸ対応版統合型表計算ソフト あのアシストカルクの IJN Ⅸ対応版、ニューリリース。 ・ MS ー DOS 版アシストカルクとの互換性 / MS ー DOS 版と同じ操作性を 実現。 PC ユーザも抵抗なく使用できます。またマクロファイルを使用して データ転送も可能。 MS ー DOS 版とのデータ互換を保てます。・メモリの 制限なし / メモリの制限を受けないので、本来のアシストカルクの機能を フルに使用できます・『アシストカルク十データベースコネクション』では、 メニュー選択方式、または SQL 文の入力により、外部データベース ( ORACLE 、 Sybase ) からデータを検索し、ワークシートデータとして展開 できます。・マウスの使用が可能・デバッガの使用でエラーを素早く処理 SIJN シリーズ対応 ( 新発売 ) ・ NEWS シリーズ対応 ( 12 月発売予定 ) UNIX 、 MS-DOS 、 SUN 、 NEWS 、 ORACLE 、 Sybase は、それそれ、米国 AT & T 社、米国マイクロソフト社、米国 サンマイクロシステムズ社、ソニー株式会社、米国 O 日 ACLE 社、米国 Sybase 社の商標または登録商標です く資料請求番号 004 > 87 , 300 円 ( 税込価格 89 , 919 円 ) アシストカ丿レク十テータベースコネクション 137 , 300 円 ( 税込価格 141 , 419 円 ) ※シリーズ対応のみ ※お問い合わせ先 : 株アシストテクニカルサポートセンター TE し .044 ー 951 ー 5678 FAX. 044 ー 951 ー 5679 株ソフトウェアジャパン TEL. 03 ー 479 ー 8760

7. 月刊 C MAGAZINE 1991年1月号

ßriQf ユ ■「メモ」「書式」「スケジューノレ」 etc ・・ 編集中も表示可能、妙ロの応用機能。 旧 M PC でトップセールスに輝く プロフェッショナノレエデイター「 BR に F 」 プリーフの高機能 その 1 マクロは「工夫」を実現します ! prompt .m (nacro 「 00 : pt - b : n vanable (prmpt] ロ E t 司 ()f _hzstory_buf [def ヨ」1t:) : 灯 old_buf cld ー m 」 く用途 > 行のマクロに指定されたパラメータを取り込みます ユ u 「「一・・ひしでパラメータを指定ノない ( または、フクロ ( : old-buf (arq-b で直・び出しされたり、コマンド行から ( : 0 ] d ュ sg 」 el exec し te-macro でび出しされた ) ときは、パラメタ の入力を要求するプ・ロンプトを出すことができます。 (get-»arm 3 - 〔 u 「「「 m - no を乢 L に ~ すると、つねにプロンプトを出 ( g - 。。 1 。。。して、父または文子のパラメータを 1 つだけ取り込 ()f い ( 5 : 「」 er, _c みます。 Cur 「一 CO ー 0 日 n くパラメータ > 最初 3 ) garm-no は、パラメータの番号を指定する第文で、 、 (set-buffer -hist のパラメータは 9 てすなまります Lxne: し ol 2 たとえば、マクロでオーバーラップ・ウインドウを表示することができます。表示だけでなく ウインドウの中に書き込むこともできます。もちろんアンドウも使用できます。これを使れ、 ~ ろいろなことができそうです。 編集中に電話番号やちょっとしたメモが必要になったりします。そのたびに住所録やメモ 帳を取り出すのは面倒なものです。そんなときはオーバーラップ・ウインドに表示させまし よう。メモを見たり、書き込んだり、机の上を探し回る無駄な時間は最小限にしたしので魂 「自分で作らないからマクロ機能はいらない ! 」と決めつけないでください。公開されたマ のクロを手 ( ュ、れれば新い、機能を使うことができるのです。作らなくても機能を増やせるこ とになりますこのため弊社では、公開マクロのユサー相互利用を推進しております ッ Wo 「 dsta 硼のキー・アサインや行のソート処理など魅力的なマクロを公開しています B 「 ief マクロプログラミングコンテスト ( 8 月末締切 ) 募マクロも公開する予定です公開 マクロについては Br f ユーサ・サポート係にお問い合わせください。 USER'S VOICE B 「 ief とは長い付き合いになると思う。 私どもの実験は非常に厳しい条件で行うためデータの記録 には迅速かっ正確さが要求されま魂記録に漏れがあればデ ータの分析ができなくなり、全ての努力が無駄になりまこの ためマクロを利用し、記録項目をガイドに従って入力させるこ とにしました。また、入力ミスにはアンドウて対処することで、迅 東京理科大学工学部経営工学科 速かっ正確な入力が実現できました。 富澤儀一助教授 日本語 Brief とこれから先は長い付き合いとなると思います オピニオンリーダー誌のこの評価 ・プログラミング向きのエデイターを探している人は、もう探す必要はない。」 erry Pournelle(BYTE) ・ Brief はプログラマーに最適なだけでなく創造力をかきたてる何物かがある。 Computer World ・ほとんど完ぺきにカスタマイズできるだけの拡張性がある。 Computer language ・まるで夢のようなアンドゥだーおもわす間違うのを期待してしまいそうだ。 The C Users Journal ・主な機能 ◆パッファ書出 / 切換 / 削除 / リスト表示◆ファイル名の指定 / 表示 / 変更◆パック アップ保存◆特殊文字入力◆ 2 行を 1 行に連結◆ファイル単位の挿入◆増分検 索◆各種マーク始・終点の入換◆プロックのカット / コピー / ペースト / 印刷 / 保存 左右へのシフト◆対応する括弧へ移動◆ C 言語のコメント化非コメント化◆ DO S コマンドの実行◆キー操作記憶 / 実行◆入力ヒストリー◆英文テキスト整形◆ タブのスペース挿入◆拡張子毎に異なった設定ができるタブ◆検索置換バター ンの画面からの入力◆英字の大小文字変換その他 48 , 000 円 ( 消費税は含ます ) ・全機種対応パッケージ 5 ・ 2DD / 3.5 2DD 一括提供 ( MS ・ DOS3.1 以降対応 ) 上記以外のメディアは注文販売となります。 英語用 DOS では使用出できません。 日ホシステム槽式会社 ・お問い合せは東京都立川市曙町 1 ー 18 ー 2 ー清ビル立川事業所 Brief ユーザー・サポート係 TEL. 0425 ー 23-4469 FAX. 0425 ー 27 ー 6127 使わない方にも便利なマクロです ! 三く靆 FI ] 已 c コマント 46 メモ画面 31 こ印 : 4 ! ! 【「リ : przntf ( " 31 「 r すⅢ 1 円 : 記 ) , ー已 : ・以下第か蛎乍可能でオ。 - コ 03 い 3T : い 9 訂 鑿第 J 三いはい 0 ・を AX 協議会 富士通 日 53 / 0 日 : 3 門 5 St'TiV/Z 阯 5 い日 / p リーて N 三 C 333 ] F 川加 / き F / ⅵ↓阜 : ,'L.V/cW/RAfF.>. /LS/I. X,'ES/EX/.RS 明 X い 2 / ヨ L 朝一・ト・ : fil, ・らしい orl 「 h - 1 第 1 n 叫 u 買ー { If (d 、 if :d : 15 ) { erd d : レ ls 呂 : op_d 日ー d ・ : 15 い 1 「明弌 t ] 既・ h01 : F ロ已 c b 冂 ef れ旧ロ℃対応筬ー 0 、 Es い Exit 1 11 し 1 い ? 対応機種一覧 ・革命的マノレチマシン・エデイター 東芝・ NEC ・ AX 協議会・旧 M ・富士通の 5 機種のパソコンで動作します。 ・ 300 回ものアンドゥ 各ファイルごとに 300 までの操作を元に戻すことができますので、やり直しの面倒を気に せす、安心して編集できます。 ・ 55 ウインドウ、無限のファイル数 ウインドウは縦横自由に 55 まで開くことができます。また同時に編集できるファイルの数や 大きさには制限がありません ・プログラミング ◆自動コンバイル、エラージャンプ◆スワップアウト 自動インデント、自動テンプレート ・安全編集 Brief は、一定時間キーを操作しない場合、その時点の編集内容をファイルに自動保存 しますので、編集中に電源が切れても安心です ・ Fu S い・ 00 く資料請求番号 196 〉

8. 月刊 C MAGAZINE 1991年1月号

はしめて学ぶプロクラー ニンク 匚 , ・。コ 確保する領域の型て、す。第 3 引数 size は確保 出力するプログラムて、す。 5 , 8 ~ 12 , 15 ~ 19 する領域の大きさて、す。 行目て、それぞれのマクロを定義しています。 サンプルプログラム この記法て、書くとこのマクロの意味も見 23 行目はマクロ arg_main( ) を使い ,main 関 ただけて、わかりますね。これらは , 今まて、 それて、は List 9 を見てください 数を定義しています。 29 ~ 32 行目は引数の の連載て、よく出てきた表現をマクロ化した このプログラムはコマンドラインて、与え 数をチェックしてエラー処理をしています。 だけて、す。 たテキストファイルを連結して標準出力に 34 行目は F に E * 型のポインタを引数の数 ( つまりファイルの数 ) だけ確保し , その先 頭ポインタを F に E * * 型の変数 fp pt 「に代 入しています (argc はそのコマンドも数に数 えているのて、引数の数は argc ー 1 個て、す 36 ~ 40 行目の f0 「文て、コマンドラインて、与 えたファイルを最初から順にオープンし , こて、最初の 標準出力に出力しています。 引数は a 「 gv [ 1 ] からはじまることに注意し てください ( 37 行目 ) 。そして 1 行ずつ読み込 んて、は標準出力に出力しています ( 38 , 39 行 目 :Fig. 14 ) 。 42 , 43 行目は順番にファイル をクローズしています。 45 行目は fp pt 「の指 す領域を解放しています。 このプログラムは , ファイルポインタを ファイルごとに用意しています。しかし , このアルゴリズムて、は , ひとつのファイル ポインタを再利用して複数回使うことがて、 きます。ちょっと考えればわかりますね。 List 9 て、はマクロ mem a Ⅱ OC も例題として使 いたかったのて、わざわざこのようにしてい ます。 List 9 for ( i 0 : i く argc fclose( fp-ptr[ i free( fp-ptr ) : return 0 : っ 0 っ -4 ・ - -0 ー 8 / * ファイルクローズ * / / * ファイルポインタ型の領域解放 * / Fig. 14 List 9 の動作 ( 1 ) ループ 1 回目 ( 初期状態 ) argc = 4 argv argv[01 argv[l] argv[2] argv[3] list3. c list2. c A>list9 listl. c FILE 型 fp—ptr[01 fp_ptr[l] fp—ptr[21 日 LE 型 mem ー加で領域確保 今月はプリプロセッサについて説明をし てみました。プリプロセッサはまだまだ奧 が深く , とても 1 回の説明て、はすべてをカ ーて、きません。しかし , 大体のアプロー チの方法は伝わったのて、はないかと思って います。あとは皆さんが創意工夫し , いろ いろと試みてください。オリジナルのマク 口を集めたヘッダファイルを作ってはいか がて、しようか。 ( 2 ) ルーカ回目 argv argv[0] argv[ 1 ] argv[2] argv[3] list2. c list3. c A>Iist9 listl. c FILE 型 日 LE 型 fp—ptr fp_ptr[0] fp ユ猷 1 ] fp 2 ] はじめて学ぶ c プログラミング 127

9. 月刊 C MAGAZINE 1991年1月号

五ロ はじめて学ぶプロクラー ニンク 16 行目はデバッグ用の記号定数マクロ DEBUG を定義しています。 16 行目を見て「あれっ ? 」と思った方がた くさんいることて、しよう。この #define 文に は置換するトークン DEBUG に対応すべき置 換されるトークンがありません。ここて、は DEBUG が何かに置換されるというのは重要 て、はないのて、す。 DEBUG が定義されている ということが重要なのて、す。この DEBUG と いうマクロは 42 ~ 44 行目てデバッグ用に使 っています。 16 行目のように DEBUG が定義 されていると 42 行目の # ifdef 文が真になっ て , 43 行目のデバッグ用の情報 ( この場合は 各引数 x に対する関数 func の値 y ) の出力部を コンパイルします。デバッグが終了してデ バッグ情報をコンパイルする必要がなけれ ば DEBUG を定義しなければよいのて、す ( 具 体的には / * * / て、囲んて、コメント文にする か , # define 文自体を削除するか , #undef を 使ってトークン D EBUG を未定義にする ) 。 デバッグ情報を埋め込む別の方法もあり ます。まず 14 行目て、 , #define DEBUG 1 のようにしておきます。そして 42 行目を #if DEBUG とします。この場合 , 42 行目の DEBUG は 1 に置換されるのて、 # if 文は真になり , 43 行目 のデバッグ情報がコンパイルされます。デ バッグが終了してデバッグ情報を取りたい ときには , #define DEBUG 0 この #define 文以降て、識別子 identifier は , として再コンパイルすれば 42 行目の # if 文は token—sequence というトークンに置換され 偽になり , 43 行目はコンパイルされません。 記号定数マクロ ます (token—sequence の前後の空白文字は このように #ifdef 文や #if 文を使うと条件つ 捨てられます ) 。 #define 文 ただし , 引用符っきの文字列の中に現れ 基本的な記号定数マクロは何度も使って ている identifie 「と同名のトークンは置換さ きましたね。もうご存知とは思いますが , れません。たとえば List 4 のプログラムを実 # define 文は文字列の置換を行っているにす ぎないということを心にとめておいてくだ 行すると , 今まて、説明してきた機能にも興味深い機 This is a TEST(IO) 能がたくさんあったと思います。しかし , 記号定数マクロの書式は Fig. 6 ー①のよう と表示されます。このように引用符つきの これから説明するマクロ置換こそが , プリ になっています。 文字列の中は置換されないのて、す。 プロセッサ最大の機能て、す。 はしめて学ふ C プログラミング 121 関数 func を使い標準偏差を求めるプログラム List 3 1 : # i nc lude く std i 0. h > 2 : #include く math. h> 3 : 4 : 5 : double func( double x ) : 6 : 7 : / * M 一円の確実な定義 * / 8 : #ifndef M_PI #define M_ 円 3. 141592 10 : #endif 12 : #define MAXDATA M_ 円 13 : #define STEP 15 : / * デバッグ O N * / 16 : #define DEBUG 19 : i nt ma i n ( VO i d ) 20 : { double x, y, sum, sum2; 22 : for ( x sum2 23 : sum func ( x ) ; 24 : Y 25 : sum 十 = y : sum2 十ニ y * y : 26 : 28 : 29 : 30 : 32 : } 33 : 34 : 35 : / * 関数 func の定義部 * / 36 : double func( double x ) 38 : double y; 39 : exp ( -x ) * sin ( 2.0 * x ) + exp ( ー 3.0 * x ) * cos ( x / 4.0 ) : 40 : 42 : #ifdef DEBUG pr i ntf ( " f ( % I f ) 43 : 44 : #endif 45 : 46 : / * 関数 func のプロトタイプ宣言 * / 0. 0 : x く MAXDATA; x + = STEP ) { / * 和の計算 * / / * 2 乗和の計算 * / sqrt( sum * sum / * 標準偏差の出力 * / ー sum2 ) ) : printf(" 標準偏差 %lfYn", return 0 : / * デバッグ情報 * / = %lfYn ” return y;

10. 月刊 C MAGAZINE 1991年1月号

匚一司 五ロ はじめて学ぶプログラミング 第 1 6 回高木聡 / 山崎信行 匚ー司 先月は可変引数を取り上げました。いかかだったでしようか。可変引数の 関数を己述できるのは , C 言語のひとつの特長になっています。今月は , C 言語の大きな武器であるプリプロセッサを取り上げます。 Fig 1 C 言語プログラムの流れ プリプロセッサという言葉を聞いた があると思います。今回はこのプリプロセ ッサに焦点を当てて説明をします。 プリプロセッサの解説を始める前に ず C 言語プログラムが実行可能プログラムに なる流れを復習をしておきましよう (Fig. 1 参照 ) 。 C 言語はコンパイルをする前にプリ プロセスという処理を行います。このプリ プロセスを行うプログラムのことをプリプ ロセッサと呼びます。 処理系によってはプリプロセッサとコン パイラがひとつのプログラムになっている ものもあります。プリプロセッサはマクロ 置換 ( 記号定数 , 引数つきマクロ ) やファイ ルの取り込みなどを行います。また , プリ プロセッサには if 文に相当するような簡単な 制御構造があり , 条件っきコンパイルなど が行えるようになっています。 て、はプリプロセッサについての説明をし ます。その前に , プリプロセッサは行単位 で処理を行うということを頭にいれておい てください プリプロセッサへ指示を与・える予約語は , 118 CMAGAZINE 1991 1 ソスプログラム の標準テキストファイル TST—01 . C TST—02. C TST—XX. C ヘッダファイル ( * . h ) を取り込む ( 今回のテーマ ) プリプロセッサ イ、 ン コンノヾイル オプジェクトファイル リンク 実行可能ファイル TST. EXE プリプロセッサ