表示 - みる会図書館


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

1. 月刊 C MAGAZINE 1991年8月号

. 1 MM. EXE の起動画面 Fig Fig. 6 LINE コマンド 始点の X 座標 始点の Y 座標 → 終点の X 座標 終点の Y 座標 → → 色の指定 3 、 1 1 り 0 ん 0 昌退担し HA ィリ 0 リド第 を己第書開洋 青 1 緑 4 水色ー 5 黄 6 白 7 属性 ( * 1 ) シークレット ( * 2 ) ー ブリンク リバース アンダーライン 角を直角に表示 既存の線と交差した場合は十表示ー 1 既存の線と交差した場合は上書き一 11 角を丸く表示 ( 既存の線には上書き ) ー 12 画面の指定 ( 実際に表示する場合は表画面を指定する ) SCREEN 表画面 0 裏画面 1 ( * 1 ) 属性は複数指定もできる。各属性の値を合計して指定すればよい。たとえば , リバース表示に してかっブリンクさせるには , 4 十 2 十 1 = 7 であるから 7 を指定すればよい ( * 2 ) シークレットとは無表示にすることである 誓 ATTRI BUTE 0 ( 表示は 1 ) 2 4 8 → 四角の描画の仕方 BOXK IND Fig. 2 一覧を選択 い 5 い第ⅳ 0 : [ & ユ謝 RatiO t ・「 1 0 ( 一 girøー 744 . 9 トは 177 17 : : 四 - Ⅳト圏 1 施 5 47. に 9 トー 16 ー 7 : 24 : 24 3- 、市 - 8W9 . 9 トー 17 16 : 内 : 第 21 [ 応盟 . C . 9 ト 77 ー 6 : : ナ - F ・ 5 12 材 2 も . C げ・ 2 工 44. 震 9 ト -17 15 : 44 : 釜ナ - 51 肥工 647 . 9 トー 17 : 57 : 0- 、 - ⅱ 4 . 9 ト 8- 買に : : 3- 、 - 給 4474 . 9 ト -17 18 : : Fig. 8 爪 PUT コマンド ー C ( 表示色の指定 ) WI NNUM →ウインドウ番号 通常の表示色 COLOR 1 → COLOR2 →カーソル位置の表示色 ー F ( カーソル行の指定 ) →フィールド番号 NUM WINNUM →ウインドウ番号 → X 座標 → Y 座標 DEFAULT →デフォルト値 →フィールドの桁数 LEN 右寄せなどの指定 STYLE → ー E ( WINDOW コマンドの終了行 ) Fig. 7 BACKSCREEN コマンド → 表示始点の X 座標 → 表示始点の Y 座標 表示する内容 ( 引用符は必要ない ) CONTENT 罫線コマンドと同様の指定 COLOR ATTR I BUTE SCREEN 3 矼を選択 Fig. 簡星退択し HA ′、のヴ面 しのにつし、て ! ををおごないます る 用 号 内 、記 一はの ン切同 ョ区と シのド クとン ンごマ ア一コ〃 フキ線 各 ( 罫 マ コ 0 9 Fig. 10 W DOW コマンド -W ( ウインドウの定義 ) WINNUM →ウインドウ番号 →始点の X 座標 XI 始点の Y 座標 YI →終点の X 座標 X2 終点の Y 座標 Y2 ー C ( 表示色の指定 ) WINNUM →ウインドウ番号 COLORI →ウインドウ内の表示色 COLOR2 →カーソル位置の表示色 ー F ( カーソル行の指定 ) WINNUM →ウインドウ番号 → X 座標 → Y 座標 CONTENT → 表示内容 ボックスカーソルで選択したファイルを実行すべき EXE ファイル名 C0hMAND → →上記の EXE ファイルに与えるべき引数 ARG -E(WINDOW コマンドの終了行 ) を選択 Fig ・ 4 星択し日 A ァイしクトリ付を ぞ要書作式 5 を選択 Fig. Fig. 11 SELECT コマンド ー C ( 表示色の指定 ) COLORI →カーソル位置外の表示色 COLOR2 →カーソル位置の表示色 SCREEN → 罫線コマンドと同様の指定 STARTLI NE → 最初に反転表示するカーソル行の番号 ー F ( カーソル行の指定 ) NUMBER 行番号 → X 座標 → Y 座標 CONTENT →表示内容 COHMAND ボックスカーソルで選択したファイルを実行すべき EXE ファイル名 ARG →上記の EXE ファイルに与えるべき引数 -E(SELECT コマンドの終了行 ) 簡退鉙し HA 基準テノしクトリ都 ファインすス 作業ディレクトリ名戦 C MAGAZINE 1991 8 108

2. 月刊 C MAGAZINE 1991年8月号

正常終了の場合は 0 を返す [ 機能 ] ウインドウ winno を開いて , 各フィ データを入力する keidraw2( ) 関数 ( CM910804 , List 4 ) ールドに menurd2( ) 関数 ( CM910806 , List 6 ) メニューファイルから情報を得て , 各画 面作成ルーチンを起動 [ 書式 ] #include #include "fkey. h" ” menurd. h ” 構造体 mn て、指定するポックスカーソルメニ ュー画面を表示色 rcol 。 r て、表示し , 選択した メニュー番号を返す seldraw2 ( ) 関数 ( CM910808 , 付録ティスク seldraw2. c) メニューファイルから情報を得て , 各画 面作成ルーチンを起動 - ー一文字列から情報を取り出し罫線を表示 [ 書式 ] #include #include "fkey. h" menurd. h ” menurd2(fiIename,cmd,arg) char *filename char *cmd ; char *arg , [ 引数 ] 起動する。メニューによる選択の結果が * クスカーソルなどの表示を行うルーチンを を得て , 罫線 , ファンクションキー , ポッ メニューデータファイル filename から情報 [ 機能 ] 正常終了の場合は 0 を返す [ 戻り値 ] *arg ←引数 * cmd ←起動するコマンド *filename ←メニューデータファイル名 ボックスカーソルによるメニュー選択 ( CM910807 , List 7 ) selbar2( ) 関数 cmd, * arg に代入される [ 書式 ] #include #include "fkey. h ” ” menurd. h ” #ifdef PROTOTYPE "cboxprot. h" #include #endif keidraw2(moji) char *moji : [ 引数 ] *moji ←画面情報の入っている文字列 [ 戻り値 ] 正常終了の場合は 0 を返す [ 機能 ] 文字列 moji から情報を得て罫線を表示する keydraw2 ( ) 関数 ( CM910805 , List 5 ) ー一文字列から情報を取り出し , ョンキーを表示 ファンクシ [ 引数 ] mnC] [ 書式 ] #include #include "fkey. h" 'menurd. h ” keydraw2(moji) char *moji ; [ 引数 ] *moji ←画面情報の入っている文字列 ←メニュー番号 , メニューにおけ 号からなる構造体 および最初に反転表示する行番 の XY 座標 , 表示データの格納行 罫線の表示属性 , 表示する領域 る選択肢の数 , 各行の表示属性 , C010r ←表示色 rcolor ←反転表示色 linenum ←行数 [ 戻り値 ] 正常終了の場合は 0 を返す [ 機能 ] 文字列 moji から情報を得て , ンキーを表示する 110 C MAGAZINE 1991 8 initl ura [ 戻り値 ] ←最初の反転行 ←表 / 裏画面 ファンクショ 選択したメニュー番号を返す [ 機能 ] seldraw2(moji,fp,cmd,arg) char * moji ; FILE *fp ; cha 「 *cmd char *arg [ 引数 ] *moji ←画面情報の入っている文字列 * fp ←メニューデータファイル名のポ インタ * cmd ←起動するコマンド 引数 * arg ← [ 戻り値 ] 正常終了の場合は 0 を返す [ 機能 ] メニューデータファイル fp および文字列 moji グラムにリンクする必要がある。 のライプラリに追加し , 最後にメインプロ コンパイル後オプジェクトファイルを読者 ルスイッチをそれぞれ以下のように設定し , ラムは分割コンパイル用なのて、 , コンパイ パイル可能なものてある。なお , 各プログ 本プログラムは , MS-CVer. 5.1 て、コン コンバイル 果が *cmd, * arg に代入される ーの表示を行う。メニューによる選択の結 から情報を得て , ポックスカーソルメニュ 同様にコンパイルスイッチを設定するとと MS-C て、コンパイルする場合には , 従来と 【 MS-C 】

3. 月刊 C MAGAZINE 1991年8月号

SPARC プロクラミンク List3 ンメニューを表示するものて、ある ( データベ ースプログラム自体については次号て紹介 予定 ) 。 こて、注目していただきたいのは , include ファイルに locale. h を含めていること て、ある。これにより処理速度が若干落ちる が漢字の表示が可能になる。 a 「 uden. c (List 2 ) 伝票入力用の画面を表示した後 , その入 カ値に従ってデータベースをアクセスする 関数。この中て、使用されている mvprintw 関 数は ,curses ライプラリのものて、 , 特定の座 標に表示を行うものて、ある。また mvgetstr 関数は , 特定の座標にカーソルを移動し , 入力を促すものて、ある。 utextke4. c(List 3 ) 端末の画面に罫線を表示する関数て、ある。 まず getenv 関数て、環境変数 TERM を読み込 み , その値により罫線文字コードを与えて いる。リスト中の strcpy 内の文字は空白のよ うになっているが , 実はこれは東芝系の罫 線コードが入っている。 marmnO. c(List 4 ) ポックスカーソル選択画面を表示する関 数て、ある。 A BOLD や A DIM は表示属性を 示している。筆者はこの属性値に terminfo により MS-DOS のカラー表示コードと対応 させ , 端末にカラーを表示させることを可 ムヒ ワ 3 っ 0 っ 0n0 っ 00J っ 0 っ 0 っ 0 っ 0 っ -4 , 4 ・ -4 ・ -414 ・ -4 ・ -4 , 4 ・ -4 , 4 ・′ 0 - -0 -. 0 - -0 - -0 -0 ′ 0 ′ 0 ′ 0 戸 0 へへ《 ^. 0 《《 ^ 《《 0 ^ 行ーー行ーーー 0 ー 0 ーっーー 0 ー 8888888 strcpy(lowerright, " 」 " ) : else{ strcpy(sx, " strcpy(tate, " strcpy (upperl eft , strcpy (upperr i ght, strcpy(lowerleft strcpy (lowerright, " 空白部分には コードが 入っている xl = 2 * ( xl / 2 ) + 1 ・ x2 ニ 2 * ( x2 / 2 ) + 1 ・ if(xl return ( 0 ) if()l > x2){ i swap ()x 1 , &x2) : if()l > y2){ iswap(&yl, &Y2) : if ()l ! = x2 & & yl ! = y2 ) goto bOX : if ()l = x2 ) { for (i=yl ;i<=y2 : i + + ) { mvwprintw(win, i, xl, tate) = x2 & & yl = y2) mid (Y0k0, sx, 1 , x2-xI) : mvwprintw(win, yl, xl, "%s", YOkO) : return ( の ←し 0 4 し十し 0 , 0 っ 0 1 ムっ 0 1 ーっ 0 ′ー、 1 ー 1 っ乙 , 十十十 ・ 1 、 ). ・ー 4 11 十 1 よ・ー・ワ 0 ワ 0 00 十》 11 ′ー、、 1- よ 0 0 marmnO. C Li st 1 : #def i ne EXTN extern 2 : 3 : #include ” ctstdr. h ” 4 : #include ” compiler. h ” 5 : #include "ctoptn. h" 6 : #include ” ctstrc. h ” 7 : #include ” ctisam. h ” 8 : 9 : #include く curses. h> 11 : #include ” markndb2. h ” 12 : #include ” marknva2. h ” 13 : #include "renta101. h" 15 : int marmn0(mn, mnnum, title) 16 : struct Gmnstr mn[] : 17 : COUNT mnnum; 18 : TEXT *title; 20 : int 叩 t : 21 : i nt key : 22 : int keyi clear() : 23 : utextke4(stdscr, 2 , 1 , 76 , 3 , A_DIM) : 24 : 25 : attron (A BO し田 A_REVERSE) : mvaddstr(2.28 , title) : 26 : 27 : attroff A_BOLD) : attroff A REVERSE) : 28 : addstr 佑 , 30 , " 処理を選択して下さいつ : 29 : 30 : for( 叩 t=0;opt く mnnum; 叩 t 十十 ) { armnl. c(List 5 ) 表示属性っきて、画面の特定の位置に文字 列を表示する関数。 endspl. c(List 6 ) 実際に伝票入力用の画面を表示する関数。 attron は特定の表示属性を on にする関数て、 ある。 A BOLD は赤色表示 , A DIM は空色 表示に対応させている。 SPARC LT プログラミング 105

4. 月刊 C MAGAZINE 1991年8月号

工ル江ス・アイジャパン lnformation from C0mpiIer Makers 前回はバーションアップされた LSIC-86 Ver. 3.30 について紹介 LSI C ー 86 Ver. 3.30 は言語仕 様やライプラリが ANSIC 標準規格 に準拠したコンパイラとなってい ます。ただし , ANSIC 標準規格と は多少 , 仕様が異なっている部分 がありますのて、 , 今回は LSI C ー 86 Ver. 3.30 と ANSI C 標準規格との 相違点を示します。また , 則ノヾー ジョンの LSI C ー 86 Ver. 3.1 から の変更点についても示しておきま す。 ANSI C 標準規格との違い 0 ロ ・ LSI C ー 86 て、はキーワード far, near, nonrec, recursive 力防旦カ日 されています ・整数の格上げ (lntegral promo tion) ルールが ANSI の定義とは 若干異なっています ・プリプロセッサはトライグラフ シーケンス ( ? ? と 1 文字て、特殊記号 を表す ) をサポートしていません ・ wchar t および L' … ,, L " …”はサ ポートしていません ・可変パラメータ関数は float, double, long double, 構造体 , 共 用体を返すことがて、きません。 正確には可変パラメータ関数が 返すことがて、きるのは , リター ン値がレジスタに割り当てられ るものだけて、す ・はじめて現れた外部変数や関数 の宣言に extern がついている場 合 , その後の同じ変数や関数の 旦言 , 定義には static と指定して 160 C MAGAZINE 1991 8 もかまいません ・ ANSI 規格て、は INT MAX を越 える定数の型は long になります が , LSI C ー 86 て、は値が UINT MAX より小さいか等しい場合に は unsigned int になります ・浮動小数点定数はすべて long double 型として扱います ライプラリ ・く locale. h > と , その中て、定義さ れているマクロや関数はサポー トしていません ・多バイト文字を扱う関数群 ( mblen ( ) など ) はサポートしてい ません ( 2 ) LSI C ー 86 Ver. 3.1 との違い ロロ ・関数へのポインタ fp を使って関 数を呼び出す場合に , fp ( ) と書く ことがて、きるようになりました。 もちろん , 以前の ( * fp)( ) も許さ れます ・共用体の初期化が可能になりま ・配列や構造体型の自動変数を初 期化て、きるようになりました ・ const/volatile をサポートしまし ・関数と配列に対して単項演算子 、、 & 〃を使用することがて、きるよう になりました。 ・以前は auto と明示した変数は必 ずスタックに割り付けられてい ましたが , このバージョンから は auto 変数もレジスタ割り付け の対象となります。スタックに 割り付けたい場合は volatile を使 ▽ ってください unsigned int, signed int が使用 ・ビットフィールドの型は int, るようになりました らどこにて、も現れることがて、き ・列挙定数は int を書けるところな バル変数やスタティック変数を 定していないときには , グロー ・ #pragma optimize space を指 ルドをサポートしました また , 符号付きのビットフィー 列挙は使用て、きなくなりました。 て、きます。以前のように char や たためなくなりました ・ farstr. lib は doslib. lib に統合され ライプラリ 示的に参照してください の中 <$(LSICOPTS) のように明 変数を参照したいときには , lcc を参照しなくなりました。環境 ・ lcc は環境変数 LSICOPTS など -L に変更されました ーチするディレクトリの指定 ) は -B オプション ( ライプラリをサ イルを探すようになりました レクトリからオプジェクトファ とによって , ライプラリのディ ー I オプションて、 . obj を明示するこ 化を実行しなくなりました れば , r86 はジャンプ命令の最適 ・ lcc に一 O オプションを指定しなけ になりました ルの名前が Isic86. cfg から lcc ・コンフィギュレーションファイ なりました に指定することがて、きるように ・関数に対して far , near を明示的 なりました ワード境界に割り付けるように LSI C -86 Ver. 3.30 ・浮動小数点数を表示て、きない printf/scanf 系関数を含んだラ イプラリファイル intlib. lib を追 加しました。これにともない浮 動小数点数を表示て、きる関数は mathlib. lib から doslib. lib に移 動しました ・いくつかのライプラリ関数は▽ er. 3.1 とは仕様が変更されています のて、注意が必要て、す バージョンアップサー ピスについて すて、に LSI C ー 86 をご購入のお 客様はバージョンアップサービス を受けられます。 バージョンアップサービス料金 は 8 , 000 円て、す。登録ューザにはバ ージョンアップ案内のダイレクト メールを送らせていただきます。 バージョンアップに関する詳しい 内容はダイレクトメールをご覧く ださい なお , 旧バージョンをご使用に なっているお客様て、 , まだューザ 登録カードを返送されていない方 , またはユーザ登録をされた後て、住 所が変更になったお客様て , まだ 新しい住所をご連絡いただいてい ない方にはバージョンアップに関 するご案内がお届けてきない場合 があります。まだ住所変更の連絡 をされていない方は , 住所変更の 届け ( シリアル番号 , 旧住所 , 新住 所 ) とともに , バージョンアップ案 内の送付希望と明記して , 弊社ま て、ご連絡ください。 また , まだューザ登録をなさっ ていないお客様はお早めに登録カ ードを弊社まて返送してください。 ▽

5. 月刊 C MAGAZINE 1991年8月号

スタートアップ C 十十 4 実力養成講座 cout. width ( 7 ) ; の形式によって実現て、きる。 cout. fill( ℃ ,) ; / / バディング文字℃ ' 口までのまとめ ・ 10 進数表示く dec> cout くく 10 ; cout くく dec くく Oxa : 今回まて、一貫して , C 言語に拡張された機 cout. fill ( ' ' ) ; / / スペースへ戻す ・ 8 進数表示く oct > 能の側面を中心に C 十十を解説してきた。 パディング文字指定の場合 , printf て、は , cout くく OCt くく 10 ; C 十十に追加された機能を以下に示す。 スペースか 0 以外を指定て、きなかったが , ・ 16 進数表示く hex> ・コメントの記述 C 十十て、は , 任意の文字を指定て、きる。 cout くく hex くく 10 ; ・変数の宣言方法 標準入力ストリームて、は , cin に対し演算 ・文字コードくキャスト > ・定数型 子、、 < く〃 ( getfrom ) を用いてデータの入 cout くく (int)c ; ・型変換 ( 型チェックの強化 ) 力を行う。 cin て、は , scanf のような入力フォ ・ 1 文字出力く put(char) > ・キャスト ーマットの書式は指定せず , 入力されたデ cout. put('A') ; ・関数の定義方法 ータを格納する変数の型によって決定され cout くく 'A' ; 〃同様 ・関数のプロトタイプ宣言 ・フィールド幅 <width(int) > ・関数のオーバロード また , scanf< は , 入力データを格納する cout. width ( 7 ) ; / / 7 桁幅指定 ・スコープ ( グローバル ) 演算子 変数のポインタを引数に指定するが , cin て、 cout くく i ・ ・インライン関数 は , 引数を参照型としているため変数名を ・小数点以下桁数く precision (int) > ・参照型 指定する。ただし , 文字列の入力て、は , 入 cout. width(7) : ・ void 型の扱い 力された文字列を格納する領域のポインタ cout. precision ( 4 ) ; / / 小数点以下 4 桁 ・関数へのポインタの扱い を指定する。 cout くく 3.141592 ; ・構造体変数の宣言 : right) > ・右詰めく self(ios : ・共用体の扱い cin < < i < < f く < &s [ 0 ] cout. width ( 7 ) : ・列挙型 1 文字の入力て、は , 関数 get を使用すること cout. self(ios : ・ストリーム入出力 もて、きる。 cout くく 10 ; 今回まては , C に慣れたユーザには退屈な cin. get( cha 「型変数名 ) : cout. unself(ios ・ 部分も多かったて、あろう。しかし , C に欲し 関数 get を使って文字列の人力を行うこと ・左詰めく self(ios : かった機能やプログラミングの際に有効な もて、きる。 cout. width(7) ; 機能が備わっていることを実感していただ cin. get ( P, len, c) : left) : / / 左詰め cout. self(ios : けたのてはないかとも思う。これらの機能 char 型変数のポインタ P cout くく 10 ; によって , C よりもより効率的なプセログラ 人力文字列の最大の長さ len :left) ; / / 解除 cout. unself(ios : 入力文字列の終端子 ミングが可能になるはずて、ある。 ・バディング文字く fill(char) > : right) : / / 右詰め : right) ; / / 解除 : left) > 実 践編 白倉伸一郎・山本浩文 ( ) を使っていたが , C 十十て、は new を使う」 ます onew, delete は花形て、はないかもしれ ませんが , クラス機能が人形浄瑠璃の人形 というような誤解が , 広くまかりとおって だとすれば , new, delete はそれを裏から支 います。いや , 誤解というのはいいすぎか えて操る黒子て、す。今回は new, delete につ もしれませんが , 少なくとも正しい理解と いて解説します。 はいえません。 確かに C 十十の入門書などを見ると , そう プ VS malloc( ) 解説されているものも見受けられます。し かし , それは初心者が混乱しないように 便宜上割り切って書いているだけのことて、 「 C 言語て、は動的なメモリの取得は malloc / n w, delete は黒子 C 十十の数ある拡張機能の中て、も , new, delete はクラスに次いて、大切な機能て、す。に もかかわらず , クラスばかりが脚光を浴び て , new, delete はその陰に隠れがちて、す。 ある程度 C 十十になれた人て、も , しつかりと 理解しないまま使っていることがままあり スタートアップ C 十十 137

6. 月刊 C MAGAZINE 1991年8月号

オプジェクトのアドレスを表示する List ノインタの基本 アドレス演算子 オプジェクトにアドレスがあることがわ かりました。て、は , 実際にアドレスを表示 させて確かめてみましよう。 List 3 がそのプ ログラムて、す。 7 ~ 8 行目の & 演算子は初めて本講座に登 場しました。これはアドレス演算子 (address operator) と呼ばれています。 & 演算子をオ プジェクトに適用すると , そのオプジェク トのアドレスを得ることがて、きます ( & 演算 子はより厳密にいうとポインタを生成する 演算子て、す ) 。 1 : # i nc I ude く stdio. h> 2 : 3 : int main(void) 5 : 6 : 7 : 8 : 9 : 10 : } int printf()x のアドレス : %pYn", (x) : printf( ” Y のアドレス : %pYn ” return(0) : 初めてのポインタブログラム LiSt 1 ・ : #include く stdio. h> 2 : 3 : int main(void) 5 : 6 : 7 : 8 : 9 : 13 : 14 : 17 : 20 : 22 : 23 : 24 : 25 : 26 : 28 : 29 : 30 : 32 : 33 : 34 : / * 佐藤宏史君の身長 * / / * 佐中俊哉君の身長 * / / * 高尾健司君の身長 * / / * Mike 平木君の身長 * / / * 真崎宏孝君の身長 * / / * 男の子が好き ( i nt を指す ) = 178 , = 175 , ニ 173 , = 165 , = 179 : satO sanaka takao h i rak i masaki * isako, *hiroko; i nt int アドレス演算子 & はオプジェクトの アドレスを取る ( ポインタを生成する ) 演算子である printf の書式指定は %p となっています。 アドレス ( ポインタ ) を書式化するときはこ Fig. 3 List 3 の実行結果 x のアドレス : FFF4 y のアドレス : FFF2 p 「 intf のポインタ表示 printf は % p でポインタを表示します。 処理系によって表示形式は異なりますが , 一般には L C ー 86 のように大文字の 16 進 数で表示する場合が多いようです。 8086 用の処理系の大部分は , スモールデータ モデルでは , XXXX とオフセットのみを , ラージデータモデ ルでは , XXXX : XXXX とセグメントおよびオフセットを出力し ます。 / * isako は sato を指す * / isako &sato; / * ( 佐藤君が好き ) / * hiroko は masaki を指す * / hiroko &masak i : printf ( " いさ子さんの好きな人の身長 :Xd%n", *isako); pr i ntf ( " ひろ子さんの好きな人の身長 : Xd%n " *hi roko) : / * isako は sanaka を指す * / isakO = &sanaka : / * ( やつばり佐中君が好き ) * / / * hiroko の指すオプジェクトに 180 を代入 * / / * ( ひろ子さんの好きな人は身長が伸びた ) * / printf(" 佐藤君の身長 : XdYn" , satO) : printf(" 佐中君の身長 : %d%n ” sanaka) : printf(" 高尾君の身長 : XdYn" , takao) : printf(" 平木君の身長 : %d%n", hiraki); printf(" 真崎君の身長 : XdYn", masaki) : printf ( " いさ子さんの好きな人の身長 : % d \ n " printf ( " ひろ子さんの好きな人の身長 : % d \ n " , return ( の : *hiroko = 180 : *isako) : *h i roko) : のように p を使用します ( 本講座 6 月号 printf ません ( ぎ : ) 。ポインタとは何て、しようか。 の解説参照 ) 。 LSI C ー 86 て、の実行結果を Fig. List 4 のプログラムを見ながらもっと具体的 3 に示します。 x , y のアドレスが 16 進数て、表 に考えていきましよう。 示されています。もちろん , 実行する環境 5 ~ 9 行目については解説するまて、もない によって表示される数値はこの値とは異な て、しよう。 10 , 11 行目の宣言は見慣れない ります。 形式て、す。 ポインタを使う オプジェクトのアドレスを表示したとこ ろて、おもしろくもないし , 何の価値もあり int *isako, *hiroko : と * が指定されています。 isako と . いう変数 そうそう「オプジェクト」と呼ぶのて、し 128 C MAGAZINE 1991 8

7. 月刊 C MAGAZINE 1991年8月号

Li st 1 86 C MAGAZINE 1 1 8 1 10 : } 100 : } 関数 try は実際にバックトラックを行って て、す。 す。これは Fig. 2 と同じ盤面を出力したもの 示します。実際の出力例を Fig. 7 に示しま いるクイーンの位置を元にして , 盤面を表 て、呼び出されます。配列 pos にセットされて て、 , すべてのクイーンを配置し終えた時点 関数 print_queens は , 盤面を表示するもの 各要素を初期化しておきます。 利き筋になっていないことを示す値 FREE て、 す。また , 配列 C01 , down, up については , ます。配列 pos については一 1 をセットしま 関数 init board はこれらの配列を初期化し ほど説明したとおりて、す。 すものて、す。それぞれの意味については先 す。配列 d 。 wn と up は斜め方向の利き筋を表 す。配列 c 。 1 は , 垂直方向の利き筋を表しま ンが何列目に置かれているかを表すものて、 定義しています。配列 pos は , 各行のクイー 況と利き筋の状態を保持するための配列を 次いて、 16 ~ 25 行目て、 , クイーンの配置状 N クイーンを解くことがて、きます。 なっていますが , ほかの値にすれば任意の N = 8 になっていて , 8 クイーンを解くように 盤の大きさを定義する定数て、す。 こて、は て、定義されている N は , クイーンを配置する 義しています ( 6 ~ 12 行目 ) 。このうち 12 行目 ますプログラムの先頭て、マクロ定数を定 す。 を見つけたらその配置を表示して停止しま 示します。このプログラムは , ひとつの解 を使った 8 クイーンのプログラムを List 1 に に書き換えてみましよう。バックトラック ことがて、きたのて、 , いよいよ C のプログラム 利き筋を表現するデータ構造を準備する となります。 a 十 b き筋の番号は , をふります。ここて、 , 座標 (), b) を通る利 筋に Fig. 6 に示すように 0 から 14 まて、の番号 るかどうかを表すために , それぞれの利き これらの利き筋にクイーンが置かれてい 109 : 108 : 107 : 106 : 105 : 104 : 103 : 10 1 : 99 : 98 : 96 : 95 : 94 : 93 : 92 : 90 : 89 : 88 : 86 : 85 : 84 : 82 : 80 : 79 : 77 : 75 : 74 : 73 : 72 : down[a ー b + (N-I)] = FREE) { / * 置くことができた。場所を記録して、利き筋をセットする * / pos [a] col[b] ニ NOT_FREE; up[a + b] = NOT_FREE; down[a ー b + (N-I)] = NOT_FREE,• ニ FR EE : down[a ー b + (N-I)] = FREE,• up[a + b] ニ FREE; col [b] pos[a] / * 失敗した。クイーンを取り除く * / else { return SUCCESS; ニ SUCCESS) if (try(a + 1 ) / * a + 1 行目以降のすべての行に置けたら成功である * / e lse { return SUCCESS; if (a + 1 〉 = N) / * N 個のクイーンをすべて置くことができれば成功である * / 102 : main() / * 結局この行には置ける場所がなかった * / return FAIL,• init-board() ; if (try(0) = SUCCESS) print_queens() : printf("Sorry, but there is no solution. Yn"); e I se 8 クイーンを解くルーチンて、す。この関数 は , 先ほど Fig. 4 て、示した疑似コーディング をそのまま C て、書き換えたものて、す。関数 try はパラメータ a を受け取るようになっていま Fig. 7 関数 print—queens の出力例 す。 try は , a 行目以降のすべての行にクイー ンを配置しようとします。そして , 成功す れば SUCCESS を , 失敗すれば FAIL を返し ます。 まず 67 行目の for ループて、 , (), 0 ) ~ (a, N ー 1 ) の N 個の位置について繰り返します。 70 行目の if 文て、 , (), b) にクイーンを置くこ とがて、きるかどうかを調べます。 こて、は , 先ほど説明したように配列 c 。 1 ( 垂直方向 ) , up ( 右斜め上方向 ) , d 。 wn ( 右斜め下方向 ) の それぞれについて利き筋になっているかど うかをチェックします。もし , どれかひと って、も利き筋になっていたら , ィーンを置くことはて、きません。 クイーンを置くことがて、きたら , クイー ンの位置を配列 pos に記録します ( 75 行目 ) 。 そして , 配列 C01 , up, down に対して ,

8. 月刊 C MAGAZINE 1991年8月号

法て、 , ドライプ名を指定する方法とまった く同じ結果が得られます。 また , NetWare の API を使わなくても , MS-DOS のファンクションコールを使用し たファイルアクセスて、あればまったく間題 なく NetWare のファイルサーバをアクセス て、きます。たとえば , Turbo C 十十の標準 ライプラリにあるファイルの属性を調べる 関数や , ファイルオープン関数 ( f 叩 en ) , フ ァイルクローズ関数 (fclose) , ファイルの内 容を読み込む関数 ( fgets ) などはまったく間 題なく動作します。ただし , その場合には NetWare のファイルサーバとして提供され るファイルの拡張属性や , ファイルの作成 日 , 史新日 , 所有者などの情報を得られな くなります。 ドライ情報の取得 , こて、は , ディレクトリバスを取得し , ポリューム情報を取得します。これらの情 報によって , ディレクトリ情報やファイル 情報のサーチがて、きます。 GetCurrentDrive 関数 カレントディレクトリドライプ番号の 取得 NetWare の API の GetDriveInformation 関数て、は , 引数としてドライプ番号を与・え なければなりません。そこて、 , MS-DOS の ファンクションコールを使ってドライプ番 号を調べる getdisk 関数を使います ogetdisk 関数は MS ー DOS のファンクションコールに よってドライプ番号を取得しますが , MS- DOS のファンクションコールのレベルて、は NetWare のサーバはあたかも大容量の拡張 ハードディスクとしてとらえることがて、き るため , ドライ 7*F : やドライ 7G : として 扱うことがて、きます。 GetDrivelnformation 関数 - ーー指定されたドライプ番号の情報を取得 指定されたドライプ番号の情報を調べま す。ローカルまたはネットワークドライプ のステータスパイト , そしてネットワーク ドライプに関連したディレクトリハンドル 66 C MAGAZINE 1991 8 List 3 62 : 63 : 64 : 65 : 66 : 68 : 69 : 70 : 71 : 72 : 73 : 75 : 77 : 79 : 80 : 82 : 84 : 85 : 86 : 88 : 89 : 90 : 92 : 93 : 94 : 95 : 96 : 98 : 99 : 100 : 101 : 102 : 103 : 104 : 105 : 106 : 107 : 108 : 109 : 1 10 : 112 : 1 13 : 114 : 1 15 : 116 : 1 1 8 : 119 : 120 : 121 : 122 : 123 : 124 : 125 : 126 : 127 : 128 : 129 : 130 : 131 : 132 : 133 : 134 : 135 : 136 : 137 : 138 : 139 : 140 : 141 : 142 : 143 : 144 : 145 : 146 : 147 : 148 : 149 : &totalBlocks, &sectorsPerBlock, &availableBlocks, &totalDirectorySIots, &availabIeDirectorySlots, &volumeIsRemovable) : fprintf( stderr, " ファイルサーバーが NetWare 386 ではありません。 " ) : if (IsV3 ! = 1 買 { IsV3 = IsV3Sup rted ( connectionID ) : / * NetWare のバージョンを調べる * / ex i t ( 1 ) ; / * タイトルを表示する * / printf ”ディレクトリ名最終アクセス日作成日 printf / * スキャンのためのシーケンス変数を初期化 * / ー 1 し sequence do { / * ディレクトリをスキャンする 所有者 Yn * ディレクトリが登録されていなかったら ( 全てのスキャンが fprintf(stderr, "ScanDirEntry ディレクトリエントリを得られません if ( compIetionC0de ! = SUCCESSFUL ) { break : i f ( compl et i onCode = PATH-NOT-LOCATAB し E ) { completionCode = ScanDirEntry(connectionID, directoryHandle, " * " (BYTE) 0X00 , &sequence, &dentry) : * 終わったら ) 終了 exit(l); Yn 工ラーコード : %02XYn", completionCode ) : Fi leNameSpIit( pathname, name, ext ) : GetEntryPath (&dentry, pathname) : / * ディレクトリ情報の表示 * / printf("%-8s", name) : printf("%-6s " , ext ) : / * 最終変更日時の表示 * / 0X000f , dentry. modifyDate & 0X001f , printf ( " % 02d ー % 02d ー % 02d % 02d : % 02d : % 02d ” (dentry. mod ifyDate > 〉 9 ) + 80 , (dentry. modifyDate 〉〉 5 ) & (dentry. modifyTime 〉 > 5 ) & 0X003f , dentry. modifYTime 〉 > 11 , / * 作成日の表示 * / printf("%02d-%02d-%02d " (dentry. modifyT ime & 0X001f ) * 2 ) : (dentry. creationDate 〉 > 9 ) 十 80 , (dentry. creationDate 〉 > 5 ) & / * 所有者の表示 * / 0X000f , dentry. creationDate & 0X001f ) : Get0bjectName (dentry. ownerID, owner) : printf ("%-9sYnYn ” , owner) ; } while (I); / * スキャンのためのシーケンス変数を初期化 * / ー 1 い sequence ー / * タイトルを表示する * / pr intf " ファイル名サイズ最終アクセス日 printf do { / * ファイルをスキャンする 所有者 作成日 変更者 フラグ * ファイルが登録されていなかったら ( 全てのスキャンが * 終わったら ) 終了 (BYTE) 0X00 , &sequence, &fentry) : completionC0de = ScanFi leEntry(connectionID, directoryHand 厄 , " * " if (compIetionC0de = PATH_NOT_LOCATABLE) { break; GetEntryPath (&fentry, pathname) : FiIeNameSpIit ( pathname, name, ext ) : / * ファイル名の表示 * / printf("%-8s", name) : printf("%-4s " , ext ) ; / * ファイルサイズの表示 * / printf( "%91d " fentry. dataForkSize ) ; / * 最終変更日時の表示 * / printf ( " % 02d ー % 02d ー % 02d % 02d : % 02d : % 02d " fentry. modi fyDate & 0X001f , (fentry. modi fyDate 〉 > 9 ) + 80 , (fentry. modifyDate 〉 > 5 ) & 0X000f , fentry. mod ifyT ime > > 11 , (fentry. modifyTime 〉 > 5 ) & 0X003f , printf ( " % 02d ー % 02d - % 02d " (fentry. creationDate 〉 > 9 ) 十 80 , (fentry. creationDate 〉 > ー

9. 月刊 C MAGAZINE 1991年8月号

プログラマは楽がて、きる。 キーが 1 種類て、重複を許さないシンカレな ものだが , ISAM 関数も用意されている。 ある程度のデータ量を考慮したデータベ ースの作成もてきるわけだ。 さらに , シーケンシャルファイル , ラン ダムファイルなど専用の関数が用意され ているが , どの関数も使用方法が統一さ れ使いやすい ディスクのエラーについてはドライプの 準備がてきていなかったり , ファイルが みつからない , ファイルがオープンて、き ない , 書き込み , 読み込みに失敗したな どのエラーがあればウインドウを開いて ューザに対処を促すことがて、きる。 8 ) 画面表示の特徴として , まず罫線が容易 に引ける。しかし桔梗版て、は , アトリビ ートをいじり , 下線と垂線を使って罫 線を引く。このため罫線の水平線の色の 指定が文字と同じになってしまい , 色設 定を自由にて、きないのが難点だ。マニュ アルによると「ウインドウ機能のため」こ のような仕様になったとのことだが , い まひとつ罫線を引いたときの見栄えが悪 くなってしまうのが残念だ。 大きな特徴として 1 / 4 角文字 ( 添え字 ) の表 示 ( 原理は簡単て、グラフィック表示してテ キストと重ね合わせ表示している。その ため , 注意しないとテキストクリアして も添え字だけ画面に残されるというバグ も出やすい ) や , 半角文字の表示を 2 バイ ト半角または 1 バイト半角に設定変更て、き たり ( 変更する関数も用意されているのて、 便利 ) , 数値の 0 を画面表示ては半角アル ファベットの O ( オー ) て、表示してアプリケ ーション使用者の抵抗感に配慮したりと いうことがあげられる。なかなか細かな 配慮だ。 ウインドウ機能は , 画面の一部にデータ を表示するポップアップメニューの表示な どの用途に使える簡易なものだが , 全部て 10 個のウインドウをオープンてきる。ただ しウインドウに重なりがある場合はクロー ズする順番をオープン時と逆順にしないと いけない。ウインドウ中てはウインドウ左 上角がテキスト , グラフィックともに座標 の原点になる。 導入あたり気づいたこと 以上のように , 派手て、はないが実際的て、 使いやすいライプラリて、ある。規模も機能 も比較的こじんまりとしたシンプルなソフ トウェアて、ある。マニュアルもよく , 関数 の仕様もうまくてきているのて、とつつきや すい。工ラーへの対応も含めためんどうみ のよい関数がそろっている。このことはと くに , 新人プログラマを抱えた場合に有効 だと田 ' ・じ、フ 0 PC ー 9801 のノーマルモードて、動作するよう に作成した実行ファイルがハイレゾモード て、もそのまま ( グラフィック表示も含めて ) 動作するのはすばらしい。さらに N5200 て動 作する実行ファイルもリンクするライプラ リを N5200 専用に切り換えるだけて、作れるの て、 N5200 用のプログラム作成も引き受けるこ とがて、きる。 ライプラリの使用ライセンスについては XS ライプラリを使用しているという事実を マニュアルなどに明記すればライセンス契 約は不要て、ある。 さて , 関数名はよく考えられているが , ローマ字と英語のまじった関数名の決め方 には抵抗がある人もいるだろう。好みの問 題なのて、仕方のないことだ。 ソースについては桔梗版て、も一部付属す るが , これは将来ハードの変更があり得る 部分について ( 仕方なく ) 公開したという程 度の意味て、あり , 積極的に公したという ものて、はない。 たとえば , 文字列入力関数などて、ソース の変更がてきないのは残念だ。おかげて , 挿入モードて、文字列を入力したい場合はラ イプラリ関数て、のデフォルトて、ある上書モ 最新ロロロレポート 間い合わせ先住友セメントシステム開発株 価格 28 , 000 円 「 xs ライプラリ」桔梗版 パイルには XS ライプラリが必要て、ある。 のて、ある。なお , ソースプログラムのコン plel は標準版のもの , sample2 は桔梗版のも samplel. c と sample2. c を収録した。 sam 付録ディスクには , サンプルとして 合は 2 枚 ) 。 かの媒体 1 枚て、供給される ( ソースっきの場 クは IM バイトの 3.5 , 5 , 8 インチのいずれ つきて、 98 , 000 円て、ある。フロッピーディス 価格はソースなして、 28 , 000 円 , 全ソース を公開してほしいという意見も当然出てく 価格を安くしてほしい , あるいは , ソース れならば , ユーティリティはいらないから , 最近は安価て、高機能なものが手に入る。そ ムにせよ , プリントユーティリティにせよ , て、きて、ある。ファイルエディットプログラ 含まれているが , 付録の域を出ない程度の また , ふたつの簡単なユーティリティが ログラマがいないとも限らない 処してほしかった。自分て、対処てきないプ という意味のことを書いているのだから対 てしまうとプログラムが終了するのは不便」 ろうか。マニュアルて、も「キーを押し て、きるようにすればよかったのて、はないだ たりする。 initial 関数て、キーを無効に りにはキーを無効にする機能がなかっ 全体的にめんどうみがいい関数作りのわ 味がかなり薄れてしまうと思う。 いものだ。そうてなくてはソー・ス公開の意 変動しやすい関数のソースを公開してほし らば , ューザのプログラムによって仕様が いなければならない。ソースを公開するな 力するというめんどうな操作をユーザに強 ードをキーて、変更してから文字列を入 〒 101 東京都千代田区東神田 2 ー 4 ー 5 東神田堀商ビル TEL 03 ー 3863 ー 9470 FAX 03 ー 3863 ー 9474 最新開発環境レポート 151

10. 月刊 C MAGAZINE 1991年8月号

て見ていることになります。 接続番号からネットワーク番号とノード ノードアドレスはイーサネットのネット アドレスを得ます。ネットワーク番号はひ ワークポード固有のネットワークアドレス とつのセグメント内 ( インタネットワーク ) て、 , 世界にひとっしかないアドレスて、す。 が表される番号のことて、 , セグメントはす べて同じ番号となります。 したがって , ひとつのセグメント内にあ るサーバのネットワーク番号はすべて同じ NetWare て、はシェルにより ,MS-DOS の て、す。 たとえば , NetWare が標準て、サポートし ファイル , ディレクトリとまったく同じよ ている slist. exe などて、ネットワーク番号が異 うに扱うこともて、きますが , NetWare とし ての特有のサービスを受ける場合にはファ なるサーバが表示されたら , それはセグメ ント外のネットワークをプリッジを経山し イルおよびディレクトリサービスの API を使 ネットワークへの接続状況を表示する (netwami. c) 接続番号の取得 GetConnectionNumber 関数 サーバとの接続番号を取得 ファイルサーバの接続番号を取得します。 接続情報の取得 ファイルおよび ティレクトリサービス GetConnectionlnformation 関数 ーー接続情報を取得 指定した接続ヘログインしているオプジ ェクトの情報を取得します。この関数て、は 以下の情報を得ることがて、きます。 ・オプジェクト名 ・オプジェクトタイプ ・オプジェクトの ID ・ログイン時間 オプジェクトのタイプは finger. c て、説明し こて、は , オプジェ た値が出力されます。 クトは自分自身なのて、オプジェクト名は自 分のログイン名 , オプジェクトのタイプは ューザとなります。 現在接続中のサーバ名の取得 lSt 1 : #include く stdio. h 〉 2 : #inc lude く process. h> 3 : #include く nit. h> 4 : #include く niterror. h> 5 : 6 : void 7 : main(int argc, char *argv[]) 9 : WORD connectionNumber; WORD objectType : long 0bjectID; 12 : IoginTime[7] : BYTB user[48] : 13 : Char WORD connect i on ー D : serverNameC48] : Char network [ 4 ] , node [ 6 ] : 16 : Char 17 : WORD socket; int completionCode; / * 接続番号を取得 * / 20 : 21 : connect i onNumber ニ GetConnec t i onN umber ( ) : if (connectionNumber ー ニ 0 ) { 22 : printf ("NetWare shell not IoadedYn") : 23 : exit(l); 24 : 25 : 26 : &objectType. &objectID, loginTime) : / * 接続情報を取得 * / 27 : 28 : completionCode = GetConnect ionl nformation(connectionNumber, user, if ( compIetionCode ! = SUCCESSFUL ) { 29 : fprintf (stderr, "GetConnectionInfomat ion 接続情報を得られません 30 : exit(l); 32 : Yn 工ラーコード : %02XYn", compIetionCode ) : 33 : / * 現在接続しているサーバーの接続 ID を取得 * / 34 : 35 : connectionID = GetDefaultConnectionID() : 36 : / * ファイルサーバー名を取得 * / GetFi leServerName(connectionID, serverName) ; 38 : 39 : / * ログイン情報の表示 * / 40 : printf(" ユーザ %s はサーバー %s に " user, serverName ) : printf(" %d-%d-%d %d:%d にログインしました \ n " , 42 : IoginTimeC0], IoginTime[I), IoginTime[2], 43 : loginTime[3], loginTime[4) ) : printf(" ワークステーションの接続は %d , 接続番号は %d です \ n " 44 : 45 : / * インターネットワーク情報の取得 * / [ ーー connectionl D, connectionNumber) : 46 : compIetionCode = GetInternetAddress(connectionNumber, network, node, &socket) : 48 : i f ( compIetionCode ! ニ SUCCESSFUL ) { fprintf (stderr, "GetInternetAddress インターネットワーク情報を 49 : exit(l); 50 : 得られません \ n 工ラーコード : %02XYn", completionCode ) : 52 : / * ネットワークアドレス等の表示 * / 53 : printf( " ソケット番号 : % 04X 54 : ”ノードアドレス : % 081X % 04X 55 : " ネットワーク : % 08 Ⅸ Yn", 56 : I ntSwap (socket) , IntSwap(*((int * ) (node + 4 ) ) ) , LongSwap(* ( long *)node) ) , LongSwap(* ( long *)network))) : 59 : 60 : } ス レ ア ノ 番 * ク号ド トト目 * ワトコ * クク時 * / 名トツ一 号工エン名 * 一ッケラ 番ジジイザバネソ工 続ププグ一続一 * * * 接オオロュ接サ / / / GetDefauItConnectionID 関数 接続中のサーバへの接続を取得 この接続 ID は接続番号とは異なり , 今自 分が接続しているいくつかのサーバのうち , 実際にサービスを求めているサーバが何番 目かを示すものて、す。接続番号とは , サー バに接続している端末のうち , サーバにサ ービスを求めてきた端末が何番目て、あるか を示すものて、す。 GetFiIeServerName 関数 サー / ヾ名を取得 接 *%ID によりサーバ名を得ます。 ネッワークアドレスの取得 GetInternetAddress 関数 ネットワーク番号 , ノードアドレスを取得 64 C MAGAZINE 1991 8