ライフホート 0 「 m 面 on from (ompiler Ma 「 5 Lattice C LatticeC にはいくつかのユーテ パイルなどが避けられます。オプ るファイルの拡張子 , コロン記号 ィリティが付属しています。今回 ションは Table 2 のようになってい [ 例 ] 〇 ( : ) , 次行に生成方法を記述する sample. exe : sample.obj と次回の 2 回にわたって , この使い ます。 ことにより , 拡張子によって生成 ℃ -L sample. Obj 方について説明します。 以下に make ファイルの記述法を 方法のデフォルトを設定てきます。 sample. Obj : sample. c 簡単に示します。 に sample. c ① di 幵 . exe 最終目的は sample. exe を作るこ [ 例 ] . c. obj : ( 1 ) ターケットソース SYNOPSIS ℃ -cus -mds $ * となのて、 , そのために ,sample. obj diff Coptions] new file 行の先頭に生成されるターゲッ を作ります。 sample.obj : sample. c トファイルを記述し , コロン記号 0 file samp 2.0 切 : sample2. c ( : ) て、区切って , その元となるフ 0 f ⅱ e て、指定したテキストファ [ 例 ] >< sample. obj : sampIe2. h extrn. h イルを new f ⅱ e て、指定されたテキス ァイル名 ( ソースファイル ) を記述 sample3.0 切 : samp 巵 3.0 切 ℃ sample. c トファイルに変更するには , どの します。コロンの後には , スペー sample. exe : sample. Obj sampIe3. h extrn. h スを入れる必要があります。 行を書き換えればよいかという形 この場合 , sample. obj などは , lc ℃ー L sample. Obj 式て、 , 相違点を表示します。 その次の行に , 先頭にスペース 最終目的は sample. obj を作るこ -cus -mds sample のように処理さ 出力は標準出力て、すから , リダ を入れて , ターゲットファイルの とになるのて、 , sample. exe 以ードの れます ( 上の例て、出てくる $ * につ イレクトて、 , ファイルに出力する 生成方法 , つまり , コンパイル , リン 行は無視されます。 いては , 次回②ー ( 3 ) マクロの項を クのコマンドをどのようなオプシ ことがてきます。 ご覧ください ) 。 また , ー。オプションて , 出力フ ョンて、起動するかを記述します。 ( 2 ) ターゲットソースのデフォル ( 以下次回につづく ) ァイル名を指定することもて、きま ト設定 [ 例 ] sample. Obj : sample. c す (Table 1 ) 。 行の先頭に , 生成されるもとと sample. h extrn. h なるファイルの拡張子 , 生成され ② k. exe に -ic : *headers* -gs TabIe 2 k のオプション一覧 -md sample SYNOPSIS lmk [option] CNAME lmk は , make ファイルの最初に オプション Ctarget] 出てきたターゲットを最終的に作 =VALUE ... ] 成するファイルと見なします。て、 UNIX の make ユーティリティ と , ほばコンパチプルな Lattice 社 すから , . obj ファイルと . obj ファイ ルを作成するとき , make ファイル の make て、す。 make ファイルにプログラム生成 の最初に . exe ファイルをターゲッ 方法を記述しておくと , 更新され トにしなけばなりません。 . obj ファ たソースのみを生成して , 更新さ イルが先にあると , . obj ファイルを れていないものは , 従来のファイ 作って , lmk は終了してしまいま ルを利用するのて , 不必要なコン す。 TabIe 1 di 幵のオプション一覧 オプション -oFlLE NAME 出力ファイル名の指定 レ 0 バッフアサイズの設定 ( テフォルト : 4K バイト ) -bSlZE NUMBER 1 ファイル当たりの行数の設定 ( テフォルト : 1000 行 ) 空白を圧縮して比較 内容 すべてのターゲットファイルを作りなおす . def ファイルのファイル名を指定する バッチファイルを作成して , 実行する MAKE ファイルのテパッグ用に詳細情報を表示する ターゲットを作成する前に , 作成しなおすファイルを削除する MAKE ファイル名を指定する -f name コマンドからのエラーリターンを無視する 環境変数 LMKPATH で指定されたバスから , ファイルを検索する ターゲットファイルが作れなくても , 処理を続行する コマンドを表示するのみで , コマンドを実行しない マクロ定義と , ターゲットの依存性を表示する ターゲットが更新されたら 1 を , そうでなければ 0 を返す メッセージを表示しない ( サイレントモード ) ターゲットを作らすに , タイムスタンプだけを更新する 無条件にターゲットを再構築する UN Ⅸの MAKE と互換にする -b name -d lnformation from Compiler Makers 153
アルゴリスム テータキ造入門 く第 4 回〉循環・双方向・多重 方向リストを説明します。そして , リストのまとめ 連結リストのバラエティーとして , 循環リスト , 双 先月は , 連結リストについて勉強しました。今月は , 近藤嘉雪 として多重リスト構造を解説しましよう。 循環リスト 64 CMAGAZINE 19 9 勉強する双方向リストは , 循環リストとの 表現する場合にもよく利用されます。次に ります。環状になっていないデータ構造を 循環リストにはいろいろ便利な性質があ は存在しないことになります。 密にいえば最初や最後の要素 , というもの 要素はリング状に結合されているため , 厳 することがて、きます。循環リストて、は , 各 ストに含まれるすべての要素を順番に処理 結びあわせるポインタをたどれば , 循環リ だデータ構造を表現することて、す。要素を 循環リストの本来の目的は , 環状に並ん (circular list) と呼びます。 れることになります。これを循環リスト すが , Fig. 1 ( b ) て、は各要素が環状に連結さ 連結リストて、は各要素は一列に並んて、いま よう (Fig. 1(b))0Fig. 1 ( a ) のような通常の 初の要素へのポインタをセットしてみまし す (Fig. l(a))o ここて、 NULL の代わりに最 素がありませんのて、 NULL がセットされま っています。最後の要素には , 次にくる要 立ち , 各要素が次の要素へのポインタをも 連結リストは複数の要素 ( セル ) から成り 組み合わせ使用が定石になっています。 循環リストの操作 struct CELL * next : st 「 uct CELL { ように定義します。 てみましよう。要素を表すセルの型を次の それて、は , 循環リストの操作法を検討し int value ・ メンバ next には , 次のセルへのポインタが セットされ , メンバ v 引 ue にはセルの値 ( 整数 ) がセットされます。また , 変数 pt 「に , 循環 Fig. 1 連結リストと循環リスト 変数 pt 「 1 ( a ) 普通の連結リスト 変数 pt 「 1 ( b ) 循環リスト 5 5 リストへのポインタがセットされているも のとしましよう。 変数 pt 「は , 次のように宣言してありま す。 struct CELL * ptr ; 変数 pt 「が NULL てあることによって , 循環 リストにひとつも要素がないことを表しま す。 まず , 要素の挿入と削除については , 連 結リストの場合と同様に扱えます ( 本誌 8 月 号参照 ) 。挿入は注目するセルの直後に新し いセルを , 削除は注目するセルのひとつ後 ろのセルの削除が , それぞれ可能て、す。 次に , 要素を順にたどることを考えまし 100 100
アルゴリズム 0 テータ構造入門 List 1 ※ループの末尾で終了条件を判定している。 1 : struct CEL し *ptr, *p; 2 : 3 : if (ptr ! ニ NULL) { 4 : 5 : 6 : 7 : 8 : p = ptr ; do { / * p で指されるセルの処理を行なう * / p->next; } while (p ! = ptr); 循環リストをたどる ( まちがった方法 ) List 2 ※ループの先頭で終了条件を判定している。 ※ 4 行目で p に ptr が代入されるので , 5 行目の wh ⅱ e ループの条件が成立しない。 3 : if (ptr ! = NU し L) { 2 : 1 : struct CE しし *ptr, *q : ※したがってループの本体は決して実行されないことになる。 4 : 5 : 6 : 7 : 8 : = ptr; P wh i I e (p ! = pt r) { / * p で指されるセルの処理を行なう * / p->next; 箇所て、行っています。これは , 前者が pt 「 = 循環リストをたどる ( 正しい方法 ) アルゴリズムとデータ構造入門 65 NULL, 後者が p = =ptr と , 別の条件て、判定 されることによります。これに対して普通 の連結リストては , 次のように両者をまと めて判定することがて、きます。 f0 「 (p ptr ; p ! = N ULL ; p— >next) / * p て、指されるセルを処理する * / fo 「文の条件部分は , リストが空かどうか をチェックすると同時に , リストの最後の 判定も兼ねているのて、 , プログラムはすっ きりします。循環リストについても , この ふたつの境界条件を統一して扱うことがて、 きないものて、しようか ? こて、 , もうひとつの循環リストの表現 法を紹介しましよう。循環リストの先頭を 表す特別なセルを入れます。この特別なセ ルは , リストの先頭を表すと同時にリスト の末尾も表すことになります。このセルを リストの頭 (listhead) と呼びます。つまり , Fig. 1 ( b ) の循環リストは ,Fig. 2 ( a ) のよう に表現されることになります。また , この 方法て、は要素がひとつもない場合て、も , Fig. 2 (b) のようにリストの頭が必ず存在するの て、 , 境界条件をすっきりと扱えます。リス トの頭はセルとしてメモリ管理関数て割り 当てるのてはなく , あらかじめ変数として 宣言しておきます。たとえばリストの頭を P よう。連結リストと同じように , メンバ next には次のセルへのポインタが入っています から , このポインタをたどればうまくいき ます。ただし , 連結リストて、は N IJ LL'* イン タて、リストの最後を判定て、きますが , 循環 リストて、はそうはいきません。なぜなら , すべてのセルが環状につながれているから て、す。 たとえば , Fig. 1 ( b ) て、左端のセルから順 にポインタをたどっていくと , 右端のセル に到達してから , 再び左端のセルに戻って しまい , 堂々めぐりになってしまいます。 この解決策はとても簡単てす。ポインタ を順にたどっていく途中て , ポインタの値 が変数 pt 「と等しくなれば , 最初のセルに再 び戻ってきたことがわかります。循環リス トの要素に対して順番に処理するには List 1 のようにします。まず , 3 行目てはリストが 空てないかを確認します。もし , 変数 pt 「が N ULL なら , この循環リストは空 ( ひとつも 要素がない ) なのて、何もしません。リストが 空てないなら , 4 ~ 8 行目てセルを順番にた どって処理を行います。ここて , do ~ wh ile の形式を用いて , ループの末尾て終了条件 を判定していることに注意しましよう。も し , 次のように先頭て、終了条件を判定した とすると , ループの本体は決して実行され ません (List 2 ) 。 もうひとつの 循環リストの表現法 ところて、 ,List 1 て、はリストが空の場合の 判定とリストの最後の判定をそれぞれ別の Fig. 2 リストの頭をもちいた循環リストの表現法 変数 head 1 ( a ) 4 つの要素をもつ循環リスト 変数 head ( b ) 空 ( 要素がひとつもない ) の循環リスト 変数 head 1 ( c ) 普通の連結リスト 2 2 3 3 4 4 ・最後のセルのポインタ部に , NULL の代わりに リスト部へのポインタを入れれば ( a ) になる ・斜線をひいたセルが「リストの頭」である
ては , 人間の書いたアセンプラソースと比ど差がありません。これは GNU CC の優れ きない 2 回目のプログラムのはずてす ) 。適 較しても , ほとんど遜色のないコードを生た最適化の査証てもあります ( 構造体ポイン 当な 512 * 512 ドットのグラフィックを表示 成しています。 C て、記述て、きるメリットは大タを int ポインタにキャストしてクリアする させ , プログラムを起動してください。ジ きく , ヘッダはコンパイラ作成と同じ時期姑息な手段を用いていますが・・・ ョイステックのみてしかコントロールてき に作ってあったのて , 所要時間 1 時間て、完成 このような改造が可能なのも , GNU CC ませんが , 割り込みて画面の一部分を左右 しました。現実問題として , 割り込み処理がソースて、配布されているためてすが , そ と 8 ラスタ単位てラスタスクロールします。 はディスプレイをとおしてデバッグするのの反面 , 改造に伴って心ず信頼性は低下し OPMDRV. X は組み込まずに実行してくだ は不可能に近く , RS ー 232C を経由したター ます。 さい。組み込まれていても実害はありませ ミナルモードのデバッガて行わないと困難 この改造版 GNU CC は NIFTY-Serve< んが , ほかの割り込みを禁止していないの てすが , この程度のプログラムならリセッソースとともにアップロードされています て、 , OPMDRV. X が無制限に割り込み , 激 ト & コンパイルてもデバッグが可能てした。 が , 「日刊 GCC 」の悪名高く巨大なファイル しく画面が乱れます。 INTR. C ては asm 文を用いていますが , 完を何度も更新し , ダウンロードされる方々 コンパイラの出したアセンプラソースも 全に C だけて、記述した INTRI. C てもほとんに迷惑をかけています。この場をお借りし 収録しておきます。この規模のプログラム Li st 00 0 0 っ 0 6 っ 0 0 0 0 っ 0 っ乙 CD A-. 0 # # 6 6 》 1 6 Q) CO . 1 1 0 ー・ E 0 1 ? ・一 コ - 十し X Q) 0 O O O 0 0 0 ・ ( 、 0 0 0 0 E 0 0 0 1 ワ 3 っ 0 -4 戸 0 ん 0 0 Q) 0 test: return iOCS : extern SP BUP *buffer ロ : void test(int no) : i 十十 ) for (i 0 : i く no if (get-sprite (), buffer[i])) error() : movem. 1 ー 24 (a6) , d3/d4/d5/d6/d7/a3 unlk a6 rts Conference Room 137
アルゴリズムアータ構造入門 ぶことにします。 双方向リストも普通の連結リストと同様 リストの先頭へのポインタによって管 理てきます。しかしせつかく前後両方向へ のポインタをもっているのて、 , リストの末 尾を指すポインタも用意すると便利てす。 先頭と末尾のふたつのポインタによって管 理された双方向リストを Fig. 3 ( a ) に示しま す。 しかし , Fig. 3 ( a ) の方式て、はリストの先 頭と末尾を特別扱いにしなければならない のて、 , 取り扱いが少しめんどうになります。 そこて、 , 先ほど勉強した循環リストを応用 します。つまり , 双方向リストの中に特別 なセル ( リストの頭 ) を入れて , リストが環 状になるように , 最後のセルのメンノヾ next は リストの頭を指すように またリストの頭 のメンノヾ p 「 ev は最後のセルを指すようにし ます (Fig. 3 (b) ) 。これ以降この方式を用い て話を進めましよう。 要素がひとつもない空リストは , Fig. 3(c) のようになります。空リストて、は , リスト の頭のメンバ next と p 「 ev がそれぞれリスト の頭そのものを指しています。 連結リストと比べて双方向リストが優れ ている点をあげます。 第 1 にリストの要素を前後に自由にたどれ ることてす。そもそも , 後ろ向きにも移動 がてきるように 前のセルへのポインタを 導入したのてすから , これは当然て、す。し かし , 要素へのアクセスは , 相変わらずシ ーケンシャルアクセスに限られています。 第 2 に要素の挿入・削除が連結リストに比 べてとても簡単にてきる , ということてす。 連結リストては , 指定した要素の直後に新 しい要素を挿入することがて、きます。しか し , 指定した要素の直前に挿入することは てきません。また , 同様にして , 削除てき るのは指定したセルの直後のセルて , 指定 したセルそのものや直前のセルを削除する ことはてきません。てすから , 先月紹介し た関数ⅲ se 「 t ( 8 月号の List 3 ) のように , ふた つのポインタを用いて , 現在注目している セルと , 直前のセルをつねに指すようにす るのが定石になっています。 双方向リストのセルは , 前後のセルへの ポインタをもっているのて、 , このような制 約を受けずに自由に挿入・削除て、きます。 挿入は , 指定した要素の直前 , 直後のいず れにも行えます。また , 削除についても , 指定した要素の直後などというまわりくど ことをせずに , ずばり指定した要素その い ものの削除が可能て、す。もちろん , 各セル は前後のセルへのポインタをもっています のて、 , 指定した要素の直前や直後の要素を 削除することも可能て、す。双方向リストの 利点は , 前後に自由に移動て、きる点よりも , むしろ挿入や削除が自由に行える点が大き な比重を占めています。挿入 , 削除の実際 については後ほど説明しましよう。 また , 双方向リストの欠点は , 連結リス トに比べ , ポインタをひとっ余計にもつ必 要があることて、す。この点については , リ ストを表現するのに配列と連結リストのど ちらが得かという議論と同じことがいえま す。つまり , 扱いたいデータが小さい場合 ( たとえば , 整数 ) には , ポインタをふたっ ロー第ロー Fig. 4 双方向リストへの挿入 し , データの大きさが十分大きい ( 数十バイ もっオーバヘッドは無視て、きません。しか ト以上 ) なら , セルにポインタをふたつもた せるオーバヘッドはほとんど問題にならな いて、しよう。また , 扱うデータが小さい場 合て、も , 操作の自由さを考えれば十分検討 に値すると思います。 双方向リストの操作 それて、は双方向リストの操作を説明しま しよう。まず , セルは次のように定義され ているものとします。 struct CELL { struct CELL *prev ; struct CELL *next ; MYDATA value ・ メン '*prev には前のセルへのポインタ が , メンノヾ next には次のセルへのポインタが それぞれセットされます。また , M YDATA 型のメンバ va 旧 e に必要なデータをセットし ます (MYDATA 型がどんな型て、あっても , 以 下の議論には関係しません ) 。 また , 次のように定義された変数がリス トの頭になります。 struct CELL head ; まず , 最初に初期化を行わなければなりま せん。この場合 , 初期化とは空リスト ( 要素 ・ポインタ p で指されているセルの直前に , ポインタ x が指すセルを挿入する ( a ) 挿入前 ーローロ 0 ①④②③ ( b ) 挿入後 prev next アルゴリズムとデータ構造入門 67
st 「 uct CELL head ; として定義しておきます。 この方法て、は , 最初の要素へのポインタ は , head. next にセットされていることにな ります。要素がひとつもないときには , head. next がリストの頭自身の変数 head を指して ※循環リストになっています。一般にこの方式が利用されます。 List 3 循環リストをたどる ( 先頭を表すダミーセルを用いる方法 ) 1 : 2 : 3 : 4 : struct CELL head, *p; / * p で指されるセルの処理を行なう * / for (p ー head. next; p ! = &head; p = p- 〉 next) います。つまり , head. next &head となります。また , セルをたどっている途 中て変数 head を指しているポインタがあれ ば , 循環リストをひとまわりしたことがわ かります。したがって循環リストの各要素 を順番に処理する C プログラムは , List 3 の ようになります。 List 1 と比べると , ずい分 すっきりしました。 この方法は , ポインタの代わりにセルそ のものを使い連結リストを表す方法 ( Fig. 2 (c) ) とよく似ています。先月説明しました が , 最初のセルへのポインタ変数によって 連結リストを表す方法て、は , 挿入や削除を 行う場所が , リストの先頭て、あるときとリ ストの途中てあるときて、 , 扱いを変える必 リストの先頭をセルその 要がありました。 ものて表せば , すべての場所に対する挿入 と削除の統一的な扱いが可能になります。 , こて、考察した循環リストの第 2 の表現法 は ,Fig, 2 ( c ) の最後のセルに , NULL の代わ りにリストの先頭を表すセルへのポインタ Fig. 3 双方向リスト 変数 FRONT ( a ) 先頭と末尾を指すポインタによる表現法 ( b ) リストの頭をもちいた表現法 66 CMAGAZINE 19 9 ( c) リストの頭をもちいた表現法 ( 空リスト ) をセットしたものと見なせます。したがっ 構造を表現するのてあれば , 最初の方法が かにもよりますが , 純粋に循環したデータ ことがて、きます。どのような操作をしたい ば , 循環リストの要素を回転 ( r 。 tati 。 n ) する す変数 ( Fig. 1 ( b ) ての変数 pt 「 ) の値を変えれ す。最初の方法をとれば , 循環リストを指 変数 head ) が固定されてしまうのも欠点て、 て、は , つねにリストへの着目点 ( Fig. 2 て、の プしなければなりません。また , この方法 順番に処理する場合 , リストの頭をスキッ 注意が必要てす。つまり , リストの要素を ているて , 循環リストとして扱う際には いう本来は存在しない特別な要素が含まれ 先ほどの方式に比べると , リストの頭と ます。 よってリストの終端が判定される点が違い ポインタが変数 head を指しているか ? りのポインタが NULL て、あるかて、はなくて , うことがてきます。ただし , リストの終わ 結リストの先頭を表す方式と同じように行 て , 要素の挿入と削除も , セルを使って連 便利かもしれません。 リストの頭を用いる方法は , むしろ環状 て、はないデータ構造を表現するのによく利 用されます。あるセルからポインタをたど り続けると , 必ずリストの頭にたどりつき ます。この性質を利用して , リストに連結 されている要素に共通の情報をリストの頭 に格納するわけて、す。このテクニックは , 複合したデータ構造を構成するのに役に立 ちますが , その詳細は後ほど説明しましよ 双方向リスト 双方向リストは , 各セルにふたつのポイ しましよう。 ます。ここて、は双方向リストと呼ぶことに 双方向リスト , 重連結リストなどと呼ばれ います。日本語て、は , 双方向連結リスト , このようなリストを doubly-linked list とい できると考えるのは当然の発想て、しよう。 れば , 前後に自在にリストをたどることが のほかに , 前のセルへのポインタをもたせ きません。そこて、 , 次のセルへのポインタ ないのて、 , セル間の移動は一方向にしかて、 て、す。次のセルへのポインタしかもってい ルに次のセルへのポインタをもたせるもの リストを学んて、きましたが , これらは , セ さて , 今まて、 ( 普通の ) 連結リストと循環 こては , 筆者の趣味から next, prev と呼 -link のつもり ) などとすればよいて、しよう。 と考えるなら , llink と rlink(left-link,right いて、しよう。また , リストが左右に伸びる メンバを next と p 「 ev という名前にすればよ が前後に並んているなら , ポインタをもつ ンタをもっています。もし , リストの要素
List 4 83 : 84 : 86 : 89 : 90 : 92 : 94 : 95 : 96 : 98 : 99 : 100 : 101 : 102 : 103 : 104 : 105 : 106 : 107 : 108 : 109 : 110 : 111 : 112 : 113 : 114 : 115 : 116 : 117 : 118 : 119 : 120 : 121 : 122 : sti ret timestop even _spentt ime mov ret —spenttime even dataseg dw kick vsync pushf call push and out ou t sti POP iret kick_vsync even i nc_COU NT push mov mov 1 nc mov mov 0 t POP out iret inc COUNT end 0 proc ; 経過時間はわざわざ関数の形にしないと ; 最適化のせいで無限ループになる ax, _COUNT proc end p dword ptr cs: int180ff : 先に BIOS を呼ぶ これは int 命令と等価にするため ; ァータセグメントの保存場所 これを加えてみた この 1 / 5 6 秒後に再び呼ばれる ds, dataseg ax, dS 0r0 C near end p 64h , al i8259 + 2 , al al, not VSYNC al, i8259 + 2 word ptr —COUNT end p 64h , al i8259 , al al,EOI dS, ax TEXT Li st 5 TEXT 11 : public DATA DATA 6 : DGROUP ; extern ; extern : extern ; extern 14 : 13 : 9 : 8 : 7 : 5 : 4 : 3 : 2 : ends . end segment word publ ic ' DATA' DATA putch2(int) ;by Taka puts2(char * ) ;by Taka getch2(void) ; originally by Daichi kbhit2(void) ; originally by Daich int Char VOid VOid group endS kbhit2, assume segment word publ ic ' CODE' —getch2, —puts2, —putch2 cs : _TEXT, ss : DGROUP, ds :DGROUP one point Edition ・ cline 用クリッヒ。ングウインドウ設定 関数 setwindow( ) を削除 ・第 5 引数 colo 「の意味合いの変更 ( 前 述のとおり ) ・ラインが水平の場合はとくに高速化 ・そのほか BUG をいくっか修正 ・矩形描画専用関数 g ー box ( ) の追加 TAKALITH の旧バージョンて、は L ℃のル ーチンを使っていたが , 凵 0 を使うと占有べ クタの関係上 CreamyAMI さん作の cw(co mmunication watcher) との共存がて、きなく なるのて、 , やむをえず凵 0 関数はみな別のル ーチンて、書き換えた。その一環として CLINE. ASM に g_box( ) を追加した。 FASTWRIT.ASM (List 3 ) 文字列を高速に画面に出力するためのル ーチン。漢字が混在していても OKO アトリ ビュートはノータッチ。 含まれている関数 : fastkanj(int 「 OW , int CO し cha 「 * str) 行「 ow , 列 co ば画面左上が 0 , 0 ) に文字 列を出力する VTIMER. ASM(List 4 ) VSYNC 割り込みを用いて , 約 1 / 60 秒単位 て、時間を計測するルーチン。 含まれている関数 : VOid timestart(void); 時間計測ルーチンの初期化 void timestop(void); 時間計測ルーチンの終了時に呼ぶ int spenttime(void); timesta 「 t( ) を実行してからの経過時間 を取得し , 返り値とする INPUT. ASM (List 5 ) 基本的な入出力ルーチンてある , kbhit ( ) , getch( ) , puts( ) , putch( ) の代替ルーチ One Point Edition 131
GN び奮闘記ー第⑥回吉野智興 GNU CC の asm 文と割り込み処理 GNIJ CC は強力なインラインアセンプラをもっていますが , ほかの C コンバイラ , 数埋め込んだ asm 文 のインライン機能と使い方かかなり異なり , その使い方も少し難しくなっていま魂 具体的な例をまじえて GNLJ CC を説明してみたいと思います。本稿は , 本誌 7 月号 GNU CC の asm 文のもっとも強力な機能 の g c c についての吉田氏の記事を , より具体的な例で説明する意味で記述しました。 て、す。強力なだけに難解な部分があります。 しかも GNU CC て、は asm 文をも最適化の対 タを割り当てて使うことがてきます。 象にするため , 使い方を誤ると予想もしな register int f00 asm(" d7") ・ いコードに展開されることがあります。 GNU CC の asm 文 これは D7 レジスタを変数 f00 に割り当てる asm (" opecode 0/onO,0/on1 . 宣言てす。関数が記述される前にこの宣言 OUtPUt operand をソースファイルの先頭て行っておけば , input operand 一般的な C コンパイラの , インラインアセ 変数 f00 はレジスタ d7 に割り当てられ , この 破壊レジスタ ) : ンプラ機能は , ただたんにソースに記述さ 変数のアクセスは d7 になります (List 1 ) 。 これが一般的な記述形式てす。 output れ埋め込まれたアセンプラソースコードを operand, input operand には 、内の register 変数を コンパイラの出力ファイルに混在させます。 " 制約文字 " ( C の式 ) . のレジスタに設定する場合 GNU CC の asm 文はこの機能だけてなく , という形式て記述します。任意の C の式が ( C 関数内て宣言するレジスタ変数を任意の 非常に多くの機能を盛り込んだ強力なもの の式 ) の部分に記述可能てすが , output てす。 レジスタに設定てきます。この機能は単独 ope 「 and は左辺値 ( lvalue ) てなけ川要なりま てはあまり意味がありませんが , オペレー せん。また , 必ず制約文字の前に 、 a ルジスタ変数の ションコードを指定した asm 文との組み合わ 必要てす。破壊レジスタは文字列の形てす。 言使う場合 せて , ハードウェアに依存した関数が容易 たとえば d4 〃のように記述し , 複数の場 GNU CC てはグローバルな変数にレジス に記述てきます。 合は ! 〃て並べます。 List 2 を参照してく List register int f00 asm("d7") : extern VOid cal (int) : int opl(void) f00 = 5 : cal ( f00 ) : return f00 : 0 # 7 7 ー 4 0 た 0 0 0 れ さ 成 生 0P1 : Conference Room 133
PC986 シリーズ ( ハイレゾルーションタイプを除く ) 、 MS-DOS Ve 「 3 」以上 ( 対応機種・ OS) 続々登場。 スクリーン関数は画 (CRT) の設に するこ簽ットファイル スクリーンには一連の流れを持ち以下に ー編品ー ( 対応コンヾイラー ) C'PARTS-VOL:.8 (Microsoft) MS-C Ve 「 4.0 以上 (Lattice) Lattice C Ve 「 3.0 以上 Quick C Ve 「 1.1 以上 (Microsoft) TURBO C Ve 「 1.5 以上 (BORLAND) ※上記会社名、製品名は各社の商標または登録商標です 0 ソースー また、入力テータの編集について次の機能かありま魂 1 ) 入力文字種の限定 2 ) 入力データの右詰め表示 3 ) 数字の右側入力 4 ) 数字の 0 抑制表示 5 ) 入力数字データをカンマ付数 字に変更して更表示 本ライプラリーのその他の仕様は 次の通りで魂 1 ) マルチウインドウ処理が可能 ( 最大ウインドウ数はメモリー の限界まで ) 2 ) 入力桁数は 500 字まで 3 ) フォーマットファイノレに言殳定され ている機能の解除、または機 能変更 4 ) 表示ウインドウのスクロール 本ソースライプラリーでは、画面表示、テータ入力用の関数を提供しま魂 本ソースライプラリーでは、画面フォーマットファイルを使用することにより、入力位置、桁数、 タイトル ( 固定文字 ) の指定か随時可能となっていま魂 また、本フォーマットファイルには、入力テータの編集の条件、表示色、ボックスサイズ、ホック スカラー、罫線、初期テータなどの各種バラメータの設定も可能です力、ら、プログラム作成後 でも、上記項目についての変更か可能となっていま魂 また、ウインドウ単位で上記フォーマットファイルを設定しますから、かなり複雑な処理も可能 更に、メニューで設定されたウインドウでは、メニュー選択の処理関数を用意していますので、 ユーサーは本関数を呼ぶだけでメニュー選択処理か出来ま魂 フォーマットファイルで設定可能な項目は次の通りです。 1 ) ウインドウタイトル 2 ) ) ウインドウ表示位置、サイズを設定 3 ) ウインドウポックスカラーの設定 4 ) ウインドウ左右スクロール単位の設定 5 ) ウインドウ罫線モードの設定 6 ) 入力項目への初期値の設定 7 ) 入力項目のアトリビートの設定 8 ) 表示イメージはそのままで、入力位置、桁数、固定文字を設定 秋島ビル 処理をり返しますか いいえ し E D C-PARTS-VOL:4 ー スラフラ 5 ) キーとして使用可能なデータの型は cha 「コ nt , unslgned ⅲてコ ong , unslgned long double です。 6 ) キー長はキーの型を cha 「で指定したとき最大 128B です。他の数値型の場合はそれぞれの 型のサイズによります。 7 ) 最大レコード長は 32KB です。 8 ) 最大レコード件数は 232 ー 1 件です。 ( 実用的な件数は各キーのデータ型によります ) 9 ) 検索方法は指定キーに対しての一致データ検索。また前回検索データについて昇川頁検索 及び降順検索が可能です。また、一致キーがなかったときは、検索キーに最も近いキーを検 索します。 10 ) 検索速度は各コンバイラー、キー長、データ長に依存します。 1 1 ) 入出力関数には簡易アクセスタイプと高速タイプの 2 種類あります。 本ソースライプラリーではコ SAM を C て使用可能にするための関数を提供しておりま魂 ー SAM ファイルは、テータ部分とキーテータ部分を独立して管理しており、 1 つのテータを検 索するためにいくつかのキーを設定することか出来ま魂 また、呼び出し時には設定キーでテータを呼び出すことか出来ますから、テータ管理か格段に 楽になりま魂 主な機能は次のとおりです。 1 ) ファイルに登録されたデータをキーを使って管理することができます。 2 ) 設定可能キー数は最大 45 キーです。 3 ) 同時アクセス可能キーは最大 10 キーです。 ( キー間の条件付検索はできません ) 4 ) キー名称は最大 16 文字です。 C-PARTS—VOL:.5 ラフ乍成ソースライプラー 設定、刻みなとの項目もフォーマットファイル中で指定できま魂 また、同一画面上に複数のグラフも表示可能で魂 ( 1 グラフにつき 1 フォーマットファイルか 対応しま魂 ) また、現在あるテータをもとに将 来のテータを予測する、テータ予 測関数も装備していますので単に 既存のテータをグラフ化するにと どまらず一歩進んだプレセンテー ションを行うことができるものと思 われま魂 また、これらのグラフを作成するた めに用意された、グラフィック関数 や文字の拡大・縮小・網掛け等を 行う文字修飾関数は、単独で使用 することか可能です。 本ソースライプラリーでは、フォーマットファイルを使用した各種ヒジネスグラフ作成関数を提 供しま魂 フォーマットファイルを使うことによって、プログラムの変更なしにグラフの種類、テータの項目 数、グラフの表示位置・色・サイズ・種類・各種文字修飾の有無・タイトル等を変更することかで きま魂 ( 通常ユーサーか使用する関数は 1 個だけで魂 ) また、表示用のデータはテータファイルから取り込む方法と、アプリケーションプログラム中で 渡す方法かあり、用途により選択できま魂 作成できるグラフは下記の 5 種類ですか、これらには多数のバリエーションかありますので、組 み合わせによっては数百におよぶグラフを作成することかできま魂 1 ) 棒グラフ ( ビラミッドグラフを含む ) 2 ) 折れ線グラフ 3 ) 円グラフ ( ドーナッグラフを含む ) 4 ) レーダーチャート 5 ) 散布図 上記グラフ作成時の凡例、各テータに対応する線種、色、ハッチングノヾターン、項目名座標の ・プログラム開発ツールシリーズ C DATA SCOPE レコードの定義はプログラム起動後に定義する方法と、 inc de ファイルで指定する方 通常、プログラムを作成しても、テスト用テータの作成、作成後のテータ 1 ) 法がある の内容の確認なと、本体プログラムの作成以外の労力で結構手間取るこ 2 ) 使用可能データファイルは固定長データファイル とかあるものです。そこで、登場したのか、「 C DATA SCOPE 」で魂 3 ) レコードの初期設定 ( 一括指定、部分データの設定 ) 「 C DATA SCOPE 」は、 C での st 「 uct の表記で、レコードのフォー 4 ) レコードデータの変更 ( s げ uc ーで記述された型での入力が可能 ) マットを記述することにより、プログラムで使用するファイルのテータをア 5 ) レコードデータの削除 6 ) レコードデータの追加 クセス可能にするもので、次のような特徴かありま魂 7 ) 画面上での指定データの検索、表示 8 ) レコードデータのダンプ ( 打ち出しフォーマット、打ち出しデータの指定が可能 ) tutLOX タタタタ タタタタ デデテデデデデデ ■ロ・■ S Vo 匚 5 ー 2 3 4 5 6 7 8 月月月月月月月月 8 月末発売予定 \ 19 , 800 お求め方法 お近くのパソコンソフト取扱店または弊社までこ注文 下さい。弊社へこ注文の際は、メティアサイスをこ指 定下さい。 ( 現金書留または振込 ) また、詳しい資料を こ希望のかたはお電話下さい。 アイセル株式会社 〒 171 東京都豊島区池袋 2 丁目 53 番 8 号秋島ヒル 5F TEL. 03 ( 988 ) 6973 ( 代表 )
米国 特・集コーイラ れ独自の座標系スケーリング , 原点 , およ び軸の方向て、設定て、きます。ビューポート の外への描画はクリップされます。テキス トを描画するためには , ROM-8x8 と ROM ー 8X14 というふたつのフォントだけが使え ます。 線を引く関数て、は , 各点の相対値または Table 1 ライプラリのノヾフォーマンス早見表 絶対値を簡単に指定て、きます。定数 STEP を 使うと , 次のふたつのパラメータは , 最前 の点からの相対座標と見なされます。また , 定数 CURR PT をふたつのパラメータ ( 普通 は最初のパラメータ ) の代わりに使って , 最 前に使われた点を指定て、きます。ⅱ ne ( ) 関数 はしたがって , 引数の個数が可変て、す。 Aztech C C Network Compiler Eco-C88 High C lnstant C La ttice C Microsoft C Power C TopSpeed C Turbo C Watcom C Zortech C/C + + N/A 事情 d 「 aw ( ) 関数はフォーマット文字列と , 引 数リストを引数に取ります。たとえば , d raw( " U = R = D = L = 60 , 60 , 60 , 60) は , 上 , 右 , 下 , 左に 60 ユニット移動しま す。文字列中の等号は , 値を次の引数から 取ることを示します。文字列には , 移動と 設定変更のコマンドを入れます。 MetaWare の GFX ライプラリは , Lattice のグラフィックライプラリと同じものて、す。 マニュアルもほとんど同じて、す。 MetaWare のマニュアルはコンノヾイラのマニュアルと 一体化せず , ライプラリのメーカ—(SterIing Castle) からのものを使っています。マニュ アルには , 別売の強力なフォントエンジン , メニュー , インタフェイス構築ツールなど の解説もあります。ソースコードも入手て、 きます。 MS-C のグラフィックライプラリは , Her cules のカード以外の , ほとんどすべてのデ イスプレイをサポートしています 0Hercules のカードを使うためには , 提供されている TSR プログラムを , グラフィックを使うプ ログラムを走らせる前に , 常駐させなけれ ばなりません。 グラフィック関数は , 画面上左隅を原点 とするスクリーン座標を使います。浮動小 数点数の引数を取り , 浮動小数点数のスケ ーリングを行い , 任意のワールド座標系を 使う , 別の関数セットが提供されています。 フィルバターンとラインスタイルをプロ グラムて、指定てきます。テキスト表示には 多種類のフォントを使えます。各フォント のタイプフェイスは , サイズが複数ありま す。フォントはビットマップまたはべクト ルフォントて、 , 固定スペーシングまたは均 衡スペーシングのいずれかを使います。フ オントファイルは MS-Windows のものと同 じなのて、 , いろいろなフォントを使えます ( Windows 用に設計されたフォントなら何て 特集米国コンバイラ事情 53 プレゼンテーション用のグラフィックライ 表示と単純な形状描画用の関数に加えて , も使えます ) 。