data - みる会図書館


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

1. 月刊 C MAGAZINE 1993年12月号

C 言語プログラミンクレッスン・ 問題 1 の解答 List 1 3 て、す。初めて習う言葉なのて、すからそれは 当然のことて、す。英語の新しい構文を習っ てもすぐにペラベラ話せるようにはならな いのと同じことて、すね。初めは時間がかか っても , 何度も何度も繰り返し練習してい ると , さっと for 文を組み立てることがて、き るようになるものて、す。本当に瞬間的にて、 きるようになるのて、すよ。 似たものの繰り返しを見抜いて配列て、表 現したり , 処理の繰り返しを見抜いて for 文 て、圧縮したりすると , プログラムがすっき りと整理されるように思います。そしてそ のあたりに , プログラミングの楽しさが満 ちているように私は思っております。 繰り返しを見抜くのはあなたの目 , それ を表現するのはあなたの手て、す。 ササイズの解答 問題 1 の解答 解答は , たとえば List 13 のようになりま す。 dataCi] を見て , その値が max data よ りも大きかったらその値を新たな max dat a とします。こうすることて、 , max data に は「 dataC0] —dataCi] の最大値」が入ります。 for 文は i = 0 ~ 9 まて、動きますから , for 文が 終わった時点て、 max data は「 dataC0] —dat a [ 9 ] の最大値」が入ることになります。そし てこれが求めるものて、した。 間題 2 の解答 解答は , たとえば List 14 のようになりま す。値の交換をしようとして , data[j] ; data[i] data Ci] : dataCj] とやってはいけません。初めの代入文を実 行した時点て、 , data [ i ] にそれまて、入ってい をソート (sort) とかソーティング (sorting) た値は失われてしまうからて、す。いったん といいます。プログラムて、問題を解く方法 , 別の変数 tmp を使って いわゆるアルゴリズムの本には必ずソート tmp = data[i] ; 今月は配列について学びました。 dataCi]= data[j] ; について書かれています。 for 文や配列 , そ さて次回は「リュックサックにオニギリっ れに関数について学んだあなたは , そろそ data[j]= tmp , めて」と題して , 構這体について学ぶことに ろそういうプログラムに関する本を読み始 とやるのが一般的な技法て、す。 めてみてはどうて、しようか。 しましよう。 ところて、 , List 14 のような並べ換え 82 C MAGAZINE 1993 12 1 : #include く stdiO. h> 2 : #include く stdlib. h> 3 : 4 : #define MAX—DATA 10 5 : 6 : void main(void); 7 : 8 : void main(void) 10 : 11 : 12 : 14 : 15 : 16 : 17 : int i, max_data; int dataCMAX—DATA] = { 31 , 41 , 59 , 26 , 53 , 58 , 97 , 93 , 23 , 84 第 max—data = dataC0] ; for (i = 0 : i く MAX_DATA; i + + ) ( if (max-data く data[i]) { max—data = data[i] ; p 「 intf ( ”最大値は Xd*n ” , max-data) ; 問題 2 の解答 List 1 : #include く stdiO. h> 2 : #include く stdlib. h 〉 3 : 4 : #define MAX—DATA 10 5 : 6 : void main(void) ; 7 : 8 : void main(void) 11 : 12 : 13 : 14 : 16 : 18 : 19 : 20 : 21 : 22 : 23 : 24 : 25 : 26 : 27 : 28 : 29 : 30 : } int i, j, tmp; int dataCMAX—DATA] = { 31 , 41 , 59 , 26 , 53 , 58 , 97 , 93 , 23 , 84 } : printf( ”並べかえる前 *n") : for (i = 0 ; i く MAX—DATA; i + + ) { printf("data[Xd] = Xd*n", i, dataCi]) ; for (i = 0 : i く MAXDATA ー 1 : i + + ) ( for (j = i + 1 ; j く MAX—DATA; j + + ) { if (data[i] > dataCj]) { tmp = dataCi]; data[i] = dataCj]; data[j] = tmp ; pr ⅲ tf ( ”並べかえた後 \ n ” ) ; for (i = 0 ; i く MAX DATA; i + + ) { printf("data[Xd] = Xd*n ” , i, data[i]) : こうぞたい

2. 月刊 C MAGAZINE 1993年12月号

1 : #include く stdio. h> 2 : #include く stdlib. h> 4 : #define MAX—DATA 10 6 : void main(void); 8 : void main(void) int i, j; int data[MAX DATA] = { 31 , 41 , 59 , 26 , 53 , printf(" 並べかえる前 \ 心 ) ; for (i = 0 : i く MAX—DATA; i + + ) ( printf( ” data[Xd] = Xd*n ” , i, data[i]) ; for (i = 0 : i く MAX—DATA ー 1 ; i + + ) { for (j = i + 1 : j く MAX—DATA; j + + ) { if (data[i] > dataCj]) ( / * 値を交換 * / pri Ⅱ tf ( ”並べかえた後 \ n ” ) ; for (i = 0 ; i く MAX_DATA; i + + ) ( printf("data[Xd] = Xd*n ” , i, dataCi]) : 【問題 1 】 26 : 25 : 24 : 23 : 22 : 21 : 20 : 19 : 18 : 14 : 11 : 7 : 5 : 3 : List 28 : ) A> STATS く S 腿 P . S ー STATS. EXE の実行 動作確認 : PC ー 9801 14 : } 問題 2 : 小さい順に並べましよう Fig. 58 , 97 , 93 , 23 , 84 } ; 1 ] 十 0 ; そう , 1 ] 十 i ; 7 STATS の実行 A> LCC STATS. C 11d @1 ⅲ k. i A> TYPE S 朋 P . S 4.15 92.6 5.35 89.79 3.23 84.3 26.4 33.3 83.2 79.0 データの個数 11 合計 504.42 平均値 45.8564 最大値 92.6 最小値 3.1 中央値 33.3 ー STATS ℃のコンバイル ー数値テータの確認 STATS. EXE の実行結果 List 10 のプログラムは , 配列 data の要素 の中て、もっとも大きい数を表示するものて、 すが , まだ完成していません。これを完成 させてください ( 最大値を求めるプログラ ムて、す ) 。 【問題 2 】 List 11 のプログラムは , 配列 data の要素 を小さい順に並べるものて、すが , まだ完成 していません。これを完成させてください ( ソートプログラム ) 。ここて、いう小さい順 とは , dataC0] ミ data [ 1 ] ミ data [ 2 ] 坙・・・・・・の しようじゅん ことを指します。昇順ともいいます。 ティク 間違い探しのコーナーて、す。配列 a [ i ] に 0 ~ i まて、の和を代入しようと思って , List 12 のようなプログラムを作りました か間違っているて、しようか。 List 12 の間違いは , for 文て、使われている i が何から何まて、変化するかを調べることて、 わかります。まず初めに i は 0 になりますね。 はどうなりますか。 aC0] aC0 となります。右辺の配列の添字が一 1 になっ てしまうのて、 , よろしくありません。また for 文の繰り返しの最後には i は 10 になります ね。このときは , a [ 10 1 ] 十 10 , a [ 10 ] となってしまいます。 a [ 0 ] —a [ 9 ] しか使え ないのに a [ 10 ] を使おうとしてよろしくあ りません。 List 9 のようにするとよいて、しよ フ。 2 : 4 : 7 : 8 : 9 : 11 : 12 : 13 : 5 : void main(void) 3 : void main(void); 1 : #include く stdio. h> List 間違い探し ところて、・・・・・・実は配列 a [ i ] に 0 ~ i まて、の printf( ” Xd*n ” , a[5]); aCi] = aCi for (i = 0 : i ← 10 : i + + ) int a [ 10 ] ; 和を代入するにはもっとよい方法もありま 2 れ ( れ十 1 ) す。数学の公式て、 , i * (i 十 1 ) / 2 , for (i i く 10 ; i 十十 ) { という式があるのて、 , それを使えば 大値・最小値・中央値を計算するプログラ ータを受け取って , その合計・平均値・最 これは , 標準入力からたくさんの数値デ ログラム」 ( STATS ) て、す。 今月のサンプルプログラムは「統計計算プ 計計算プログラム いぶんすっきりしているかもしれませんね。 とすることも可能て、す。このほうが if 文がな コンパイラ ムて、す。 : LSI C ー 86 Ver. 3.30 試食版 対応機種 : MS-DOS が動作する全マシン このとき , 80 C MAGAZINE 1993 12

3. 月刊 C MAGAZINE 1993年12月号

どのタイマ割り込み ( 実は VSYNC 割り込 み ) を用いて測定することて、自動的に決定し ています。 ただ , 開発は 80286 ( PC ー 9801VX21 ) て、行 っていますのて、 , 80486DX2 の 66MHz あたり になってくると 1 秒間の書き換えフレーム数 が 60 以上になり , メータの指針が複数見え たり , キー操作が追いつかなくなってくる 可能性 ( とくにギアが入りにくいなどの不具 合 ) があります。こういう場合はクロック数 を落として対応してください ンン音 背景スクロール ①スクロールサププロシジャ SUB frontground ' FOR FRONT-VIEW SCROLL from scroll data :BPLANE ( 6000 ). RPLANE(6000), GPLANE(6000), AP し ANE(6000) tO graphic V-RAM each plane (), R. G, A) RENGE: ( 0.70 ) - ( 639 , 99 ) MACHINE CODE PROGRAM 8086 block tarnasfer from scroll data tO vram parameter scroll data SCADB:scr011 data bplane start adress SCADR:scroIl data rplane start adress SCADG:scroll data gplane start adress Boff :scroll data offset 第 ②マシン語コードのセット 'MACHINE CODE SET for front ground scroll ppl : VARPTR(AsmCodef(l)) DEF SEG ニ VARSEG(AsmCodef(l)) 'MACHINE CODE SET FOR K% : 0 TO 123 READ D% POKE ppl + K%, D% NEXT List + 14 + 12 + 10 + 6 SCADB% : VARSEG(bplane(l)) SCADR% ニ VARSEG(rplane(l)) SCADG% ニ VARSEG(gplane(l)) ' block transfer scroll data to graphic vram (execute) d i rt f : d i rtf - 田 RT 惲 d i r t f > 引 9 TH EN d i r t f ニ d i r t f - 319 作 dirtf く 0 THEN dirtf : dirtf + 319 Boff% ニ INT(dirtf) DEF SEG ニ VARSEG(AsmCodef(l)) C 乢し absolute(BYVA し SCADB%, BYVAL SCADR%, BYVAL SCADG%, BYVAL Bof f%, PPI) DEF SEG END SUB 0 工ンジン音には BEEP 音を使っています。 MS-BASIC には SOUND 命令があるのて、す が , SOUND 命令て、は音を出す時間を指定す る必要があり , 連続的に鳴らすには不便て、 す。そこて、 , このゲームて、は BEEP 音の I / O ポート ( 3FDBH ) を直接アクセスする方法を 採用しています ( 参考文献 [ 3 ] ) 。このため , BEEP 音は自動的に鳴ってくれるようになり ました。また , VM 以降の PC ー 9801 て、は BE EP 音の周波数は変えることがて、きるのて、 , 工ンジン回転数に応じて変化させています。 ただし , 無印 / E / F / M て、は BEEP 音の周波 数を変えられないのて、エンジン音は変化し ません。もっともこのゲームはこれら 8086 搭載の機種はサポートしていないのて、ゲー ム自体が動かないかもしれませんし , 動い ても重くてゲームにならないて、しよう ( ちな みに無印と U2 はグラフィック画面がひとっ しかないのて、動きません ) 。 背景クロール このゲームて、は , コーナリングをすると 背景のビルや山が横スクロールをします。 横スクロールといっても 1 ドットスクロール て、はなく , 簡単な 8 ドット ( 1 バイト ) 単位の スクロールて、す。難しいことは何もしてい ません。メモリ上のデータを VRAM へプロ ック転送しているだけて、す。スクロールに は GDC(GRCG や EGC) を使う手もあります ③マシン語本体 ' front ground scroll mash i ne COde DATA & h55 'start: push bp DATA &h8B, &hEC mov bp, sp DATA &hlE push ds DATA &h6 push es DATA & h50 push ax ax, [BP + に] DATA &h8B, & h46 , &hOC :scroll BPLANE start aderess DATA &h8E, &hD8 dS, mov DATA &hB8, & h00 , &hA8 ax, 0a800h ;vram blue plane start adress mov DATA &h8E, &hC0 mov Sl,[bp + 6 ] DATA &h8B, & h76 , & h06 : scroll offset mov DATA &hB8, & h80 , & h16 : ( 0 , 72 ) ax, 1680h DATA &h8B, &hF8 mov DATA &hB3, &hlE bl,01EH ;sum of scroll mov DATA &hB9. & h28. & h00 コ abe 日 cx, 28h ;tran.sfer :mov DATA &hFC cl d DATA &hF3, &hA5 movsv rep DATA &h81, &hC6, & h40. & h01 add si . 0140 日 0 DATA &hFE, &hCB dec 国 DATA & h80. &hFB, & h00 bl,0H DATA & h75 , &hEF labe Ⅱ Jnz DATA &h8B. & h46 , &h0A ax. [ bp + 10 ] ;scroll rPLANE start aderess mov DATA &h8E, &hD8 dS, mov DATA &h8B, & h76 , & h06 Sl,Cbp + 6 ] : scroll offset DATA &hB8, & h00 , &hBO ax, 0b000H DATA &h8E, &hC0 mov DATA &hB8, & h80. &h16 ax, 1680h mov DATA &h8B, &hF8 d i. mov DATA &hB3, &hlE bl,01EH mov DATA &hB9, & h28. & h00 'labe12 ・ cx,28h DATA &hFC cl d DATA &hF3, &hA5 rep movsv DATA &h81, &hC6, & h40 , & h01 add si , 0140H DATA &hFE, &hCB dec DATA & h80 , &hFB. & h00 bl,0H つ DATA & h75 , &hEF jnz labe12 DATA &h8B. & h46 , & h08 ax. Cbp + 8] mov DATA &h8E, &hD8 dS, mov DATA &h8B, & h76 , & h06 s Cbp + 6 ] mov DATA &hB8, & h00. &hB8 ax, 0b800h mov DATA &h8E . &hCO 田 OV es, DATA &hB8, & h80 , &h16 ax, 1680h 田 OV DATA &h8B, &hF8 di, DATA &hB3, &hlE bl,01EH mov DATA &hB9 . & h28. & h00 'labe13 ・ cx,28h DATA &hFC cl d DATA &HF3. &HA5 rep 田 OVS 響 DATA & h81 , &hC6. & h40. & h01 add si . 田 40H DATA &hFE, &hCB dec 国 DATA & h80 , &hFB. & h00 bl,0H DATA & h75 , &hEF labe13 jnz DATA & h58 POP DATA & H07 POP line(3 の ; 400 - 80 ;sum 0f scroll ; transfer Size ⅱ ne ; 400 - 80 ;scroll GPLANE start aderess : scroll offset ;sum of scroll : transfer Size ー i ne : 400 - 80 Conference Room 153

4. 月刊 C MAGAZINE 1993年12月号

List 256 ノヾイト以上のテータを処理したら戻る 元の関数 List 1 : void receive(long limit) 3 : AGAIN : clear-timer(); 6 : CHECK_DATA: if .com/length() 〉の { get.com/data(); goto AGAIN; 14 : 15 : 1 . v 0 i d rec e i v e ( n g ⅱ m i t ) 6 . AGAIN : clear_timer(); 8 . 9 . CHECK_DATA: com-length(): if (i 〉 0 ) { get.com/data() ; S i ze 十ニ i : if (size > ニ 256 ) return; goto AGAIN; 20 : 22 : } i n t S i ze i f ( read- t i me r ( ) くⅱ m i t ) { goto CHECK_DATA; get.com data が処理したテータサイズを戻す List i f ( read ー t i me r ( ) くⅱ m i t ) { goto CHECK_DATA; 1 ・ VO i d rec e i ve い 0 ng ⅱ m i t ) i nt S i ze 5 : AGAI N : clear-timer(); 8 : CHECK_DATA: if .com/length() 〉 0 ) { size + ニ get.com/data(); if (size 〉 = 256 ) return; goto AGAIN; goto を使わない場合 List 1 : v 0 i d rec e i ve (1 0 n g ⅱ m i t ) 3 . i n t S i ze h ⅱ e (s i ze く 256 ) { clear_timer(); while .com/length() if (read-timer() > ニ return; ⅱ m i t ) i f ( read ー t i me r ( ) くⅱ m i t ) { goto CHECK_DATA; size + : get.com/data(); om data( ) の仕様次第て、 , ほかの処理が正 も明確になっている。元のリストは , 継続 という変数を追加した。しかし , この処理に の判断が処理の中に埋もれてしまってわか というのはどう しかったり危険だったり , は , すて、に述べた大きな欠陥がある。 com りにくい も釈然としない length() を呼び出した時点から get.com d 0 したがって , 前回 , 「もう少し複雑な処理 get.com data( ) が , 実際に引き取ったデ ata ( ) を呼び出すまて、の間に新たなデータが になると , このように書き換えられない ータのサイズを戻すようにするというアイ きてしまったとき , 計算した size と実際に処 とがある」の例として , この間題を示したの デアもある。これは , fread のような関数と 理したデータの長さが食い違う危険がある は , まったくの空振りというか , 的外れて、 同じ発想なのて、 , 慣れた人ならこのほうが のだ。 あったわけて、 , 恐縮ながら例としては , 前言 コーディングしやすいだろう。この結果は 題の解決 を撤回させていナだく。しかも , 成り行き上 , List 3 のようになる。 代わり 0 間題を一示す ~ きだと思われ 00 さて , goto を使わない場合だが , 実はも だが , あまりよい例も思いつかなかったの っと複雑になるかと勝手に想像していたの この問題を解決するにはどうすればよい て、 , 中途半端のまま今回のネタは終わる。 て、あるが , 実際に書いてみると , List 4 のよ か。ひとつの方法は , get com data( ) の作 こて、話を終えるには , うに , 思った以上に簡潔になってしまった しかしながら , り方を工夫することて、ある。つまり , get c あまりにも無責任すぎるのて、一言補足して 簡潔になった最大の理由は , for のループを om data ( ) は , 直前に com length( ) を呼び while に置き換えて , 256 バイトという判断 おく。 出したとき , 戻した値だけデータを引き取 List 1 の / * (1) * / とコメントが書いて のための条件式をここに埋め込んだからて、 るという仕様にするのだ。その間に新たに ある部分に処理がある場合は , フラグを使 ある。 割り込み処理て、受け取ったデータは , その わないかぎり goto は除去て、きない これにより , receive( ) の処理が , size< ままバッフアに残しておき , 次回呼び出し 256 という条件を満たす間だけ継続すること ( フィンローダ NIFI 、 Y&rve FPRCX?J SN)P) たときに引き取るのて、ある。しかし , get c フィンローダのあつばれご意見番 161

5. 月刊 C MAGAZINE 1993年12月号

C 言語プログラミンクレッスン・ 問題 1 : 最大値を求めましよう List ず , 16 進表記を使って書くこともて、きます。 List 6 を書き直してみましよう (List 7 ) 。 次元配列の初期化が二重の { } て、表現され ていることに注意してください そうそう。演算子十 = の説明を忘れると ころて、した。 sum 十 = tenCi] ; 1 : #include く stdio. h> 2 : #include く stdlib. h> 3 : 4 : #def i ne MAX—DATA 10 5 : 6 : void main(void) : 7 : 8 : void main(void) int i, max data; 10 : 11 : 12 : max_data = data[0] ; 13 : for (i = 0 ; i く MAX—DATA; i + + ) { 14 : 15 : max data printf(" 最大値は Xd*n ” , max-data) : は , int data[MAX_DATA] = { 31 , 41 , 59 , 26 , 53 , 58 , 97 , 93 , 23 , 84 } ; sum = sum 十 ten[i] , と同じ意味て、す。変数 sum に「足し込む」と考 えればよいて、しよう。同様に ・・などが C 言語には用意され ています。 ズ 0 ます。したがって a [ 5 ] の値は 25 となりま ズの答え す。 さて , 今月もいろいろ勉強してきました。 [ クイズ 3 の答え ] こて、 , 今月のポイントて、ある配列につい 15 と表示されて改行されます。 for 文によ [ クイズ 1 の答え ] ての理解度をチェックするため , 簡単なク って , 配列 a に代入される値は , 次のように ウソ。 C 言語の配列は 0 番目から始まるの イズを用意しました。 て、 , 使えるのは a [ 0 ] ~ a [ 99 ] まて、の 100 個の なります。 [ クイズ 1 ] aC0] = 要素て、す。 配列を , aC1]= aC0] [ クイズ 2 の答え ] int a [ 100 ] ; aC2]= a[l] 25 と表示されて改行されます。 for 文によ と定義したとき , a [ 1 ] ~ a [ 100 ] まて、の 100 個 aC3] = a[2] って , 配列 a に代入される値は , 次のように の要素が使える。これは本当か , ウソか。 なります。 [ クイズ 2 ] List 8 をコンパイルして実行すると , 何が 表示されるか。 aC2]= 4 ; [ クイズ 3 ] aC3] = List 9 をコンパイルして実行すると , 何が 表示されるか。 十 1 ; 十 2 ; 十 3 ; aC9] = a[8] 十 9 ; いいかえれば , 0 十 1 ; 0 十 1 十 2 ; 0 十 1 十 2 十 3 ; aC9] = 0 十 1 十・ すなわち , a Ci] の値は 0 ~ i まての和となり ます。 aC5] の値は 15 て、す。 ササイズ ェクササイズのコーナーて、す。このコー ナーて、は , あなたにプログラムを考えても らいます。今回は未完成のプログラムを完 成させるという問題を用意しました。 C 言語入門講座 79 a[9]= 81 ; つまり添字の二乗が配列の要素の値となり TabIe 2 ニ次元配列の図 namae[i] [ 4 ] namae[i] [ 2 ] namae[i] [ 3 ] namae[i] [ 1 ] namae [i] [ 0 ] ' *xEA' ' *x8C' namae[O] [i] ' *x8D' ' *x91 ' ' *x8A' namaeC1 ] [i] ' \ X77 ' ' \ X94 ' ' \ X90 ' ' *x8C' ' *x EA' namaeC2] [i] ' \ X70 ' ' \ X89 '

6. 月刊 C MAGAZINE 1993年12月号

WeIcome to Macintosh mm の手の記事にまかせます。 THINKC て、はプログラムの作成をすると きに C 言語ソースを打ち込んだファイル (M acintosh 流にいえば書類ともいいますが ) と は別にプロジェクトファイルというのを作 成します。 マニュアルによれば「 . 司て、終わる書類名 て、プロジェクトファイルを作成することに なっているようて、すが , 英語システムての 字に相当する文字は日本語システムの場合 は半角カタカナの「ケ」に相当して , みつと もないため [ 4 ] , 筆者はマニュアルの推奨に 逆らい「 . pr 。 j 」て、終わる書類名て、プロジェク ーポインタを書き換えます。プログラムは トファイルの名前を決めています。 目的のメモリのアドレスを見るのて、はなく , DisposHandle(aHandle) ・ それから , 通常はこれ以外にリソースの 目的のメモリのアドレスが記録されている とするだけて、す。 作成をリソースエデイタて、行い この書類 NewHandIe によって目的のサイズのメモ マスターポインタを見て目的地にたどりつ 名を「プロジェクト名十 . rsrc 」て、つける約束 くようにします。こういうと一見ややこし リと , そこのアドレスを記録しているマス になっています (Fig. 6 参照 ) 。 そうて、すが , 今まて、、、 * 〃ひとって、書いて ターポインタを同時に確保します。 それから , ついて、といってはなんて、すが , いたものを、、 * クふたつに変史をするとか , そして最後に DisposHandle によって確保 プロジェクトの設定についても簡単にお話 、、 * 〃のなかったところに、、 * 〃をつけると したメモリおよびマスターポインタが解放 しておきましよう。本連載て、解説している いう手間だけて、す。今まてだったら , されます。 プログラムは , 当面はここて、設定している *aPtr, *aP Char スエテイタを使おう ロ とおりのパラメータ ( Fig. 7 参照 ) て、動作させ int ます。 C ソースとプロジェクトファイルは THIN さて今回から , リソースエデイタて、リソ aPtr = malloc(ALLOC SIZE) ; KC て、作成します。 C ソースは「 FiIe の New 」 ースを編集するという作業がて、てきます。 て、 , プロジェクトファイルは「 Project の Ne 本連載てはリソースエデイタの詳しい使い aP = aPtr ; w Project 」て、新規に作成します。リソース 方は説明しませんが , 最低限必要な扱い方 for()l = 0 ; 引く ALLC SIZE ; a 怦十 ) ファイルは THINK C て、はなく ResEdit( リ だけは解説しておきます。より詳しい説明 * a P 十十 = FIX DATA , ソースエデイタ ) て、新規に作成します ( Fig. 8 は市販のリソースエデイタの解説本や , そ Fig. 6 コンバイルで必要な書類 芸ロ 1 6 項目 NO. 4.c Fig. 5 八ンドルの図解 八ンドル ←マスターポインタ こは移動しない 移動可能フロック ここか削除されコンバク ションされたとする こは移動される マスターポインタの記録は書き替わるが , マスターポインタ自身は移動しないので 八ンドルの記録は変わらない free(aPtr) ・ としていたのをハンドルの場合は , Char * *aHandle, *aP ・ ロ 1 原稿 NO. 3 136 MB 用 int aHandIe = NewHandIe(ALLOC SIZE) ; 0.4.pro N prOJ aP = *aHandIe , for()l = 0 ; 引く ALLC SIZE, 引十十 ) ↑この行は変わらない * a P 十十 = FIX DATA , ↑この行も変わらない リソースファイル プロジェクトファイル C ソース Mac 専科 109

7. 月刊 C MAGAZINE 1993年12月号

が , このゲームて、は CPU て、行いました。 ところて、 , このスクロールルーチンはア センプラて、書かれています ( 参考文献 [ 4 〕の プロック転送テクニックを応用しました ) 。 実際には MASM を使ってコーディングした 後 , MS ー BASIC の配列にこのマシンコード を埋め込んて、 ( List 5 の②マシン語コードの セット ) 使っています ( 参考文献 [ 5 ] , List 5 の③ ) 。マシン語本体に注釈としてアセンプ ラのソースリストをつけていますのて、参考 にしてください BASIC 部分の処理 (List 5 の① ) はサププ ロシージャにあるように横方向の位置 dirtf をマシン語ルーチンに渡しているだけて、す。 マシン語部分はこの横方向の位置を受け取 り , メモリ内のグラフィックデータのその 位置に相当するデータを VRAM に転送して います。 この処理は当然 C 言語て、同じように書けま す。ただ , その場合注意しなくてはいけな い点があります。 BASIC て、は BYVAL VE RSEG ( ) て、マシン語ルーチンに引数をわた せばよいのて、すが , C 言語て、はセグメントと オフセットを渡さなくてはならない点て、す。 したがって , C 言語用のマシン語ルーチンは 引き数の数が BASIC の場合と異なってきま す。 List 6 に QuickC て、書いた場合のソース ( マシン語部も含む ) を示したのて、 , BASIC の場合と比べてみてください。違いがわか ると思います。 なお , スクロール用の画像データ ( べタフ ァイル ) は Z's STAFF 98 Ver. 2 を使って作 成し , このデータをスクロールルーチン用 に加工するのは加工用に自作した別のアセ ンプラブログラムを使いました。 ナ / デジタルティスプレイ自動判別 MS ー BASIC て、は VX21 以前の機種て、はア ナログディスプレイをつけていてもデジタ ル扱いになってしまいます。それだけなら いいのて、すが , アナログ関係の命令を書い てしまうと VX21 以前の機種て、それを実行し List 5 8 0 0 DATA &hlF DATA &h5D DATA &hCA, & h08 , & H00 背景スクロール ( C 言語版 ) ①スクロールサププロシジャ display() / * scdatab: 背景データブループレーン用配列ポインタ * / / * scdatar: 背景データレッドプレーン用配列ポインタ * / / * scdatag: 背景データグリーンプレーン用配列ポインタ * / / * scdataa: 背景データアナログプレーン用配列ポインタ * / / * boff : 方向 * / boff ニ (int)(dirtf); ptr=scdatab; pb=FP_SEG(ptr) : bboff=(unsigned int)boff + FP_0FF(ptr) : ptr=scdatar; pr=FP_SEG(ptr) : rboff=(unsigned int)boff + FP_0FF(ptr) ; ptr=scdatag; pg=FP_SEG(ptr) : gboff=(unsigned int)boff + FP_0FF(ptr) ; ptr=scdataa, pa=FP-SEG(ptr) : aboff=(unsigned int)boff + FP_0FF(ptr); scroll (pb, pr, pg. pa, bboff, rboff, gboff. aboff) : ②マシン語本体 scroll (unsigned int psb, unsigned int psr, unsigned int psg, unsigned int psa, 第 unsigned int bOff, unsigned int roff,unsigned int goff, unsigned int aoff) / * scroll mashine code * / asm Li st 0 start: push ds push es ax, psb mov dS, ax,0a800h si,boff mov ax, 5460h di, a.X mov bl, 01eh mov cx, 28h labell: cl d rep mOVSW add si , 0140h dec い b l, 0h jnz labe Ⅱ mov PS r dS, mov a.X SI, roff mov ax, 0b000h mov mov a,X ax, 5460h ßlOV di, a.X bl, 01eh ßlOV labe に : cx, 28h mov cl d rep movsw add si , 0140h dec bl cmp bl,0h jnz labe に mov psg dS, mov goff mov ax, 0b800h mov mov ax, 5460h mov mov bl,01eh mov labe : cx, 28h mov cl d rep mOVSW add si, 0140h dec い bl.0h ね b 引 3 jnz ;scroll BPLANE start aderess ;vram blue plane start adress : scroll offset : ( 0 認 70 ) ;sum of scroll : transfer Size line(3 の : 400 ー 80 ;scroll rPLANE start aderess ; scroll offset line ;sum of scroll ; transfer Size : 400 - 80 ;scroll gPLANE start aderess ; scroll offset ⅱ ne ;sum of scroll : transfer Size ; 400 - 80 C MAGAZINE 154 1993 12

8. 月刊 C MAGAZINE 1993年12月号

すると , プロジェクトファイルのウインド 右向きの矢印はプログラムの実行がその点 ザて、ある。 OOP 言語の代表格て、ある SmaIIt ウのタイトルバーの左端の所に「 Bug 」のアイ まて、進んて、いることを示す。プレークポイ alk ー 80 環境には , クラスハイアラーキプラ ントの設定 / 解除はマウスて、クリックするだ コンが現れ , それと同時にソースファイル ウザと呼ばれるツールが備わっていること 名の左側に小さな菱形が表示される (Fig. けて、ある。 はよく知られている。オプジェクト指向言 2 ) 。この菱形が「このファイルをデバッグの さて , デバッガて、ステップ実行をさせて 語て、は , プログラムが , 各クラスのメソッ 対象とする」という意味て、ある。 いると , しばしば変数の値を参照したくな ドの形て、分散して記述される傾向が強く , もちろんソースファイル単位て、選択的に る。これは Data ウインドウて、行うことがて、 手続き型言語の場合のように「ソースリスト デバッグ状態を ON / OFF て、きる。それには きる (Fig. 4 ) 。ここて、は Byte * て、ある nam をにらむ」だけて、は , プログラムの処理がど 菱形の部分をマウスて、クリックすればよい e という変数を参照している。 Byte は char を のように流れるのかを把握するのが困難て、 この状態て、「 RUN 」させると , 必要に応じて typedef したものて、 , 要するに name の型は c ある。そのため , オプジェクトのクラスを デバッグ情報っきてソースファイルが再コ har * て、ある。 Data メニューの中から表示の どのように宣言しているのか , その階層関係 ンパイルされ , 実行を開始する。 属性を変化させることがて、きる。この変数 がひとめて、見渡せるとたいへん都合がよい そうすると Fig. 3 のようなデバッガのウィ の値を Pointer 値として表示すると 0X00FIB Symantec C 十十て、はこの機能が備わって ンドウが開く。上に表示されている 6 個のボ、 140 となる (Pointer は 32ビットて、ある ) 。同じ いる。コンパイラに付属してくるデモプロ タン ( 「 Go 」「 Step 」「 ln 」「 Out 」「 Trace 」「 Sto 変数の値を C String , すなわち C 形式の文字 グラムのひとって、ある tinyEdit というソース p 」 ) が , ステータスパネルと呼ばれる部分て、 列として表示させると、、 test. s" となる。同様 て、定義しているクラスの階層関係 ( の一部 ) あり , それぞれのボタンは , 「連続実行 ( プ に , 今度は * name, すなわちポインタ変数 を示したのが Fig. 5 て、ある。非常にきれいな レークポイントに出会えば止まる ) / 現ソー name のポイント先の char オプジェクトの値 木構造になっていることがわかる。 スの 1 行実行 ( 関数呼び出しは飛び越す ) / 別 を 3 通り ( 10 進 , 16 進 , 文字 ) て、表示させたの 任意のクラスの箱をダブルクリックすると , の関数を呼び出すまて、実行 / 現関数から抜け がそのすぐ下の例て、ある。 そのクラス定義が行われているソースをオ るまて実行 / ソースの 1 ステップ実行 ( 関数呼 このような表示対象の式と , その表示属 ープンし , クラス定義のところへとカーソ び出しはその中を追っていく ) / 実行中断」を 性は , やはりプロジェクトファイルに記憶 ルが移動する。またクラスの箱をクリック 意味している。 されており , 一度 SymantecC 十十を抜けて すると , そのクラスて、定義しているメソッ その下に見えるのはソースウインドウて、 も , 再び後からまた用いることがて、きる。 ドがポップアップメニューとして登場する。 あり , それが現在実行中のソース位置を示 この Data ウインドウを用いて , 逆に変数へ そして同様に , そのメニューの中から特定 の値のセットを行うこともて、きる。 している。ソースウインドウの左側にある トレー のメソッドを選べば , そのソースのところ 白抜きの菱形は , そこにプレークポイント ス中に特定の値をセットしてみて , 何が起 にカーソルが移動する ( ことになっている ) 。 を仕掛けることが可能て、あることを示して この機能 きるかを観察したいことがあり , だが , 実際にはこれはテキストべースて、 おり , 黒い菱形はプレークポイントが設定 も便利て、ある。 サーチしているようて、 , 場合によっては変 されていることを示す ( Fig. 3 て、は下から三 なところに移動することもあるようだ。 クラスプラウザ つ目の菱形が黒くなっていて , そこにプレ ところて、 , クラス階層が常にこのように ークポイントが設定されている ) 。また黒い もうひとつ重要な機能が , きれいな木構造になっていれば何も間題は クラスプラウ Fig. 5 重要な機能のひとつ「クラスプラウサ」 Fig. 6 多重継承を行った場合の表示結果 ~ んれ戸んルは面 r 面 ws m test.cpp 0 0 ◆ 28 ー 0 0 28 ー 92 四一 88 2197 日 m Pro ect Tin E 由い・ . ケ 0 ・ 0 ・ 4428 432 392 30 ? 12 3 ー 04 い 2 8 48 ー 60 8 <CAppleEvent.CP> い都 k 尊 <CEditText.CP> ・圷第罅な上物棄幟第匯物臠朝譎箝 ! ↓囀 i 6 00 ノを、 ( -0 ツ 3* “、イ endl; 応ⅱ 0. VOid stOo<vOid) ( マ S ・ - ・・を 5 ■料物囀以百繍握第曜盟鷭物讎囿緡囃第物贔一群期 印第 0 メ第 :wirtual のい 0 0 ( 応い 0 . 0 ーー 0 x : ⅵ′れぬー応い 0 0 ⅵ”を、期ー新応い 0 」 x ( vOid ・ ( VO ー d ) ( 仮 : ト ~ ( わ めⅱ 0 ロ 0S5 Browser 80 ー x( 10. ~ 0 をも 06 」をイ ( リ・せ 10 物 ( ). 126 C MAGAZINE 1 3 12

9. 月刊 C MAGAZINE 1993年12月号

「 DOS の統合開発環境を実現」 ライフラリ関数のソースコートー - ーー完全公開 きわめて移植性の高いコードなのて , コンノヾイラのノヾーション・アップへの対応や , 異なるコンバイラ への移植作業はこ自身の手て容易に実行可能 0 組み込みロイヤリティーーーー無料 通常のアプリケーション・プロクラムへの組み込みに対するロイヤリティーは一切不要 ソフトの道具箱 4 み 「異機種の開発かあなたのマシンで OK み C/Dbase ( シーティーベース ) C/Window ( シーウインドウ ) ¥ 60 , 000 ( 機種別 ) \ 90 , 000 ( os 別 ) 検索ロジックに正当な Btree + アルゴリズムを採用 , 本格的データベース構築用関数ライプラリ。 提供関数群は ISAM 関数 , Data 関数 , Btree 関数の 3 グループこ大別。 ISAM 関数は一般的 な業務用データベースの構築に最適。 Data, Bt 「 ee 関数は文献検索システム、 CD-ROM 検索 システム等にも威力を発揮。 ・提供ライプラリ概要 ー完全マルチプロセス対応 ISAMlkJ 数群 : Data 関数と Btree 関数て、 レコードレベル、ファイルレベル排他制御を 扱う 2 つのファイルを統合し サポート。 ひとつのファイルとして扱う。 ー豊富な検索機能 一般的な業務用データベー キー値によるアクセスに加えて、レコード番号に スはこの関数群のみで扱える。 よるアクセスも可能。 Data 関数群 : レコードをアクセスするための ■削除レコードの復旧機能 関数群。 Btree 関数と組み 削除レコードはファイルのパージを行うまでフ 合わせて使用することにより、 ァイル内に存在するので、必要に応じて復旧 ISAM 関数だけでは実現不 可能。 可能な汎用的なデータベース ・充実したファイルの破壊対策機能 の構築を可能にする。例えば、 ファイルの整合性検証およびに修復の機能は 可変長レコードからなるデータ ユーティリテイだけでなく関数としても提供。 べースも作成可能。 ■高速な検索スビード BtreelkJ 数群 : BtreelkJ 数は、 Btree ファイル データ量が多くなるほど、威力を発揮。 をアクセスするための関数群 で、索引簿を管理する。この 索引簿では、検索の対象とな るデータとそれに対応づけられ た値が結合したひとつのオプ ジェクトとして管理される。 ・ WINDOWS 版 (DLL 方式 ) 対応 0 S : MS-WINDOWS(V3.0) MS-WINDOWS(V3.1) 対応言語 : Borland C 十十 ( V3.1) Microsoft C/C 十十 ( V7.0 ) ・ DOS 版 対応 0 S : MS-DOS, IX)S/V 対応言語 : Microsoft C(Quick C) Borland(Turbo) C 十十 ・ OS / 2 版 ( DLL 方式 ) 、 IJN Ⅸ版 対応 0 S : 問い合わせ下さい。 対応言語 : 問い合わせ下さい。 仮想画面いポートした本格的なオーバーラップ , 卩マルチウインドウ・アプリケーション開発用の関 数ライプラリ。グラフィックスもサポートしているので、きめ細かな 1 画面設計が容易に実現可能。 ■メモリ効率のよいグラフィック管理 ・異機種間の画面制御方式の相違を 線 , 距形 , 円 , 格円 , りつぶしマーカ , 枠 , すべて吸収 ひとつの機種て開発されたアプリケーション・ 背景模様 , グラフィック文字 , イメージデータ等 , プログラムがそのまま異機種で動作可能。 すべて図形として管理。 ■仮想画面の概念を導入 ・対応機種 : 巨大な仮想画面を設定可能。ビューとして物理 PC ー 9800 シリーズ , DOS. / V パソコン , J ー 3100 画面に投影。 シリーズ , FM-R シリーズ ・多彩なウインドウ操作 ・対応 OS : 拡大縮小 , 移動、表示 ON/OFF, 枠タイトル , MS-DOS, DOS/V 色 , タイル , 亜なり順序の変史。 ・対応言語 . ・強力なテキスト操作処理 Microsoft C (Quick C), 低レベルな入出力から高機能なスクリーンエデ BorIand (Turbo) C 十十 ィッはで日本語完全サポート。 C/Print ( シープリント ) ¥ 30 , 000 ( 機種別 ) 仮想べージ・プリンタ方式を採用したテキスト十グラフィックス印字ツール , C / Window と完全連動。 ラインプ ) ンタでもべージプリンタ感覚でレイアウト可能。 ■異機種パソコン / プリンタに対応 ・対応機種 : プリンタの機種依存部はすへて BIOS として常 PC ー 9801 シリーズ , DOS/V'€Y コン , J ー 3100 駐させるので , プログラムの変更なしに異機種 シリーズ , FM-R シリーズ パソコン / プリンタで出力が可能。 ・対応プリンタ : ーテキスト装飾機能 PC-PR201 系 , ESC/P 系 種々の文字サイズ , 文字属性 , 網掛けをサポ ・対応 OS : MS-DOS, DOS/V ・豊富なグラフィック処理機能 ・対応言語 : 図形表示 , 塗りつぶし全面 / 部分画面コヒ。 Microsoft C (Quick C) , BorIand (Turbo) C 十十 •C/Window と連動 C / Window にて作成された画面の印字も可能。※別売の C / Window が必要て、す。 C/Graph ( シーグラフ ) C/BCD ( シー七一シーテー ) ¥ 30 , 000 \ 30 , 000 1 つあるいよ複数のデータ系列から 13 種類の図表を簡単に作成可能。また , 各図表要素 ( キャンバ ス、軸 , セグメント . ラベルけし例 ) の属性の規定値を変史することにより , キャンバスの枠 , 背景色な どきめ細かい変史がグラフごとに可能。 ・対応機種 : ー多彩なグラフ種類 横棒グラフ ( 4 種類 ) 、縦棒グラフ ( 4 種類 ) , 折 PC ー 9801 シリース : DOS / V パソコン , J ー 3100 シリーズ , FM-R シリーズ。 れ線グラフ ( 2 種類 ) 、円グラスレータ・一チャー ・対応 OS : ト , 散布図をサポート。 ・多彩な図表要素 MS-DOS, DOS/V 種類豊富な枠形状 , 線種 , マーカ形状 , 文字 ・対応言語 : サイズ , 背景模様 , 塗りつぶしパターンをサポ Microsoft C (Quick C), BorIand (Turbo) C 十十 ※別売の C / Window が必要て、す。 ・上記価格には , 消費税は含まれておりません。 ※上記機種以外のパソコンへの移植も以下の条件にてこ相談に応します・・・・・・作業期間司 ~ 8 週問 , 受注価格 = 応談 , 受注条件 = 作業期問中パソコン貸与 ・ MS-DOS. MS-OS/2. MS-WINDOWS. MS-C. QUlCk c は米国 M ℃「 0S0 れ社の商標です。 Borland c 十十 . Tu 「 b0 C は米国 Borland 徹 e 「 na on 社の商標です。旧 M / 2 は米国旧 M CO 「 p. の商標です お金の計算のように高い演算精度が要求さオ処理を実現すこめの関数ライプラリ。サポートは 四則演算のみだが , doub への型変換を行えば科学技術計算も可能。また , BCD 型データは C / Dbase にてサポートされる ISAM キー値としてそのまま使用可能。 ・対応 OS : ー異 OS への移植か簡単 すべて C 言語で記述 , 異 OS への移植が容易。 MS-DOS, DOS/V ・対応言語 : ■豊富な編集機能 sprintf ( ) のよプょ手軽さで BCD 型のデータを編 Microsoft C (Quick C), BorIand (Turbo) C 十十 集可能。 ・開発元・販売元・問い合わせ先 AQLFT " ツールクラフト 〒 182 東京都調布市国領町 2 ー 3 ー 15 センチュリー K & AI 102 号 TEL. 0424 ( 89 ) 0202 FAX .0424 ( 89 ) 4888 く資料請求番号 184 〉

10. 月刊 C MAGAZINE 1993年12月号

more 未指定 (unspecified) 未定義 (undefined) たとえば , ここて、あげられているほかに も , 実行時にどのような文字セットを使用 するかとか , int のビット数が何ビットて、あ るかとか , double の表現範囲は 10 の何乗ま て、かといったような問題はすべて処理系定 義てある。 一方 , 最適化の具合によって , ケースパ イケースて、コンパイルのされ方が変化する ような項目 ( たとえば上にあげられている引 数の評価順序 ) 以外にも , 部分式の評価順序 や式内部て、の副作用の発生タイミングなど , あるいは , 文字出力て、 , 画面の先頭に出力 位置がいる状態て、ノヾックスペースの文字コ ードを出力すると何が起きるかとか , 静的 オプジェクトがいっ初期化されるかといっ た , コンパイラ以外の環境 ( 端末表示系やリ ンカなど ) にも強く依存するだろう項目や , さらには ( 意外かもしれないが ) , 浮動小数 型の内部表現の詳細といった項目は「未指 定」となっている。こうして見てみると , 未 指定と処理系定義というのは微妙な関係に あることがわかる。要は , いずれも処理系 や環境に依存して定められるものて、あって , そのうちて、 , 処理系製作者がドキュメント に明記することが要求されているものは処 理系定義て、あり , とくに明記する必要がな いもの ( したがって , 首尾一貫していなくて もかまわないもの ) が未指定となっていると 考えられる。 格準拠のプログラムとは さて , unspecified, undefined, implem entation-defined の説明が終わったのて、 , 次 に , 規格に準拠したプログラムとは何かと いう問題を考察してみよう (Fig. 4 ) 。 最初に一点補足をしておこう。最初のパ ラグラフの末尾の文の中の , 「処理系の制限 値に関する最低値の規定を越えてはならな い」は , 一見意味不明かもしれない。「最低 値を越えてはならない」というのは変に思え Fig. 2 三つの用語の定義① ( 1.6 DEFINITIONS OF TERMS ( 用語の定義 ) より ) ANSI C ー more 131 新しい右隣ピットの値へと伝搬する。これは定義された動作のはすである。 論理右シフトを行うならば , 新しい値は常に 0 である。しかし , 古い最上位ビットの値は , 確実に なるのかが問われているのである。算術右シフトを行うならば , 新しい値は古い値と同じになる。 注 : p 「 opagation は「伝搬」だが , ここでは実際にシフトした結果 , 新しい最上位ビットの値が何に ように処理されるかがあげられる。 「処理系定義動作」の例としては , 符号っき整数が右シフトされたときに , 最上位ピットがどの bit when a signed integer is shifted right. An example Of implementation-defined behavior is the propagation Of the high-order 「未定義動作」の例としては , 整数のオーパフロー時の挙動があげられる。 An example Of undefined behavior is the behavior on integer ove 用 OW. 「未指定動作」の例としては , 関数へ渡される実引数が評価される順序があげられる。 are evaluated. An example Of unspecified behavior is the order in which the argumentsto a function Fig. 3 三つの用語の定義② ( ANS 凵 .6 DEFINITIONS OF TERMS より ) おり , そして各処理系がドキュメントしていなければならないような動作をいう。 正しいプログラムの構成と , 正しいテータに関する動作で , 処理系の実装上の性質に依存して •lmplementation-defined behavior ( 処理系定義動作 ) しない。それらはすべて同一の「未定義である動作」を記述している。 する明示的な定義を省路していることで示される。しかし , これら 3 種類の表現の間に優劣は存在 ろでの未定義動作は , 「 undefined behavio 「」という用語で明示されているか , あるいは動作に関 といった要求に違反した場合には , その動作は未定義である。本標準において , それ以外のとこ 制約条件 (constraint) 以外の部分に記されている「 ~ ねばならない」とか「 ~ であってはならない」 実行を ( 診断メッセージを表示して ) 停止するといったところまでがあり得る。 ントされた方法で反応する ( 診断メッセージを出力してもしなくてもよい ) とか , あるいは翻訳や ものから始まって , プログラムの翻訳中や実効中に , 環境の性質に応じて , あらかじめドキュメ 作として許容できる範囲は , その状況を完全に無視してしまって , 予測不能な結果を得るという できないオプジェクトの使用に関する動作で , 標準が何も要求を行わないものをいう。未定義動 移植不能 , もしくは誤りのあるプログラムの構成 , あるいは誤ったテータ , あるいは値が決定 ・ Undefined behavio 「 ( 未定義動作 ) いう。 正しいプログラムの構成と , 正しいテータに関する動作で , 標準が何も要求を行わないものを ・ Unspecified behavio 「 ( 未指定動作 ) each implementation shall document. and correct data, that depends on the characteristics Of the implementation and that * lmplementation-defined behavior ー behavior, fO 「 a correct prog 「 am construct behavior that is undefined. behavior. There is no difference in emphasis among these three : they all describe by the words "undefined behavior 0 「 by the omission Of any explicit definition Of the behavior is undefined. Undefined behavior is otherwise indicated in this Standard げ a shall" 0 「 shall not" requirement that appears outside Of a constraint is violated (with the issuance Of a diagnostic message). without the issuance Of a diagnostic message) , tO te 「 minating a translation 0 「 execution program execution in a documented manner characteristic Of the environment (with 0 「 the situation completely with unpredictable results, tO behaving during translation 0 「 Standard imposes no requirements. Permissible undefined behavior 「 anges from ignoring 「 am construct, Of erroneous data, 0 「 Of indeterminately-valued objects, fO 「 which the behavior, upon use Of a nonportable or erroneous prog * Undefined behavior - data, fO 「 which the Standard imposes no requirements. behavior, fO 「 a correct program construct and C0「「 ect * Unspecified behavior ー