マクロ - みる会図書館


検索対象: 月刊 C MAGAZINE 1990年12月号
30件見つかりました。

1. 月刊 C MAGAZINE 1990年12月号

するソースプラウザ機能がビルトインされ った。 35 個におよぶ C010r スイッチは PWB ル移動やテキストセレクト , ウインドウ操 た。あらかじめ , Make メニュー, Options だけて、なく , CodeView やヘルプ画面につい 作などの効率が大幅に向上した。また , ウ メニューのコマンドを使用して , ソースプ ても指定する。 Build スイッチはコンパイ インドウにはリサイズ機能も付加されてお ル , プロジェクトビルドにかかわる情報を ラウザの検索対象となるデータベースを定 り , ダイアログボックス , ヘルプウインド 義することて , コンパイル時にプログラム 構文指定する。おもな指定内容を列記する ウなどを含むウインドウの操作がクイック 情報のデータベースが作成され , 対話形式 と以下のとおりとなる。 かつイージーにてきるようになった。 て、プログラム情報を検索て、きる。また , ソ NMAKE マクロを指定するマクロ指定 , さらに , QuickC 風なウインドウによるユ ースプラウザはヒストリー機能を備えてお 目的ファイルのリストを指定するターゲッ ーザインタフェイスは , カスタマイズされ り , プログラミング構造解析中のローカル ト指定 , 目的ファイルのビルドコマンドを るプラインドな高速キー操作との併用が可 なヒストリーを作成するため , 以前に検索 定義するターゲット指定 , オプジェクトフ 能となっているのも大きな特長といえよう。 した箇所に簡単に戻ることもて、き , 開発効 ァイル作成時のコマンドを指定する推論規 プラインドなキー操作を補うものとしては , 率はきわめて高くなる。また , 検索結果を 則指定 , コンパイル , ビルドのコマンドラ メニュー , ファイル選択などのリストボッ リスト生成て、きるため , 必要に応じてプリ インを指定するコマンド指定 , ソースファ クス , テキスト入力などのためのダイアロ ント出力することも可能だ。以下にソース イルて、検出するタグを指定するインクルー グボックスやプロンプトなど , ビジュアル プラウザの主要機能をまとめよう。 ド指定 , 工ラーメッセージ書式を指定する なユーザインタフェイスが採用されている。 メッセーシ孑旨疋。 ◇シンポル名を指定して , 関数 , 変数 , 型 , 画面の分割て、は自動的にカレントファイル マクロの定義部分への移動 そのほかのスイッチについても , たとえ がデュープリケイトされ , ポックスモード ば , ディスクを満杯にしないよう指定する ◇シンポル名を指定して , 関数 , 変数 , 型 , のほかにラインモード , ストリームモード マクロの参照部分への移動 Undelcount スイッチ , キーのフリクション が選択可能となった。 ◇ PWB ソースプラウザのデータベースを検 を制御する ( 加速キーを実現する ) Fast 以上のようにプログラマズエデイタて、は func, Factor スイッチ , ューザの追加メニ 索し , 関数 , 変数 , 型 , マクロの個別指 多くの機能が拡充強化されている。ちなみ 定の関係表示 ューを指定する User スイッチなどが追加さ に編集機能は , 基本機能 88 種類 , 個別機能 ◇関数 , 変数 , 型 , マクロをそれぞれ参照 れ , トータルて、は C010r35 個 , BuiId7 個 , そ 298 個におよんている。そのほかにも , 添付 のほか 59 個 , 合計 101 個に達する。マイクロ している関数のコールドバイリスト , ユ された PWB 拡張サンプルプログラムだけて、 ーズドバイリストの生成表示 ソフトエデイタの 36 個のスイッチ群と比較 基本機能 21 種類が含まれ ,PWB のメニュー ◇ファイル名を指定して , 関数呼び出しの すれば , いかに大幅な改善が施されたか理 コマンドにはそれとは異なるオリジナルコ コールツリーの生成表示 解て、きよう。 マンドも含まれているのてある。 デフォルトて、指定されているプログラマ ◇ファイル名を指定して , プロジェクトの さらに今回のバージョンアップて、は大幅 ズエデイタのキーアサインメントはセッシ 関数 , 変数 , 型 , マクロのアウトライン なスイッチ群の強化も施された。とくにカ ョンなぎりて、も , セープして繰り返しても , の生成表示 ラー指定スイッチとコンパイル , プロジェ 再設定て、きるばかりて、なく , マクロにも , クトビルド指定スイッチが分離独立し , そ ーたタベース化可能な PWB 拡張にもキーアサインすることが可能 れぞれ Color スイッチ , Build スイッチとな 、ラインヘルプ だ。サンプルとして添付されている PWB 拡 Fig. 4 M ES ライクにセットした PWB 張プログラムて、はワードスターライクなマ MS-DOS, MS OS/2 のいすれの環境下 ルチシフトを実現する方法まて、もが示され にい、・い物い第 : いー て、も PWB て、は , オンラインヘルプ ( マイク ている。 QuickC のユーザはデフォルト仕様 ロソフト C アドバイザ ) が利用て、きる。この のままて、 PWB を使うことがて、きる。 オンラインヘルプはきわめて使い勝手がよ 発プログラムのテー く , MS-CVer. 6.0 の詳細な言語仕様 , ラ ロ ースとソースプラウサ イプラリ , PWB 機能などがハイバーリンク 形式て、連鎖され , PWB と CodeView のいす れの場面からも高速検索が可能なばかりて、 PWB には開発中のプログラムを構造解析 1 0 0 をま : 2 : : しこ E に : に式朝こしリ茨 44 CMAGAZINE 19 12

2. 月刊 C MAGAZINE 1990年12月号

て、き , マクロとしての機能も兼ね備えてい マクロの登録は , まず Edit メニューをマウ スて、クリックする。現れた < SetRecord … > 項目を再度クリックし , マクロ名を登録す る。 < Set Record > コマンドはマクロを登録 し , マクロ名およびショートカットキーを 定義することがて、きる (Fig. 13 ) 。 CIearFirst を選択しないと , PWB はすて、 に存在するマクロに新しいコマンドを追加 する。自動的にショートカットキーを割り 当てるには , カーソルを { } の中に位置さ せ , マクロに割り当てる実際のキー ( または キーの組み合わせ ) を押す。正しくキーが割 り当てられると , 押したキーの名前が角カ ッコ ( [ ] ) 内に表示される。たとえば CTRL 十 f ・ 6 を割り当てるには , ーキーと f ・ 6 キーを同時に押す。もし , 認められたら CTRL および f ・ 6 が角カッコ内に CCTRL 十 f ・ 6 ] 表示される。これて、 , マクロ名が登録され た。今度はこのマクロに実際の操作を登録 する。 < Record On > コマンドを使うとマクロ 登録が可能になる。実際にマクロを登録す るには < Record On > を選択し , 登録した い操作をエデイタ中て、行う。く RecordOn > をマウスて、クリックすると , マクロ登録可 能状態になるが , そのときの目印としてス テータスラインに X が表示される。したがっ て , X が表示されているときはマクロの登録 中と思ってまずまちがいない。 < RecordOn > をもう一度選択すると登録が終了する。っ まり , 終了とともにステータスラインの X も 消え , マクロの登録が完全に終了した を知らせてくれる。 マクロ登録中にはヘルプ関数とマクロを 呼び出せない点は注意すべきて、ある。さら に , Record 関数はマウスをクリックしたた めに生じるカーソル位置の変化は登録しな ことも知っておく必要がある。マクロに カーソルの動きを含めたいときは , キーボー ドを使うことて、ある。そうすればカーソル 70 CMAGAZINE 19N 12 の動きを登録て、きる。 マクロがすて、に定義されているときは , 新しいコマンドがそのマクロに追加される。 マクロ定義を完全に置き換えるには , Set Macro Record ダイアログボックス内の Clear 環境変数の取り扱い First を使用する。 ELPFILES 環境変数 から , HELPFILES 変数て、設定されたディ カレントディレクトリを最初にサーチして QuickHELP も同様て、ある。サーチルールは 定するために必要な環境変数て、ある。また , されたが , そのドキュメントファイルを指 PWB には , オンラインヘルプがサポート なる。 トリの次に INIT 変数のパスを調べることに 変数が登録されていればカレントディレク ルじ、 する。存在しなければそれまて、だが , INIT リを調べ ,TOOLS. INI ファイルの存在を確 PWB は起ち上げられたカレントディレクト もし , INIT 変数が設定されていなければ INIT 変数が必要になる。 ファイルの存在を PWB に知らせるために ど説明する。この起ち上げ時に TOOLS. INI TOOLS. INI ファイルの詳細については後ほ INI ファイルを読み込むようになっている。 PWB のデフォルト起ち上げて、は , TOOLS. 江環境変数 にとって必要というわけて、はない ァイルて、ある。ただ , TEMP はとくに PWB あくまて、も PWB を使用するために必要なフ もいくつか設定する必要があるが , これは 6.0 にとって必要な環境変数は , これ以外に STS ファイルのふたって、ある。 MS—CVer. を記述してある TOOLS. INI と CURRENT. HELPFILES, TEMP の 3 っとシステム情報 PWB にとって必要な環境変数は INIT , レクトリをサーチする。 TEMP 環境変数 TOOLS コファイル 起動時には TOOLS. INI とともにこの CUR などの情報が格納される。しかも , PWB の えば , 使用したファイルやカーソルの位置 RENT. STS ファイルに書き込まれる。たと PWB の終「時に作業環境情報が CUR LJ 日 RENT. STS ファイル はめている。 リネームして使用するようにマニュアルて、 後はこのファイルを TOOLS. INI ファイルに ファイルが提供されており , インストール ない。ただ , デフォルトとして TOOLS. PRE したときには TOOLS. INI ファイルは存在し ちなみに MS-C Ver. 6.0 をインストール ないファイルて、あるといえるだろう。 映される。カスタマイズにはなくてはなら ときに TOOLS. INI ファイルにもすぐさま反 み込んて、おり , また変史があれば SAVE する 起ちにげのたびに TOOLS. INI ファイルを読 ールについて記述する必要がある。 PWB は なくとも MS—CVer. 6.0 のすべてのモジュ ファイルはそれほどのものて、はないが , 少 をどこかに記述する必要がある。 TOOLS. INI るためにもなんらかのシステム関連の情報 て、きるため , すべてのモジュールを管理す のすべてを PWB から一度に使用することが ろなモジュールがサポートされている。そ MS-C Ver. 6.0 には , PWB を含めいろい 題なさそうて、ある。 ないだろう。 TEMP 環境変数は TMP て、も間 ンボラリディレクトリとして使わない手は プなどを使用している場合には , それをテ くなるというものて、はないが , 仮想ドライ 数は指定しなくてもとくに PWB が稼働しな プのディレクトリを使用する。この環境変 用するために , TEMP て、設定されたドライ PWB は一時的なテンボラリファイルを使

3. 月刊 C MAGAZINE 1990年12月号

TabIe 1 暗黙の型変換 ホインタ型 long double double float unsigned long long unsigned int int unsigned short short unsigned Char Char 実引数の型 Fig. 4 実引数のスタックへの積まれ方 ( 可変引数 ) 関数に渡される型 unsigned int ポインタ型 long double double double unsigned long long unsigned int int unsigned int int int スタック 関数 g の リターンアドレス (long 型 ) 3.8 (float 型 ) (int 型 ) (dou b 厄型 ) 5L (long 型 ) Char int int 型で計算し long 型へキャスト g ( i 十 3 , d 十 1.5 , float double d = 2.3 : doub 厄型にキャスト int 型にキャスト doub 厄型で計算し float 型へキャスト f, 5L); void g い ong a, float b, とプロトタイプ宣言された関数があり , float double d= 2.3 ; int Char の関数 g を呼ぶところて、 , そ 関数のマクロ定義 可変引数を扱う関数は , すべてマクロて、 可変引数 #define MAXBUF 128 えば , 号定数の定義がほとんどて、したね。たと 今まて、本講座て、扱ったマクロといえば記 簡単にマクロの説明をしておきましよう。 の操作にはマクロの知識が必要になります。 定義されています。したがって , る数の 2 乗を計算する引数つきマクロ squa 「 e っきマクロを定義て、きます。たとえば , あ たね。この # define の置換機能を用いて引数 のようにして , 記号定数を定義してきまし Y square(5.5) ; なります。そこて、 , これて、 , 目的のマクロが定義されたことに #define square(x) (x) * (x) を定義してみましよう。 Y #define square(x) x*x 口を 意しなければなりません。もし上記のマク マクロを用いるうえて、カッコの使い方を注 ( 5.5 ) * ( 5.5 ) ; て次のように展開されます。 と書くと , この文はプリプロセッサによっ と定義したらどうなるて、しようか。たとえ ば , squa 「 e ( 1.5 十 3.6 ) : Y Y としても , 以下の場合はどうなるて、しよう ばなりません。正しくカッコを用いていた た , インクリメントなどにも注意しなけれ これて、は , 2 乗が正しく求まりませんね。ま 1.5 十 3.6 * 1 .5 十 3.6 ; ます。 とすると , 以下のように展開されてしまい と宣言されている変数があったとします。 このとき , 以下のように実引数を与えたと します。 g( i 十 3 , d 十 1.5 , c, f, 5L ) ; このとき , スタックは Fig. 4 のようになり ます。第 5 実引数の 5L は long 型のままスタッ クにブッシュされます。第 4 実引数の f は float 型なのて、暗黙の型変換に従い doub 型にキ ャストされてからスタックにブッシュされ ます。 同様にして第 3 実引数の c は char 型なの て、 , int 型にキャストされてからスタックに ブッシュされます。第 2 実引数の d 十 1.5 は doub 型て、すが , この部分は仮引数の型 (float 型 ) にキャストされてからスタックにプ ッシュされます。第 1 実引数 i 十 3 は int 型て、す が , 仮引数の型に従って long 型にキャスト されてからブッシュされます。そして , 最 19 12 後に関数 g のリターンアドレスがブッシュさ 120 CMAGAZINE れます。 これは , す。 Y square(x 十十 ) ; 以下のように展開されてしまいま これて、は , y の値も正しく求まりませんし , x も 2 回インクリメントされてしまいます。 したがって , 引数の形式も関数のように自 由にとはいきません。しかし , マクロの効 用はそれにもまして大きいのて、す。マクロ て、は , どんなデータ型て、もひとつのマクロ て、代用て、きます。関数のように型が違うと , いちいち別の関数を作り直す必要もありま せん (List 5 参照 ) 。また , マクロは関数て、は ないのて、 ( たんに置換しているにすぎない ) , 頻繁に呼び出される関数をマクロて、記述す ることがて、きれば , 関数呼び出しの実行時

4. 月刊 C MAGAZINE 1990年12月号

MS-C ド ルのプロフェッショナルプログラマ要求ま て、 , 柔軟に対応て、きる。 このフレキシビリティに富んだ PWB のカ スタマイズは , オープンアーキテクチャの 採用によるところが大きい。オープンアー キテクチャの採用により , ユーザは独自の ヘルプデータベースの追加や , PWB 拡張の 追加が可能となっている。くわえて , マク ロや多数のスイッチ群が用意されている点 もカスタマイズの幅を広げる要因て、ある。 キーポードアサインメントについても同様 だ。また , PWB には新たなユーザメニュー を追加するというカスタマイズ手段が用意 されている点も特長として挙げられよう。 Fig. 1 MS-C Ver. 6.0 開発環境 そのほかのツール Microsoft Programmer's WorkBench アドバイサ ヘルプファイル MAKE テパッガ CV3.0 工デイタ ユーサによる 機能拡張 ソースプラウザ C6.0 MASM 機能強化された プログラマズエテイタ 三ロ PWB には専用のマルチファイル , マルチ ウインドウ型のヒストリー機能をもったプ た各種機能群のほとんどがマクロ記述能力 ほかのビルドを行い , 結果を View メニュー ログラマズエデイタが組み込まれている。 を備えているため , 使い慣れるとカスタマ コマンドて、確認し , Browse メニューて、間題 イジングの格好の手段となるばかりか , 新 このエデイタは , その前身て、あるマイクロ 箇所のリファレンスが得られる。さらにデ たに装備された Record 機能によって , 簡単 ソフトエデイタを大幅に機能強化したもの バッグ段階て、も , 同じく PWB 上 <CodeView て、 , 基本的にはアップワードコンパチプル にキー操作を記録し , これをマクロとして を起動しプログラムを実行追跡することが だ。 PWB にプログラマズエデイタがインテ セープ使用する道も開けた。 可能なのだ。 グレートされた結果 , ソースコードエディ プログラマズエデイタて、は新たにマウス このプログラマズエデイタには Record 機 ット前後の作業はきわめて便利になった。 の使用が可能となっている ( もちろん , PWB 能を兼ね備えた強力なマクロ機能が装備さ PWB I•て、コンパイル , アセンプル , その 全域て、のマウス使用が可能て、ある ) 。カーソ れている。 Ver. 5 . 1 と比べ大幅に強化され Fig. 2 QuickC ライクにセットした PWB Fig. 3 マイクロソフトエテイタライクにセットした PWB 33 「 ch ー ke Run Op い ( ) 応 Split 「に ont 引 Split 「ー ・ Ct 「い F8 Size Ⅲ国 ー幻面 ze Ⅲ 04 Ct 「い日 9 Ctrl+F4 ロ 0 ? Ⅲ 4 Coupi RnJlts V ・「 5i0 2 OjEt = ー 0 fS 「 0 「 01 = 0 第 ⅲ t ⅵ 7 2 1 部 ー L を第 D : 1 し u 使 凵 0 : : 鉢し旧 モ L ー D : 6*ELP . 0 File Edit D:ü*IN!T*CLFFENT. STS V 「 5 i on = 2 0 「 Oj を ct ゞ” ild 『き印 5 「 0 fS 「 0 を 4 S 「 0 = V 「 fSr 5 「 0 = fRplRe=ø ⅲてⅵ = 7 W24 2 ! 24 i 「 on ] IFCLUtE=D:ü*ItCLUDE L = D : 6 軋旧 モ F ! S = D : 軋詳モ . HLP ttuild) bJild: 0 「 0 : ミョ」 3 ” 3 ” [édit-2 0 0 lj: しⅵⅢ T れ」トに STS V 「 5i0 「 2 proj き 0 て = ”” bu ⅱき 4 fS 「 0 4 5 「 0 = f 印 [ 部 it-2 【ⅱ d ] bJiId: 20 「 0 工” 9 ・ bJiId: 20 「 0 ・ 0 b 「 %k ・” + 酊 Ch for Nb lt ・ ー込一石 . に ilt け対 ( トめ「 izonta いリ at ロ ) 「 特集 MS-C Ver. 6.0 研究 43

5. 月刊 C MAGAZINE 1990年12月号

五ロ はしめて学ぶプロクラー ニンク めします。 ック上のアドレスを int 型て、アクセスするこ とになります (Fig. 6 参照 )0List 6 のように 定義されている処理系て、はプリプロセッサ va ー a 「 g の補足説明 によって List 8 の②のように展開されます。 int va a 「 g はマクロて、実現されているのて、使 List 8 の②を見るとわかると思いますが , long 用するときに注意しなけらばならない va pt 「を int * 型 ( int 型のポインタ ) にキャス float があります。関数マクロ va arg を使ってス トし , それを間接演算子 * 〃を用いてそ double タック上の実引数にアクセスすると同時に の内容を参照するようにしています。つま Char ポインタがインクリメントされ , 次のポイ り , va pt 「が指すアドレスの内容を int 型て、 ( 文字列 ) ンタを指すようになります。したがって , 読み出し , それを su m に加算しているのて スタック上の実引数には基本的に 1 回しかア す。そして , アクセスした後には va ptr を int 関数の戻り値は入力した項目数とします。 クセスて、きません。もう一度スタック上の 型の大きさて、インクリメントすることによ 上記の場合て、は 3 が返ってきます。フォーマ 実引数にアクセスしたいときには , 関数マ り va pt 「がスタック上の次の実引数を指すよ ット文字列が正しくない場合は EOF を返す クロ va sta 「 t を呼んて、ポインタを初期化する うになるのてす 0List 7 ては num 回ループを ことにします。また , 関数 scanf のように変 必要があります。 繰り返すことによって sum に総和が求まりま 今まて、スタック上の実引数の読み出しの 換に成功したかどうかの判断はしていませ す。 み説明してきましたが , va a 「 g は関数て、は ん。各入力は空白文字 ( ここて、はスペース , ( 4 ) ポインタの後始末 なくマクロなのて , va a 「 g を代入式の左辺 タブ , 改行 ) て区切ることにします。空白文 字はいくらあってもよいことにします ( 空白 に書いてスタック上の実引数の値を書き換 スタック上の実引数にアクセスした後 , えることもてきます。 文字は読み飛ばす ) 。 アクセスに使ってきた va ⅱ st 型の変数を関数 マクロ va end を使って後始末します。関数 マクロは引数がひとって va ⅱ st 型の変数を引 使用している標準関数の説明 数にします。 27 行目のように このプログラムに使われている関数のう va end( va ptr ) : 最後に可変引数の代表的な例てある scanf ち , 今まて、の講座て、まだ説明していなかっ のようにして , va pt 「を後始末するのてす。 をまねた簡易 scanf を作ってみましよう。関 た関数の説明をします。 List 6 のように定義された処理系てはプリプ 数名は pscanf とします。 関数 atoi ロセッサによって以下のように展開されま [ インクルードファイル ] stdio. h す。 [ 書式 ] ( (void)( va pt 「 NULL ) ) ; 関数 pscanf の仕様 この例を見ればわかるように , この関数マ [ 機能 ] 関数 pscanf は関数 scanf のように第 1 引数 クロは va pt 「にヌルポインタを代入してい 文字列 s を int 型に変換して返します。 がフォーマット文字列て , その次にそれぞ るにすぎません。このマクロは処理系によ れのフォーマットに対応したポインタを並 関数 atol って処理に差があります。たとえば , この [ インクルードファイル ] stdio. h べることにします。ここては , プログラム 関数マクロを呼び出しても何の操作もしな [ 書式 ] を簡略化するために % 〃を使わずに 1 文字 いといった処理系もあります。したがって , long atOl( const char *s ) ; てフォーマットを表すようにします。フォ 関数マクロ va end を使わなくても実際には [ 機能 ] ーマット文字列は Table 2 のようにします。 支障ありません。しかし , 関数マクロ va start 文字列 s を long 型に変換して返します。 以下にその例を挙げます。 から可変引数のアクセスが始まり , 関数マ cha 「 s [ 128 ] ; 関数 atof クロ va end まて可変引数のアクセスが行わ [ インクルードファイル ] stdio. h れるという範囲が明確になります。プログ [ 書式 ] ラムがわかりやすくなるということから関 double atof( const char * s ) ; 数マクロ va end もきちんと使うことをお勧 はじめて学ぶ C プログラミング 123 TabIe 2 関数 pscanf のフォーマット文字 フォーマット文字 型 Char int atOi( const char *s ) ; double d ; s, pscanf("sid' ,

6. 月刊 C MAGAZINE 1990年12月号

五ロ はしめて学ぶプロクラミンク のオーバヘッドを避けることがて、きます。 stda 「 g. h のインクルード 可変引数の関数を作るには , まず stdarg. h をインクルードする必要があります ostdarg. h は可変引数の関数を作るためのマクロが定 義されているヘッダファイルて、す。 の部分の実引数の操作はこのヘッダ内のマ クロを使って行うことがて、きます。ちなみ に stdarg. h は , STanDard ARGument Header を意味しています。 可変引数へのアクセス 〃の部分の実引数にアクセスする には , stdarg. h て、定義されている関数マクロ を使います。関数マクロには , va start,va arg,va end が定義されています。さらに れらのマクロて、用いる引数へのポインタを 宀言するための型 va list も定義してありま す。これらのマクロにはいろいろな定義の 仕方がありますが , ひとつの定義例を List 6 に示しておきます。もしお使いのコンパイ ラが ANSI C 準拠て、はなく , stdarg. h がな い場合は List 6 を参考にして stdarg. h を自分 て、作ってください それて、は , 順を追って可変引数へのアク こては , セスを説明していきましよう。 不定個の int 型の足し算をする関数 iadd を作 ります。第 1 引数に足し算する要素数を指定 し , その後に実際の足し算の要素を並べる ことにします。以下 List 7 を中心に参照しな がら読み進んてください ( 1 ) 引数へのポインタ宣言 まず , スタック上にある実引数にアクセ スするためのポインタを宣言します。実引 数ヘアクセスするためには va list 型を使いま す。 va list 型は stdarg. h の中 <List 6 の typedef VOid *va list : のように宣言されています。あるいは , はじめて学ぶ c プログラミング 121 ある数の 2 乗を計算する関数マクロ squa 「 e の例 List 5 1 : #include く stdio. h 〉 2 : 3 : #define square( x ) ( x ) * ( x ) 4 : 5 : vo i d ma i n ( vo i d ) 7 : i nt X : 8 : double y; 9 : pri ntf ( " I nput I nteger X = scanf( ” Xd", &x ) : 12 : printf("lnput Double Y = scanf("%lf" printf()X * X = %dYn" printf()Y * Y = XlfYn" 18 : } square( x ) ) : square( y ) ) : 可変引数へのアクセスのためのマクロ例 List 6 1 : typedef void *va-l ist; 2 : 3 : #define va_start(ap, parmN) 4 : #define va_arg(ap, type) 5 : #define va_end(ap) (va-l ist)&parmN 十 sizeof(parmN))) ((void)(ap = NU しい) 不定個の int 型の足し算をする関数 iadd の例 List 7 ワ 0 / 、 ん′ 0 0 > っ 0 っ 0 っ 0 っ 0 . 、′っ 0 っ朝り朝っ 0 0. cd / 、十 0 、ー 4 1 よ 1 よ・ー 4 本し十レ 十レ十》十レ本し ・ 0 十し一 0 0 11 っ朝っ 0 -4 ロ 0 6 7 8 9 0 1 0 乙っ 0 4 0 ^ 0 ー 8 0 1 ・・つ 0 00 -4 - -0 ー 8 0 1 よ 1 , 1 1 ー 1 よ 1 よ 1 よ 1 ・・ 1 11 っ 0 つなワっ 0 っ 0 っ 0 つなっ 0 ワ 0 っ 0 っ 0 / * 可変引数の関数プロトタイプ宣言 * / / * 可変引数の関数定義部 * / / * ポインタの宣言 * / / * ポインタの初期化 * / / * 引数へのアクセス * / / * ポインタの後始末 * /

7. 月刊 C MAGAZINE 1990年12月号

特集 MS-C 旧い 新機能インラインアセンプラ のメリット 高村誠之 Tu 「 bO C, QuickC なとに加えて , いよいよ MS - C Ve 「 . 6.0 てもインラインアセンプルか可能になった。ここては , イ ンラインアセンプル機能の使い方を簡単に説明したうえて , その利占注意点を述べる。 asm int もしくは , 21h まじめに い部分だけを最適化したりすることがて、き とくに高速化した 言語て、関数を書いたり , などのアセンプラは必要ない ) , アセンプリ 異なる。またコンパイルに MASM,TASM パチプルて、 ( Turbo C のそれとは少し文法が MS ー C に実装されたものは QuickC とコン がて、きるようになった。 からインラインアセンプル機能を使うこと センカレが可能て、あったが , MS ー C も Ver. 6.0 Turbo C,QuickC などて、はインラインア とをいう。 ソースの中に直接アセンプリ言語を書くこ インラインアセンプラとは , 咼級言語の asm C の文の使えるところにおいて , インラインアセンプラを使用するときは , ごくごく簡単に文法の説明をしよう の文法 ンラインアセンプラ る場合は , とになる。アセンプリ言語が複数行にわた の .. …の部分にアセンプリ言語を記述するこ asm mov ah, 01h のように続けて書くか , asm { mov ah, 01h int 21h 擬似命令は使えないが , C プリプロセッサの 行うマクロ展開は適用て、きる。その際 , マ クロは 1 行に展開されることに注意すべき #define beepmacro \ だ。すなわち , のようにプレース、、 { ドて、くくって記述する。 80286 , 80287 のインストラクションも , / G2 オプションをつけてコンパイルすれば使用 可能て、ある ( 80386 専用の命令は使えない ) 。 asm 文の中て、使える擬似命令に emit と いうものがある。これは , TurboPascal の in ⅱ ne 文に似ており , emit に続く 1 バイトを コードの中に直接埋め込むものて、ある。 これを使えば 80386 の命令も書くことがて、 きる。 コメントは , C のように / * と * / て、くくっ ても , または新しく MS-C Ver. 6.0 から可 能になったコメントの先頭にソ / 〃 ( スラッ シュふたっ , 行末まて有効 ) ても , もともと asm asm asm mov ah, 02h mov dl, 07h int 21h のようなマクロは間題ないが , 次のような マクロを書くとエラーとなる。 #define beepmac 「 0 mov ah, 02h \ mov dl, 07h \ asm { \ int 21h #define beep and set val(val) たとえば , 用して書くときも , この点を念頭におき , マクロの中て、アセンプリ言語と C 言語を混 の MASM< のように も , かまわない asm { / * コメント 〃注釈 Remark 〃 ( セミコロン ) て、 asm asm asm val = 0 ; mov ah, 02h mov 引 , 07h int 幻 h } MS-C Ver. 6.0 のインラインアセンプラ はマクロアセンプラて、はないため , macro } を使わなければならない のように - やクク また , その行の終わりまて影響をおよば すコメント C げやソ / つをマクロの中て、 使うときも , とくに注意が必要てある ( / * ・ * / を使えば大丈夫てはあるが ) 。 定数は , MASM て、使えるものはほとんど 特集 MS-C Ven 6.0 研究 59

8. 月刊 C MAGAZINE 1990年12月号

typedef char *va list : のように宣言されている処理系もあります。 この va list 型を用いて va list va ptr ・ とし , スタック上の実引数を指すためのポ インタを宣言します ( 20 行目 ) 。このとき va list はもともとがポインタなのて、宣言のとき * 〃をつけないように注意してください ( 2 ) ポインタの初期化 次に , 関数マクロ va start を使い可変引数 の先頭の引数を指すようにポインタを初期 化します。 va start はふたつの引数をもちま va start( va ptr, num ) ; のように 前 ( 左側 ) の仮引数名を指定します。 22 行目 ポインタ型 ) て、 , 第 2 引数には、、 す。第 1 引数は , va list 型の変数 ()a list 型は 〃の直 す。この操作によって , va ptr はスタック上 の次のスタックのアドレスを指し示すのて、 代入されます。つまり ,va pt 「は第 1 引数 num の大きさ ( バイト数 ) を加算した値が va ptr に アドレスを va ⅱ st 型にキャストした値と n u m れます。これを見るとスタック上の num の ロセッサによって List 8 の①のように展開さ 6 のように定義されている処理系て、はプリプ が va pt 「に代入されます (Fig. 5 参照 ) 。 List ック E の可変引数の先頭ポインタ ( アドレス ) 積まれている次のポインタ , つまり , スタ とすることによって , スタック上て、 num が 〃の部分の先頭を指し示すように 122 CMAGAZINE 19 12 とすることにより , va pt 「が指しているスタ sum 十 = va arg( va ptr, int ) ; 引数の型を指定します。 25 行目て、 , にはこれからアクセスするスタック上の実 1 引数は va ⅱ st 型の ( ポインタ ) 変数 , 第 2 引数 ロ va arg は , ふたつの引数をもちます。第 の可変引数にアクセスて、きます。関数マク 関数マクロ va arg を用いて , スタック上 ( 3 ) 可変引数へのアクセス 初期化されたことになります。 Fig. 5 関数マクロ va ー sta の動作 関数 iadd の呼び出し側 iadd ( 3 , 1 , 関数 iadd 側 iadd(int num, ()a 」 ist)&num 十 sizeof(num) アドレス スタック 関数 iadd の リターンアドレス 低 va—ptr アドレス 高 3 1 2 3 使用中のスタック領域 List 8 ( (void) sum 展開後の様子 va_ptr (va-l ist)&num 十 sizeof( num ) ) ) : Fig. 6 2 , 2 , 3 ) ; 3 ) ; 関数マクロ va ー a 「 g の動作 va—arg (va—ptr, int) iadd ( 3 , アドレス 低 関数 iadd の スタック 1 , ②十十 [ インクリメント ] va—ptr ( 次の実引数を指す ) ①参照 リターンアトレス 3 1 2 3 アドレス使用中のスタック領域

9. 月刊 C MAGAZINE 1990年12月号

0 く例〉 colo 「 2 ( 5 , Reverse) ; / * 水色反転 * / Dconsole VOid Dconsole(int ax, int (x) ; テキスト画面制御ライプラリ各マクロの 下位の関数て、す。 AH レジスタに ax の下位 8 ビット , DX レジスタに dx, CL レジスタに Ox10 を代入して PC ー 9801 用 MS ー DOS の拡張 機能呼び出し ( 直接コンソール出力 ) をコー ルします。 Turbo C の場合 , レジスタ疑似変数を使 用するコンパクトなものとなります。 disp VOid disp(int x, int y, int CO し char *string) ; 座標 ( x , y ) の位置から文字列 st 「 ing を col て、示される色・属性て表示します。 く例〉 disp(), 7 , White, ' 文字列表示 ' ) ; dput VOid dput(int x, int y, char *string); 座標 ( x , y ) の位置から文字列 st 「 ing を表示 します。 く例〉 disp(), 7 , " 文字列表示 ' ) ; く注意 > 同じ色て、の表示が連続する場合 , 1 , Red, ' 表示 1 " ) ; disp(l, disp(), 2 , Red, 表示 2 " ) ; とするよりも , coIor(Red) ; 1 , ' 表示 1 " ) ; dput(l, dput(), 2 , " 表示 2 " ) ; のほうが効率のよいコンパクトなコードを 生成します。 kanJi VOid kanji(int (w) ; 0X81 ~ 0x9F および 0xE0 ~ 0xFC の文字を シフト JIS コード ( 2 バイト文字 ) の 1 バイト目 として扱うか ()w = 1 のとき ) , グラフ文字と して扱うか ( sw = 3 のとき ) のモードの指定を 行います。 locate 130 CMAGAZINE 19 12 6 : 7 : #if !defined(__LIB-PC9801_DEF_) 8 : #define ーい B_PC9801_DEF- 9 : ーライプラリ関数プロトタイプー 10 : / * ー 12 : extern void DconsoIe(int ax, int (x) : 13 : extern void putstr(char *string) : 14 : ー DconsoIe を呼び出すマクロ -Dcons01e(0x00, ch) 16 : #define putchr(ch) 17 : #define color (atr) -DconsoIe(0x02, atr) -Dconsole(0x03, ((y) くく 8 ) + (x) ) 18 : #define locate(x,y) Dcons01e(0x0A, sw) 19 : #define _cls(sw) 20 : #define clrline(sw) Dcons01e(0x0B, sw) 21 : #define kanji (sw) -DconsoIe(0x0E, sw) 22 : 23 : / * -Dconso 1 e を呼び出すマクロ ( を呼び出すマクロ ) 24 : #define cls ー c 1 s ② 25 : #define C010r1 (c) c 引 or ( ( (c) くく 5 ) + 1 ) 26 : #define C010r2 ( c , a) color(((c) くく 5 ) ー (a)) 28 : / * ー ーさらに便利なマクロ (putchr ()h くく 8 ) , putchr()h & OXFF)) 29 : #define putkchr(ch) (locate(x,y) , cls(0)) 30 : #define clreos(), y) color (c) 31 : #define disp(x,y,c,str) (locate(x,y) putstr(str)) 32 : #define dput(), y, str) (locate(x, y) putstr(str) ) 33 : 34 : / * ー ー c 引 or ( ) のための定数 35 : #define Black 0X01 36 : #define Blue 0X21 37 : #define Red 0X41 38 : #define Magenta 0X61 0X81 39 : #define Green 40 : #define Cyan 0xAl 41 : #define Yellow 0xC1 42 : #define White 0xE1 43 : 44 : #define Blink 0X02 45 : #define Reverse 0X04 46 : #def i ne 旧 i ne 0X08 47 : #define Vline 0X10 48 : 49 : #endif 滅転線線 ~ 黒青赤紫緑水黄白点反下縦 void locate(int x, int y) ; カーソルの位置を座標 ( x , y ) に設定しま す。座標は画面左上が ( 0 , 0 ) て、す。 putchr void putch 「 (int ch) 文字 ch を表示します。 putstr VOid putstr(char *string) 文字列 st 「 ing を表示します。 さて今回は大部分をマクロて、作成しまし たが , すべての機能を作成したわけて、はあ りません。 PC ー 9801 版 MS ー DOS のマニュア ルを研究して , 自分て、機能を追加してみて ください / プログラムの変更 10 月号て、添削・改良したプログラムを , 前回および今回作成したライプラリ ( メモリ アクセスおよびテキスト画面制御 ) を使うよ うに変更したプログラ、ムを付録ディスクに MODIFIED ℃として収録しています。ま た , 前号をおもちてない方のために , 前回 作成したメモリアクセスライプラリも再録 しています。 キャラクタを自由に動かす 佐伯さんの目標は , ちょっとしたゲーム

10. 月刊 C MAGAZINE 1990年12月号

Fig . 1 0 Fig . 1 1 Options メニュー Options Menu く Environment. く Key Assignments. く Editor Settings... 〉 く Build Options... 〉 く CodeView Options... 〉 ( OS / 2 ) く C0deView Options …〉 (DOS) く NMAKE Options... 〉 く LINK Options... 〉 く C Compiler Options... 〉 く Browse Options... 〉 PWB 環境変数を設定します キーにコマンドを割り当てます 工テイタスイッチを変更します b ⅶ d プロセスを設定します PWB Source B 「 owse 「テータベースを設定 します。 C コンノヾイラオプションを設定します 凵 NK のコマンドラインを設定します CodeView オプションを設定します CodeView オプションを設定します NMAKE のコマンドラインを設定します MS-C ド Browse lnformation を選択する に , ダイアログボックスの Generate Browser データベースを作成するため Options... > を選ぶ。そして , Source ジェクト用に設定されているかぎり , プロ 用て、きる。 Browse オプションが現在のプロ 終えると <BrowseMenu> のコマンドが使 相違がある。いすれにしても以上の処理を ースプラウザ情報を定義するときは若干の PWB 用て、ない外部のメイクファイルてツ てプログラムを構築する 2 . 次に < Make Menu > コマンドを使っ Browse メニュー Browse Menu く GotO Definition... 〉 く Goto Reference... 〉 く View ReIationship... 〉 く List References... 〉 く C 訓 Tree... 〉 く Out ⅱ ne... 〉 く Next 〉 く Previous 〉 く Case Sensitive 〉 く Split Window 〉 シンホルの定義を検索します シンホルのリファレンスを検索します シンボルの関係を表示します 変数のリファレンスをリストします プログラム呼び出しツリーを表示します プログラムアウトラインを表示します 次の定義かリファレンスに進みます 前の定義かリファレンスに戻ります シンボルの検索で大文字と小文字を区別します フ、ラウザウインドウに画面を分割します などの関係を調べ , なおかつ一覧て、きるこ とて、ある。 Browse メニュ—(Fig. 11 ) のコマンドはま とめて PWB ソースプラウザと呼ばれてお り , これらのコマンドて、選択したファイル を構成するデータベースを検索し , 定義リ ストや参照リストを得ることがて、きる。ま た , 呼び出しツリーとアウトラインのビル ド , プログラムシンボル間の関係リストも作 成することがて、きる。このコマンドを使う 前に , ソースプラウザが検索するデータベ ースを定義する必要がある。データベース 定義は次のとおりて、ある。 1. Options メニューから <Browse Set Macro Record Fig . 13 マクロの登録 グラムを構築し直すたびにソースプラウザ データベースは自動更新される。ソースプ ラウザは . SBR と . BSC のふたつのファイル を利用するが , いったんデータベースが構 築されると , . SBR ファイルの内容は不要に なる。 プログラマは必要に応じてオンラインへ ルプを表示させることがて、きる。そのため には Help メニュ—(Fig. 12 ) をマウスて、クリ ックするだけて、よい マクロの機能 PWB はマイクロソフト社のエデイタ M. EXE をかなり改良したものて、 , プログラマ がかなりのキー操作を改良することがてき る。そのひとつにキーバインディングがあ る。これは , 慣れ親しんだ工デイタソフト にそっくり似たようなキー割り当てにする ことがて、きる。しかもこのキーバインディ ングはキー割り当て以上に拡張することが Fig. 12 Help メニュー HeIp Menu <lndex 〉 く Contents 〉 く Topic 〉 く Help on HeIp 〉 く Next 〉 トピックのアルファベット順リスト 目次 カーソル位置の単語のヘルプトピック ヘルプシステムの使い方のヘルプ 次のヘルプトピック Key Assignment: { } [ # # # # # # ] [ ] CIear First マクロ名を入力します マクロに割り当てるキーを押します CIea 「 Fi 「 st を選択し , 同じ名前のマ クロを削除します 特集 MS-C ver• 6.0 研究 69