TabIe - みる会図書館


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

1. 月刊 C MAGAZINE 1991年5月号

し , 空のキューに対する serve はまた別の状 況を招きます。そこて、 , キューの定義を ( Fig. 3 のように ) 変えて , 例外条件 full と empty を 示せるようにします。菱形の記号は , その クラスて、生じうる例外を表します。例外の パラメータにも菱形を使い , その例外を起 こしうる操作を示します。 ひとつのクラスの中のすべての操作を , クラス定義の外部に対して可視にする必要 はありません。 OOSD の記法て、は , 可視な操 作はクラスの定義と重ねて , 可視な部分と 隠蔽部分があることを表します。外部から まったく利用て、きない操作 ( pr ⅳ ate な操作 ) はクラスの定義の内側に書きます。 承と総称性 オプジェクト指向設計の真髄ともいえる 原理は , 一般的なクラスというものを定義 して , それから , より特定性のある複数の 下位クラスを定義していけることて、す。 般的なクラスの属性は , 下位クラスの属性 へと継承されますが , 下位クラスは上位ク ラスと自分を区別するための独自の属性も もてます。すなわち , p 。 lyg 。 n ( 多角形 ) を一 般的クラスとして , 辺の数 , 最長の辺など の属性をもたせることがて、きます。すると rectangle ( 矩形 ) が polygon の下位クラス , さらに square ( 正方形 ) が rectangle の下位ク ラスとなります。 クラスは , オプジェクトとその属性 , そ れに対する操作を表現するのて、 , OOSD はク ラスの階層や派生関係も表現て、きるものて、 なければなりません。クラス間の関係を表 すための基本的な考え方が「継承」て、す。総 称性 (genericity) は , 特定のパラメータセッ トをもった一般的クラスを定義し , それに よって関連クラスのファミリを定義て、きる というものて、 , いわば継承の特殊ケースて、 す。 総称性を利用すると , クラスの属性の一 部 , たとえばキューのサイズ , キューに入 る項目のデータ型などをパラメータ化 ( 変項 化 ) て、きます ( 個々のデータ型ごとにクラス を定義しないて、よい ) 。たとえば整数が 100 個入るキューが必要なときて、も , キューの 総称的なクラスにパラメータを与えて , そ ういうインスタンスを生成したほうが , 単 純明快て、す。 テープルのクラスを考えてみましよう。 テープルにはレコードがあり , れに複数のフィールドがあり , ードの型は , それぞれのテープルによって 違います。しかしどの場合にも , レコード に対する基本的な操作は以下のようなもの て、す。 ・新たなレコードの挿入 ( inse ① ・特定のレコードの削除 ( de 厄 te ) ・特定のキーフィールドの値のレコード を探Äsearch) したがって , Table は , クラスのシエネレ ータ ( 生成器 ) ないしテンプレートを表し , それからクラスを定義て、きます。 TabIe の定 義には , テープルの最大サイズと , レコー ドのタイプを決めるふたつのパラメータが あり , それらを使って TabIe の下位クラスを 作り出します。 テープルの設計表現を Fig. 4 に示します。 Table と , ふたつの総称的パラメータは , 破 線て、示され , Table がそれ自体はクラスて、は なくて , クラスの生成に利用されるものて あることを表します。クラスは , このテン プレートから定義て、きます。たとえば cplxta ble というクラスを , size に 100 , rectype に complex というパラメータの値を提供して作 れます。クラスの操作て、ある insert, delete, search は , Table テンプレートに定 義されているとおりに利用て、きます。 Fig. 5 Tab 厄の子孫としての symbo は ab 厄を定義する Fig. 6 多重継承 insert Table enter block symbol table d elete block leave search insert move setmin そのそれぞ そしてレコ setma 个 mln max bounded point location history point 个 bounds h istry bh—point C + + におけるオプジェクト指向構造化設計 33

2. 月刊 C MAGAZINE 1991年5月号

スタートアップ C 十十 実力養成講座 7 値が , 式を評価して求められる値となる。 演算子に対していえることて、ある。 して使用する場合のほかにポインタに対し したがって , 上記例て、は , 整数型の値「 3 」が 四則演算子 て使用する場合が当然ててくる。ポインタ 式「 x = 10.0 / 3.0 」を評価して求められる値 四則演算子 (Table 2 ) て、注意しなくてはな に対して使用する場合には , とくに注意が となる。さらに , 代入演算子は右から左へ らいのは , 剰余算 % 〃てある。剰余算は , 必要となる ( 詳しくはポインタの項て解説す 左辺右辺がそれぞれ整数型て、なければなら の結合性をもっていることから , 以下のよ る ) 。つまり , 定数型の宣言において , 以下 うな式を記述することがて、きる。 ない。どちらか一方て、も整数型以外のデー のような記述が可能て、あるため , やや複雑 タが指定されるとエラーとなる。ほかの演 int a, b, c; となる。 算についてはデータ型の規定はないが , 型 a = b = c = 0 ; const cha 「 * pl ー "Suzuki" ・ この例て、は , まず式「 c = 0 」が評価され , そ 変換の規則に従って演算が行われる。「式を char const * p2 = "Yamada' ・ の結果として「 0 」が求まり , 求まった値が b 評価するとひとつの値が求まる」とは , 乗算 const cha 「 * const p3 = "Simizu"; ・・・③ に代入されるといった順て式が評価される。 を例にすると「 10 / 3 」て、は , 整数型どうしの ①は , ポインタ変数 pl の指すデータが定 乗算て、 , この式を評価すると結果として「 3 」 インクリメント / デクリメント 数となり , ポインタ変数自身は定数て、はな C 十十においても , C 言語と同様に , 変数 が求まるといったことてある。 い。②は , ポインタ変数 p2 が定数となり , の値を 1 増やす , または 1 減らすためのイン 代入演算子 ポインタの変更は行えないが , ポインタの クリメントおよびデクリメント演算子が備 演算の結果など , 変数に値を格納する場 指す値は定数てはない。③は , ポインタも わっている ( Table 3 ) 。このふたつの演算子 合に代入演算子が使用される。代入演算子 ポインタの指すデータも定数となる。 は , 変数に対してのみ有効て , 式に対して は多数存在する (Fig. 2 ) 。代入演算において 演算と式 使用することはてきない。また , この演算 注意すべきことは , 値の型と代入される変 子は , 単項演算子て、あり , 以下の例のよう 数の型が異なった場合に , 必ず値が代入さ C 十十に用意されている演算子は , C 言語 に , 変数の前と後ろのどちらにも記述する と同様てある。これより , C 十十に用意され れる変数の型に変換される点て、ある。以下 ことがて、きる。 ている演算子を解説するが , まず演算子と の例のように , 浮動小数点型のデータによ / / 後置形 i 十十 ; って演算が行われると , 求まる値は浮動小 式についてまとめる。 / / 前置形 演算子は , 演算において行われる動作を 数点型となるが , 代入する変数が整数型て、 表す記号のことて、あり , C 言語と同様の演算 あれば , 求まった値 ( 浮動小数点型 ) が整数 Fig. 2 代入演算子 子が存在する。また , 変数や定数などの基 に変換されたあとて、代入される。 10.0 / 3.0 : 本的な要素と演算子を組み合わせた文法単 int X また , 代入も演算子を用いた式 ( 代入式 ) 位を「式」と呼ぶ。「式」を計算する ( 評価す てあるから , 式を評価するとひとつの値が る ) と , 必ずひとつの値が求められる。これ 求められる。代入て、は , 変数に代入された は , 四則演算子や関係演算子などすべての TabIe 2 四則演算子 TabIe 4 関係演算子 / △ 子 算十一 * 算算算算算算 演加減乗除剰 例 意味 より小さい より大きい 等しいか , より小さい 等しいか , より大きい 等しい 等しくない TabIe 3 インクリメント , テクリメント演算子 インクリメント演算子 デクリメント演算子 十十 スタートアップ C 十十 107

3. 月刊 C MAGAZINE 1991年5月号

し - ① r ー①①、 r 朋・朋に①①、 i 碧羆①十十 ラスの定義て、はなく , クラスの利用によっ て生じます。クラスは , それを利用するこ とによってあるモジュール ( ないし別のクラ ス ) にとって可視となり , その対外的な属性 ( 操作 ) が使用て、きるようになります。クラ スの利用は , モジュールとクラスを結ぶ太 線て、表します。この太線に付随する出力デ ータバラメータは , そのクラスの宣言 ( イン スタンスの生成 ) が複数あることを示しま す 0Fig. 2 は use queue というモシュールを 示しますが , これは queue クラスを利用し て , そのクラスの 103 個のオプジェクト ( ク ラスのインスタンス ) を作っています。モジ ュールの記法は , 構造チャートの場合と同 じて、す。 形式ノヾラメータ <queue> は ,queue クラ スのオプジェクトて、あり , それに結びつい ている操作が , そのクラスの何らかのオプ ジェクトを実パラメータとして受け取るこ とを示します。すなわち , Fig. 2 の enter お よび serve 操作は , ql, q2, q3 のキュー , あ るいは配列 qq のどのメンバにも適用て、きる のて、す。 ほかのモジュールがクラスを利用するこ とは , コール側のモジュールと , そのモジ ュールが使う操作を結ぶことによって表し ます。モジュールが , クラスが提供してい る操作全部を使わないのて、あれば , そうい う操作との結び付きだけを示したほうが , 結び付きがより具体的にわかり , 図を見づ らくせすにすみます。こうして OOSD て、は設 計者がモジュール間の結びつきを非常に注 意深く記述していくことがて、き , クラスの 定義とその利用との間て、のパラメータの数 やデータ型の食い違いをチェックて、きるの て、す。 キューに対する enter および serve 操作は , 例外条件を発生させる場合がありえます。 enter はオーパフローを起こすことがある Fig. 1 OOSD によるキューの定義 <queue> Fig. 2 キューのインスタンスの生成 item enter queue <queue> item serve u se queue <queue> <queue> se rve queue data e m pty item queue data item queue enter Fig. 3 キューの定義中て例外条件を表す <queue> Fig. 4 テープルの総称的な定義 <Table> <TabIe> item found data queue item item insert item L— value, <Table> serve <queue> search q 1 , 2 , q3, qq[l コ rectype size, enter queue e m pty 32 C MAGAZINE 1991 5 delete Table

4. 月刊 C MAGAZINE 1991年5月号

r ー①羆・、 r 朋①朋 r ①①、一碧題 C 十十 OOSD は , 継承によるクラスの階層も表現 て、きます。一群の操作が定義されているク ラスを考えてください。クラスの階層の中 て , これらの操作のすべてを継承する新た なクラスや , あるいは新たな操作が付け加 わったり , 別の操作と換えられている下位 クラスを定義て、きます。 たとえばコンパイラて、使われるようなシ ンポルテープルは , TabIe の下位クラスとし て定義て、きます。するとそれはその属性と ともに , ( デフォルトて ) insert, delete, お よび search 操作を継承します。しかし , 新 たなクラスに特有の操作 (enter block と leave block) も定義されます。 また , insert の場合 (Fig. 5 下 ) のように 操作の定義を変えることもて、きます。この 例の OOSD て、の表し方を , Fig. 5 に示しま す。ふたつのクラス定義の間の破線は , symbol table が TabIe の操作と属性を継承している ことを示します odelete と search は Table か ら継承しますが , insert は独自の定義としま す。そして enter block と leave block は , symbol table という総称的クラスに対して のみ定義されます 0Table と symbol table が パラメータを伴う総称的クラスの場合にも , 同じ継承の概念が適用されます。 この事例は , オプジェクト指向設計の強 みをいくつか示しています。新たに定義す るクラスに新たな操作を加えることがて、き るのて、 , データ型の拡張が可能て、す。また , 既存の操作の定義変えがて、きるのて、 , デー タ型の特定化 ( 専門化 ) が可能て、す。 OOSD は 多態性 (polymorphism) も表現て、きます。 多重継承も OOSD て、表現て、きるのて、 , クラ スを複数のクラスの操作やデータをベース として定義てきます。 Aksit と Tripathi [ 7 ] は , 多重継承を用いるクラスの階層を定義 しています。 point クラスが , 操作 loca tion, move, および display を定義していま す。 bounded point クラスが point から派生 し , p 。 int を一定範囲内て、移動させます。 bounded point は location 操作と display 操 作を継承し , m 。 ve 操作を定義変えし , そし 34 C MAGAZINE 1991 5 て操作 min, max, setmin, および setmax を追加しています。 history point クラスも point から派生して move と display を継承 し , ひとつの point のすべての位置の履歴を 維持するために , location を定義変えしてい ます。 最後に , bh point クラスが bounded point と history point の両方から派生し , display を point から継承 , move, min, max, set min, および setmax を bonded point から継 承 , location を history point から継承 , そし て新たな操作として bounds history を定義 しています。この階層および多重継承を , Fig. 6 に示します。 多重継承の場合は , 継承する操作名の曖 昧性を解決しなければなりません。この例 て、は , location は history point から継承し , move は bounded point から継承する , と単 純に述べました。 location と move は bh point の中て、定義変えしていないのて、 , move が history point から継承される可能性も等し くあります。一般的には , こういう曖昧性 は , 操作名に継承元のクラス名を明確に書 くことによって解決します。 , こまて、説明した OOSD の機能は , 構造チ ャートのシンポルをすべて提供していると ともに , 総称的クラスの定義 , クラスの階 層 , 継承なども含む広範なクラスの定義お よび利用も記述て、きるものて、す。それて、は 次に , モジュールおよび操作の起動を記述 てきる , 拡張機能について説明します。 ヨ同期処理 構造化設計はモジュールの非同期の起動 (activation) を提供し , 構造チャートてはモ ジュール間の破線て、記述しました ( ふつうの コール関係は実線て示しました ) 。今日のソ フトウェアの構造は , こういった能力をさ らに超えて , 単なるコール / 被コールの関係 て、はない , プロセス間通信を形式化て、きる ものて、なければなりません。たとえば , ネ ットワークを形成している複数のプロセッ Fig. 7 バッファリングモニタの OOSD による定義 buffer buffer buffering put 9 et buffer data サ間には , 緩結合の非同期処理がいくっか 存在することがあります。 そこて、 OOSD て、は , モニタ ( Hoare の ) に基 づく非同期処理の定義と利用を表現てきま す。モニタを並行処理の基盤として選んだ のは , それが構造的にも概念的にも , 抽象 データ型と似ているからて、す。バッフアか ら並行的にリードしライトする , というケ ースて、 , その概念を説明て、きます。 バッファリングを行うモニタは , buffer data という名の内部的なデータ構造をも ち , ふたつの操作の影響を受けます。ひと つは buffer data 構造体にデータを一杯に入 れる put て、あり , もうひとつは , データて満 杯のバッフアを空にする get て、す。このバッ フアの内容が , バッファリングを行うモニ タから往来します。並行処理の管理 ( buffer data 構造体の相互的排他性一一複数プロセ スからの同時アクセスを防ぐことーーの実 現 ) は , このモニタの内部に隠蔽されていま す。 その定義を Fig. 7 に示します。表記法はキ ューの定義の場合と非常によく似ています が , ただしタスクには平行四辺形を用い Booch のタスクの記法て、 , モニタを表現して 語を特定した場合の OSD OOSD の表記法は , そのそれぞれのシンポ ルに詳細な設計情報やソースコードを結び

5. 月刊 C MAGAZINE 1991年5月号

上記のように , インクリメント / デクリメ ント演算子が単独の式として使用された場 合は , 前置形てあっても , 後置形て、あって も , 演算子の処理は同様てあるが , ほかの 演算子と組み合わせて使用された場合は , 次のような意味をもつ。前置形ては , 変数 を使用する前にインクリメントやデクリメ ントの演算が行われた後に , 式が評価され る。後置形て、は , 変数の値により式の評価 が行われ , 最後に変数に対しインクリメン トやデクリメントがされる。 関係演算子 / 論理演算子 次に , 条件演算子として関係演算子 (TabIe 4 ) と論理演算子 ( Table 5 ) がある。 関係演算は二項演算子て , 左辺および右 辺のふたつの値を比較する。比較した結果 が「真」てあれば評価値として「 1 」が , 「偽」て あれば , 「 0 」が求まる演算子てある。以下の 演算子「 = = 」の例て、は , 1 と 2 の値は等しく ないから「偽」となり , 変数 x には「 0 」が代入 される。演算子「 ! = 」の例ては , 1 と 2 は異な った値て、あるから「真」となり , 変数 y には「 1 」 が代入される。 int X 論理演算は , 演算子の左右の式を評価し て求まった値により , 左右の真偽をまず決 定する。次に , 左右の真偽の組み合わせと 論理演算子によって論理演算式が評価され 「真」て、あれば「 1 」が , 「偽」て、あれば「 0 」が求 められる演算子てある。ただし , 否定の「 ! 」 は単項演算子て、ある。論理演算ては , 左右 の式として一般には関係演算式が用いられ る。以下の式 , ては , 左辺式 ( x = = 10 ) が評価され値が求め られる。 こて、「真 ( 1 ) 」が求まったとする。 次に , 右辺式 ( y ! = 5 ) が評価され値が求めら れられる。「偽 ( 0 ) 」が求まったとする。 て、 , 論理演算が評価される。「真」と「偽」の 組み合わせて、論理積が行われ , 結果は「偽」 となり値「 0 」が求まる。左右の真偽の決定 108 C MAGAZINE 1991 5 は , 左右の式を評価して求まった値が「 0 」て あれば「偽」 , それ以外の値ては「真」として else W = x; if( x > Y ) 条件演算子 扱われる。 御構造を「式」として記述てきる方法てある。 条件演算子は , C 言語と同様に , if 文の制 の対応するビットごとに論理積や論理和を ビットごとの論理演算子は , ふたつの値 必要て、ある。 あり , システムによって異なるのて注意が 理シフトと符号ビットが入る算術シフトが ては , 空になったビットに必ず「 0 」が入る論 ったビットには「 0 」が入る。右シフトについ 算子てある。シフトを行うことて , 空にな は右に指定した数だけ桁をずらすための演 のビット並びを < < クては左に , > > クて、 そして , TabIe 6 のシフト演算子は , データ 7 に示したビット演算子は整数に適応する。 ごとの論理演算子がある。 Table 6 , Table ビット演算には , シフト演算子とビット ビット演算子 まることになる。 式が評価され , 結果として double の値が求 れば , 変数 x の値が double に変換されて条件 記の例て , 変数 x が int て変数 y が d 。 uble て、あ に従い , 型の変換が行われる点てある。前 の違いがあれば , 以降に示す型変換の規則 使用てきるとともに , 式 2 と式 3 において型 くまて、「式」てあるから , ほかの式と同様に となる。条件式において注意すべきは , あ 御構造を条件式を用いて記述すると , 条件式の評価値となる。したがって , if の制 ( 0 ) 」てあれば式 3 を評価し , 評価された値が 結果が「真 ( 0 以外の値 ) 」てあれば式 2 を , 「偽 条件式ては , 最初に式 1 が評価され , その 式 1 ? 式 2 : 式 3 条件演算式 ( 条件式 ) の形式 ~ 〃 ( チルダ ) は とる演算子てある。ただし , 単項演算子てあり , ひとつの値のビットを 反転するものてある。 型 , 換 C 十十は , C 言語からの改良として「データ 型のチェック」が強化されている。これは , C 十十の特徴のひとつにあげられている点て ある。型チェックの強化は , 異なったデー タ型の式てエラーにするのてはなく , 可能 なかぎり暗黙の型の変換を行うものてある。 暗黙の型変換について , ここては式と代 入について述べる。関数の引数 , 戻り値に ついては関数の項て解説する。まず , 式に おいてデータの異なる数値が混在している 場合は , 高いほうの型にあわされたあとて 演算が行われる。ここていう高い型とは Table 8 に示すように double がいちばん高い型とな る。つまり , double と int の演算ては , int の データが doblue に変換されたあとて , double 型どうしの演算が行われる。 次に代入ては , 代入される値 ( たとえば , 式の評価結果 ) が , 値を代入する変数のデー タ型に変換されたあとに代入が行われる。 代入の際に注意しなければならないのは , 型の違いにより切り捨てや丸めが行われる 占て、ある。 int を char に代入するとき , よぶ んなビット ( 高いほうのビット ) が捨てられ る。また , 浮動小数点型を整数に代入する 場合て、は , 小数点以下が切り捨てられ代入 される。また , double を float の変数に代入 する際には , 丸めが行われる。 このような , 暗黙の型変換のほかに変換 の指定を行う方法がある。そのひとつは , C 言語と同様のキャストて、ある。ただし C 十十 て、のキャストは演算子として扱われる。 キャストの書式 ( 型名 ) 式 このキャストとは別に , C 十十独自の型変 換の指定が以下の書式によって行える。 C + + 独特の型変換の書式

6. 月刊 C MAGAZINE 1991年5月号

まれ , それを管理する情報が FAT 領域とデ ィレクトリ領域に書き込まれます。 通常のフォーマットて、は Fig. 1 に示すディ スク全体が初期化されますが , スイッチ / C て は管理情報の FAT 領域とディレクトリ領域 のみを初期化します。したがって , スイツ チ / C による再初期化は通常の初期化に比べ FORMAT/C の欠点 非常に速く処理て、きます。 ①再初期化であるにもかかわらず , 2DD/ が , 次のような欠点もあります。 再初期化に非常に便利なスイッチ / C てす プログラマのための 2HD の種類を指定する必要がある PC ー 9800 シリーズの MS-DOS は 2DD / 2 HD を自動判別しますから , 再初期化の 場合はわざわざ 2DD / 2HD を指定する必 要はないはずてす ( DOS がいちばんよく 知っているはずてある ) 。それをユーザ に指定させるのは非常に不親切てす。 2DD のディスクを 2HD て、フォーマット したり , 2DD< フォーマットしたりし て使用している方は , フォーマットの 種類をディスクの外見だけて、判断て、き ません。 ②登録すみの不良クラスタの情報も初期 化してしまう TabIe 1 返り値 機能 TabIe 2 返り値 機能 引数 引数 アプソリュートディスクリード (lNT25h ) システムファンクション lNT25h アプソリュートティスクリード AL= ドライプ番号 ( 00h = A , 01 h=B, ・・・ ) DS : BX = ティスク転送アドレス CX = 読み込みセクタ数 DX = 読み込み開始論理セクタ番号 lNT25h キャリー 1 工ラー発生 キャリー = 0 正常終了 INT 25h コール時にスタックに積まれたフラグは終了後もそのままスタックに残っている このシステムコールではセグメントレジスタ以外のすべてのレジスタが破壊され , また , CX レジスタで指定されたセクタ数を DS : BX レジスタで指定されたバッフアに読み込む AL レジスタで指定されたドライプに関して DX レジスタで指定された論理セクタ番号から キャリー = 0 正常終了 1 工ラー発生 キャリー INT 26h DX = 書き出し開始論理セクタ番号 CX = 書き出しセクタ数 DS : BX = ティスク転送アドレス AL = ドライプ番号 ( 00h = A , 01h=B, システムファンクション INT 26h アプソリュートディスクライト アプソリュートディスクライト (INT 26h ) INT 26h コール時にスタックに積まれたフラグは終了後もそのままスタックに残っている このシステムコールではセグメントレジスタ以外のすべてのレジスタが破壊され , また , 出す を DX レジスタで指定された論理セクタ番号から CX レジスタで指定されたセクタ数を書き AL レジスタで指定されたドライプに関して DS : BX レジスタで指定されたバッフアの内容 MS-DOS はディスクをクラスタ単位て 管理します。クラスタはセクタのひと つ上の単位て、 2HD ては 1 クラスタ = 1 セ クタ , 2HC-t は 1 クラスタ = 1 セクタ , 2DD ては 1 クラスタ = 2 セクタてす。不 良クラスタというのはディスクの一部 に読み書きてきない欠陥セクタがある ときに不良としてマークしてあるクラ スタのことて、す。欠陥セクタがあるク ラスタを不良クラスタとして登録して おけば MS ー DOS が使用することはあり ません。よって , そのディスクは使用 可能となります。通常は一度欠陥状態 になると再び読み書きてきる状態にな ることはありません。つまり不良クラ スタの情報も初期化してしまうと再度 登録しなくてはいけなくなり , とても めんどうてす ( 実際のところは欠陥部分 が一時的に読み書きてきるようになっ たり , 別のパソコンてアクセスすると 読み書きてきる場合もありますが ) 。 今回はこの 2 点 ( とくに①のディスクフォ ーマットの自動判別 ) を改善したディスク再 初期化ユーティリティを作成します。その 前にディスクの情報を取得するための DOS ファンクションの説明をします。 DPB アドレスの取得 ディスクの情報を知るには DPB(Disk Parameter Block : Table 3 ) を取得しま す ODPB のアドレスは非公開の DOS ファン クション 32h(Table 4 ) て取得可能てす。 DPB 情報を Fig. 1 に対応させると Fig. 2 のよ うになります。ディスクを再初期化するに は Fig. 2 て FAT 領域とルートディレクトリ 領域を初期化すればよいわけてす。 ティスクの フリースペースの取得 公開されている DOS ファンクションの中 新 MS-DOS プログラミング入門 91

7. 月刊 C MAGAZINE 1991年5月号

lnformation from Compiler Makers FUJdTSU Hiqh C での FPU サポート High C ては , 80387 フローティ ングプロセッサユニットのための コードを生成する機能 FPU サポー トをもっています。ここては , FPU を装備したマシン上て、の High C の 運用に関する注意をまとめてみま 80387 を使用するコードの生成方 法には 2 種類あります。 工ミュレーション機能 まず 387 を装備していないマシン のための , 工ミュレーション機能 をもっライプラリを利用する方法 て、す。この場合はコンパイラのデ フォルト状態て、コンパイルし , $hce. lib" というライプラリをリンクしま す。工ミュレーションライプラリ は , 387 が装備されていなければ , ェミュレートのルーチンて、計算し , 387 が実装されている場合は , 387 を使用して計算を行います。この 方法て、は , 生成したコードが 387 の 有無にかかわらず実行てきるとい う利点があり , 387 があればそれな りに高速に計算をすることがてき ます。 38 たードのインライン展開 80387 を使用するもうひとつの方 法は , 387 のコードをインライン展 開するというものて、す。この場合 は , 生成されたコードは 387 が装備 されていないと実行て、きなくなり ますが , 工ミュレーションライプ ラリを使用した場合よりも効率の よいコードになります。リンクす る標準ライプラリは閉 cc. lib 〃にな C MAGAZINE 1991 5 ります 162 こちらの方法の場合 , 387 を使用 するコードを生成するかどうかは , コンパイルするマシンの状況と , コンパイラトグルによって決まり ます。 まずコンパイル時にコンパイル するマシンに 80387 が実装されてい る場合には , 387 の命令を生成する コンパイラトグル、、 FIoating point 〃は自動的に ON になります。 プログラム中またはコンパイル時 のコマンドラインて、 , このトグル が設定されていた場合も 387 のコー ドを生成するようになります。注 意しなければならないのは , クロ ス環境て、プログラムを作成してい る場合 , 開発マシンに 387 があって ターゲットにはない場合て、す。 コンノヾイラトグルの設定は , prag ma 文を使って pragma ON (Floating ー po int) と書くか , コンパイル時のコマン ドラインて -on FIoating point としてコンパイルします。 80387 に関するコンパイルトグル はもうひとつあります。、、 387 〃とい うトグルは三角関数や指数関数も インライン展開するというものて、 , これは 80287 から 387 の拡張部分と いう形て、サポートされているもの てす。 High C の場合 , 387 専用て、すか ら , このトグルはつねに ON にして おいたほうがいいてしよう。この トグルを ON にする場合の注意は , プログラムの一番最初に書かなけ ればならないということてす。 # include <stdio. h> などの後て ON しても実際には効かないのて、 , 気をつけてください Hiqh C バッケージに 含まれるライプラリ High C VI. 4 L20 て , TOWNS 用ライプラリとしていくつか追加 されたものがあります。これはサ ンプルという形て提供されている ため , マニュアルには記述があり ませんが , ドキュメントファイル が付属しています。 追加されたものには , 「インスト ールディスク # 3 」に入っているハ ードコヒ。ーライプラリと , TOWNS の標準の画像フォーマットて、ある TIFF 形式をサポートするライプラ リがあります。 ま $YTOWNSLIBYLIB の下に ある "HCOPY. LIB" が , TOWNS のグラフィック画面をハードコピ ーするためのルーチンを含むライ プラリて、す。このハードコヒ。ール ーチンは , 画面上の 16 / 256 / 32000 色のグラフィック画像を , モノク 口またはカラープリンタに打ち出 すことのて、きるものてす。ハード TabIe 1 八一ドコピーライプラリ High C VI. 4 L20 コヒ。ーのライプラリ関数の一覧は Table 1 のとおりてす。 もうひとつの TIFF ライプラリ は , TOWNS 上て画像データを扱 う場合の標準形式てある TIFF 形 式ファイルをサポートするものて , 画像データに関する情報が含まれ る TIFF のヘッダ部分を読み書きす るルーチンが用意されています。 これらのルーチンを使うことて、 , TIFF データを解析し画像情報を 取得して表示したり , 適切なヘッ ダをもった TIFF ファイルを作成す ることがてきます。ただし , 現バ ージョンのライプラリて、は , Town sPAINT VI. 1 L21 て、サポートさ れた圧縮画像データへの対応はさ れていません。 TIFF サポートのルーチンは , LIB 形式て、はなく OBJ て提供され , ま たソースも付属しているのて、 , 画 像ファイルを扱うプログラム作成 の参考になると思います。 TIFF ラ イプラリの関数一覧は , Table 2 を 参照してください HDC setGraph HDC setMode HDC start HDC stop PRB get status PRB put char PRB put string getprn Set cutfeed 画面設定状況の通知 印字モードの設定 八一ドコピー開始 八一ドコピー中止 プリンタ状態の読み取り プリンタ 1 文字出力 プリンタ文字列出力 プリンタ設定状態の取得 カットシートフィーダのサポート TabIe 2 引 FF ライプラリ get tiff head check tiff mode get tiff pal set tiff mode make tiff pal make tiff head 引 FF ファイルヘッダの読み込み 画像テータモードのチェック 引 FF ファイルのノヾレット情報の取得 モードに応じた羽 FF 情報の設定 引 FF ファイルノヾレットの作成 引 FF ヘッダの書き出し

8. 月刊 C MAGAZINE 1991年5月号

実力養成講座 7 TabIe 5 論理演算子 演算子 TabIe 7 ビット , 論理演算子 < く 演算子 TabIe 6 ビット , シフト演算子 演算子 TabIe 8 データ型の高い順 TabIe 9 結合性 左右の真偽の 組み合わせ 真 & & 真 真 & & 偽 偽 & & 真 偽 & & 偽 真真 真 ll 偽 偽 ll 真 偽 ll 偽 意味 評価結果と値 真 (O) 真 ( 1 ) 真 ( 1 ) 偽 (O) 偽 ( 0 ) 偽 (O) 真 ( 1 ) 真 ( 1 ) 真 ( 1 ) 偽 ( 0 ) ビットの左シフト ビットの右シフト 意味 ピットことの論理積 ビットことの論理和 ビットことの排他的論理積 1 の補数 意味 テータ型 double long unsigned i nt float は演算時に dou e に変換される cha 「 , sho 代は演算時に int に変換される スタートアップ C 十十 意味 グローバル演算子 クラススコープ メンバ選択 配列添字 関数カッコ 型の大きさ インクリメント デクリメント ビット演算 ( 1 の補数 ) 論理演算 ( 否定 ) 単項 ( プラス , マイナス ) ポインタ キャスト フリーメモリ管理 メンバのポインタ選択 乗算 , 除算 , 剰余算 加算 , 減算 ビットのシフト 関係演算子 関係演算子 ビットの論理積 ビットの排他的論理和 ビットの論理和 論理積 論理和 条件演算子 代入演算子 カンマ演算子 十 , 十十 sizeof 演算子 演算子の優先順位と結合性 十 , スタートアップ C 十十 109

9. 月刊 C MAGAZINE 1991年5月号

には DPB の情報の一部が取得てきるものが あります。たとえば , DOS ファンクション 36h(TabIe 5 ) ては , ・使用可能なクラスタ数 ・ 1 ドライプあたりのクラスタ数 ・ 1 セクタあたりのバイト数 ・ 1 クラスタあたりのセクタ数 が取得てきます。 このファンクションを呼び出す関数は TabIe 6 のようになっています。この関数を 使用してディスクのフリースペースを表示 するサンプルプログラムを List 1 に示しま す。参考にしてください FAT 領域の初期化 MS-DOS 3. x て、は 12 ビット FAT と 16 ビッ ト FAT がサポートされています。 12 ビット FAT はクラスタ番号を 12 ビットて、管理し , 16 ビット FAT は 16 ビットて管理します。 FAT 領域に書き込まれるのはクラスタ番号て TabIe 7 のような意味をもっています。 TabIe 7 から 12 ビット FAT て、は 002h ~ 0 FF6h の 4085 個まてのクラスタが扱えること がわかります。クラスタ数がそれ以上にな るときは 16 ビット FAT を使用し , クラスタ 番号 0002h ~ FFF6h まての 65525 個のクラス タが扱えます。簡単にいえば , 12 ビット FAT : フロッピーディスク IM ~ 10M バイト程度 16 ビット FAT : ハードディスク 20M ~ 40M バイト程度 ということになります。最近は数百 M バイ トのハードディスクも出現しており , 16 ビ ット FAT て、は複数のパーティションに分割 しないと使用てきない状況て、す。 MS-DOS 4. x ては 32 ビットを使用して , 大容量のディスクを管理てきるようになり ましたが , MS-DOS 3. x との互換性や使用 メモリの増加などて見送っているメーカー も少なくありません。エプソンてはとりあ 92 C MAGAZINE 1991 5 TabIe 3 DPB(Disk Parameter Block) の構造 オフセット 十 00h 十 01h 十 02h 十 04h 十 05h 十 06h 十 08h 十 09h 十 OBh 十 ODh 十 OFh 十 1 Oh 十 12h 十 16h 十 1 7 h 十 18h 十 1 Ch 十 1 Eh 十 1 Ch 十 1 Eh サイズ 1 バイト 1 バイト 1 ワード 1 バイト 1 バイト 1 ワード 1 バイト 1 ワード 1 ワード 1 ワード 1 バイト 1 ワード 2 ワード 1 バイト 1 バイト 2 ワード ドライプ番号 (O=A, 1 =B, ユニット番号 セクタ長 ( バイト数 / セクタ ) 内 次の DPB を指すポインタ ティスク交換を示すフラグ メディアディスクリプタバイト テパイスドライバのポインタ ルートディレクトリ領域の開始論理セクタ番号 IFAT あたりのセクタ数 ( セクタ数 / FAT ) 最大クラクタ番号 ( 全クラスタ数十 1 ) テータ領域の開始論理セクタ番号 ルートティレクトリのエントリ数 FAT の数 予約セクタ数 ( FAT 領域の開始論理セクタ番号 ) クラスタ←→セクタのシフトカウント 1 クラスタあたりのセクタ数ー 1 ( セクタ / クラスター 1 ) Ver. 2.1 1 の固有部分 1 ワードカレントティレクトリのクラスタ番号 64 バイトカレントティレクトリ ( ASC 文字列 ) Ve 「 . 3.10 の固有部分 1 ワード最後に変更したクラスタ 1 ワード未使用クラスタ数 詳細は不明ですが , DOS 4. x では十 1 6h の位置に 1 バイトフラグが挿入され , それ以降が 1 バイトずつずれて います。 DPB のチェーンをたどるときにはとくに注意をしてください。 TabIe 4 引 数 返り値 機能 DPB アドレスの取得 DOS ファンクション 32h DPB アドレスの取得 ( DOS 非公開 ) AH=32h DL = 装置番号 ( 0 = カレント , I=A, 2=B, ー NT 21 h DS:BX DPB アドレス AL=OFFh: 工ラー DL レジスタで指定された装置の DPB アドレスを DS : BX に返す

10. 月刊 C MAGAZINE 1991年5月号

C プログラマのための ふたつをまとめてヾイト ( = 12 ビット x 2 ) 単 位に分割してチェーンをたどります。 16 ビ ット FAT て、は Fig. 4 のようにレヾイト単位て、 素直にたどることがてきます。次のクラス タ番号が FF8h ~ FFFh(FFF8h— FFFFh)< あればファイル内の最後のクラスタを意味 し , チェーンはそこて、終了します ( 通常は FFFh/FFFFh が使用される ) 。 今回のユーティリティては次のクラスタ 番号が FF7h ( FFF7h ) て、あれば不良クラスタ を意味するためそのまま残し , FF7h(FFF7 h ) 以外てあれば 0 に初期化しています。 ルートティレクトリ領域の 初期化 ルートディレクトリ領域には TabIe 8 の内 容が 32 バイト一組て、書き込まれていますが , ディスクをフォーマットした直後はすべて 0 になっています。したがって , 今回のユー ティリティても単に 0 て、クリアしています。 返り値 BX = 使用可能なクラスタ数 ただし , 初期化時にポリュームラベルをセ DX=I ドライプあたりのクラスタ数 ットする場合はルートディレクトリ領域の CX = 1 セクタあたりのバイト数 先頭にセットしています。 AX = 1 クラスタあたりのセクタ数 なお , 今回のユーティリティのように AX =OFFFFh: 工ラー FAT 領域やディレクトリ領域に直接書き込 機 能 DL レジスタて指定されたドライプのティスクに関する情報を取得する んだときは DOS ファンクション 0Dh てディ ドライプ番号が無効の場合 AX レジスタが OFFFFh を返す スクのリセットを行う必要があります。 えず MS-DOS 4. x を出荷していますが , 以下同様 ) は次のクラスタ番号となっていま formatc の使用法 NEC は MS-DOS 4. x を見送ってメモリの点 す。つまり Fig. 3 や Fig. 4 のようにしてクラ て改善された MS ー DOS 5. x を出しそうな気 スタのチェーンをたどっていくわけてす。 ディスク再初期化ユーティリティ formatc 配てす。 FAT 領域の最初のレヾイトは FAT ID と呼ば IBM-PC/AT 互換機 <MS-DOS 4. x を ( ソースファイルは付録ディスクに formatc. れ , ディスク媒体の種類を示すものてす。 c として収録 ) の使用法は 使用したことはあるのてすが , 現在手元に 次の 2 ( 3 ) バイトはクラスタ番号を 2 から始 ないため細かく調べることはてきませんて formatc [-f] めるためのダミーてす。 [ d ヨ d : くボリュームラベル > ] した。大容量のディスクの管理方法につい 最初の 3 ( 4 ) バイトはクラスタ番号 0 と 1 に ては NEC が MS-DOS 4. x か MS-DOS 5. x 相当する部分てすが , クラスタ番号 0 と 1 は となっています。 を出したときに改めて説明したいと思いま 使用されることはありません ( クラスタ値 0 フォーマットずみディスクの再初期化を す ( なにしろ手元のマシンは 98VM と 98RA て は未使用を意味し , クラスタ値 1 は存在しな 行います。実際には説明してきたように FAT すから ) 。 領域とルートディレクトリ領域だけを初期 Table 7 を見ると 002h—FF6h ( 0002h ~ 化します。再初期化する際 , 不良クラスタ 4 ( 5 ) バイト目からクラスタ番号を示して FFF6h)( 注 : ( ) 内は 16 ビット FAT 時の値 , があればそのまま残しておきます。オプシ います。 12 ビット FAT< は Fig. 3 のように Fig. 2 DPB 情報との対応 ( 予約セクタ数 ) FAT 領域開始 ルートティレクトリ領域 論理セクタ番号 開始論理セクタ番号 0 テータ領域開始 論理セクタ番号 ( クラスタ番号 : 2 ) セクタ 1 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 理 IPL FAT 1 FAT2 ルートティレクトリ 00 01 02 03 04 05 06 07 08 09 OA OB OC OD OE OF ←ク タ 番 トラック 0 1 76 TabIe 5 ティスクのフリースペースの取得 ( DOS ファンクション ) DOS ファンクション 36h ディスクのフリースペースの取得 引 数 AH = 36h DL = ドライプ番号 ( 00h = カレント , OIh=A, 02h=B, INT 21 h 新 MS-DOS プログラミング入門 93