スデコード以前の MC68000 内のレジスタ資源 現しています ( List 2 , Fig. 4 ) 。 word は同様 は Pentium からはリトルエンディアンでその に 16 ビットレジスタに対して 8 ビットの巡回 ままアクセスできます。 シフト命令 ror を使って変換しています。 工ンディアンの変換処理は C のコードでは EX68 はこのほかにもインラインアセンプラ オーバヘッドが多くなるため , EX68 ではイン で記述している部分が多くなっています。 ラインアセンプラで , Pentium に用意されて れは MC68000 と Pentium では基本的にインス いるロングワードのエンディアン変換用イン トラクションの互換性がないとはいえ , 似た ストラクション、 bsw 叩を呼び出すことで実 性質のインストラクションが用意されている List X68000 資源の定義 Fig. 4 bswap の動作 b31 b0 3 0 1 2 0 3 2 1 / / c 部内部資源 MPU 定義 class u{ pub ic: ULONG ー d [ 9 ULONG —pc,—ppcy—USP'—ssp; //,—cyclecount'—lastcyclecount; //,—thiscycle; union { ULONG —sr,—psr; struct {UBYTE ー s て 0 , ー srl ! ー s て 2 , ー s て 31 ー s て 4 , ー s て 5 , ー sr 一 sr U{ONG ー土 ns セー p 辷て ULONG new—adr; U も 0 製 G last—access; struct { ULONG flag ・ ULONG levef; ULONG vector; U も 0 製 G reqbit; み み込一一 込み 読の の C5 0 0 0 ・ , tn O = 義 0 0 ・エ 0 0 ・ ( Cn tO 一ーー = の O O O にしじセー 1 tn ・ O 、 0 、 0 ー 1 ー 1 ーエをエー 1 マ tn tn ュて を 4 41 ′ 0 0 ) inter ー struct ( ULONG åbase; ノ / ULONG base; ULONG count ー / / 00 ー土北ー 0Y0 厄島動用貢順カウンタ ULONG frame; ULONG cur デ ULONG next—int—cyc ー e ー 〃次の割り込みのべクタ ULONG next—int—vect ー )cycle; ÜLONG func-code; ULONG rte ・ void reset( void init( ) ・ mpu( ) { 加土 t( / / X68000 資源を定義する class x6 ( public: UBYTE *mmem ・ mainsxze; ULONG 土 0 ーて eq ー ÜLONG ULONG system—req ー 土 n セ inner—L0 ー cfg—opt cfg—opt ー class UBYTE tme 爪 [ 512 * 1024 十 32 ] ・ gme 爪 [ 1024 * 1024 十 32L UBYTE class clk clk; class spr spr; class joy コ OY ー class てし c てし c ・ class midi mi 土・ class pal pal; class crtc crtc; class dma dma ・ class adpcm aåpcm; C lass sram; C lass SCC scc; class fm fm; class m p m p,• class fd fd ・ class vid VI Class class timer timer; elass wav; class key key; C ー ass mouse mouse ー class wdrv wdrv; ULONG prev—mode; int cur—focus ー in し a00 ー—fate ー spr, d-sprbg0 , d-sprbgl; —text 土北 d ー 9 て ap 4 土 f PERFORM class perf perf; #endif 土 n し vsyne—up ー UBYTE umem [ SRAMSI ZE 十 8 ] 引 UBYTE update ・ void load( リ c lass pal { public: union ( USHORT 加 em [ 256 十 256D ー UBYTE ー me 爪 [ 1024 pal( ) { u よい class sys { public: UBYTE て eg - [ 16 ULONG contrast; 土 n に power—seq ・ sys ( ) {power-seq= 6 羶 0 ・ CD ・ E O へ 1 」 十 1 」ー、・ , 編して ス 10 X ′、してセ 物 0 ・ー E て -0 -0 ー、 Z -0 ー 1 0 ・ 0 0 0 0 0 、 1 ー 1 、よ O よよ、よ 一ド - ー′ O 一、ま 0 よムよ 4 ー 0- 「 ( 、よ 0 //IM 42 C MAGAZINE 2000 7
◎⑨の F ペントミノ 第 112 回 今月の問題「ラドクリフの六角陣」には , ワシントンのクリフォードという人が 1910 年から検討を始め , 1957 年についにその解 答を見つけた , という有名な話がある。も ちろん , PC なんてなかった時代の話だ。今 回はユニークなアルゴリズムを期待したい。 4 月号の解答 正解は , 11 ピースを置くことができ , そ の配置は 1 通りであった (Fig. 3 ) 。 こうしたタイル詰めの問題のときは , 慣 れているせいか常連の方々の解答が目立っ た。盤を 1 次元配列で表し , ピースを回転・ 裏返しにした 8 通りのパターンを用意して 順次置いていく手法が一般的だ。今回のよ うに「すきま」がある場合には , そこに 1 X 1 のピースを置くと考えればよい。 ピースの形状を " - " と " * " といったキャ ラクタで表すなど , 形状の入力を容易にす るための工夫は多くの解答に見られた。し かし , FVX ントミノ以外のペントミノでも 解けるようになっている解答 ( もちろんこ の仕様は出題では要求されていない ) は非 常に少なく , とくに対称性のあるピースを 考慮していないものが多かった。 今回は , 標準的な解き方であり , タイル 詰めを勉強したい人が読むのに適した平田 豊さんと , FAO ントミノの盤上での置き方 をすべて求めてから解いている木村和人さ んの解答を紹介する。ふたりとも実行時間 が短い。 168 C MAGAZINE 2000 7 現します。ピースである FV< ントミノは回 の周りに壁を作り , 9X9 の 1 次元配列で表 データ構造は定石となっている 8X8 の盤 ・プログラムの説明 ( プログラムは付録 CD - 日 OM PUZZLEO 1 . C) 平田豊さんの解答 【 4 月号の問題】 1X1 の正方形五つを Fig. 3 のようにつないだものを「 F ペントミノ」と呼んでいる。こ の F ペントミノは , 8X8 の盤 ( Fig. 2 ) の上に最大何枚置けるだろうか。また , そのとき の置き方は何通りあるか。 置くときに , F ペントミノは回転・裏返してかまわない。また , 各ピースは必ず格子 に沿って置き , ピース同士を重ねてはいけない。もちろん , 盤全体の回転・裏返しで 同じになる置き方は , 別の解とはしない。 吉柄責樹 Fig. 1 F ペントミノ て記録し , 回転・裏返しで一致となる 5 ) ピースが指定枚数ぶん置けたら解とし になったらリターンする えておき , 探索途中で上限を超えそう 4 ) 枝刈りとして , U ピースの数を常に数 の構造上置くことができない ( 7 , 5 ) であり , 下 2 行には F/X ントミノ 3 ) ピースが置ける範囲は ( X , Y ) = ( 0 , 0 ) ~ 枚数を 12 枚から始め , 探索を進める 大 12 枚 ( U ピースは 4 枚 ) なので , 置ける 2 ) F/X ントミノは置けると仮定すれば最 テータを採取する 1 ) F ペントミノ・ビットマップから位置 法です。 探索アルゴリズムは次のような単純な方 空白の処理が楽になります。 扱いで置くようにします。こうすることで , でデータ化します。空白は U ピースという 置けるような形になるようにオフセット値 転・裏返しで 8 パターンあり , 9X9 の配列に かどうかのチェックを行う Fig. 2 8X8 の盤 Fig. 3 4 月号の正解 C P U : Pentiumlll EB560MHz であります。 さんの箱詰めパズルのノウハウが詰め込ん プから抽出するようにしてみました。たく すが , 今回は汎用性を持たせてビットマッ 手でパターンデータを作成してもよいので F/X ントミノのパターン数は少ないので ・感想
いる値が代入先の型で表現可能であるなら ば , 特別に縮小変換を許容しようというの がこのルールの趣旨である。たとえば代入 先が b e 型の変数の場合 , -128 から 127 まで の int の値であれば , 暗黙のうちに b e 型へ 変換され , 代入が行われる。 しかし , 日 g. 2 に示すようにメソッド呼び 出し変換においてはそのような特別扱いは 行われない。 int の実引数はあくまでⅲ t 以上 の引数にしか変換されない。これをしつか り認識しておかないと , 適用可能なメソッ ドがどれであるかの認識を誤ることになる。 listl をご覧いただきたい。このサンプル プログラムでは三つのクラス F00 , Bar , Baz を定義していて , それらは F 。。を頂点 とするサプクラス階層を形成している。そ してすべてのクラスで zot というメソッド を定義しているのだが , その引数の型が少 しずつ違っていて , F00. zot (double,doub (e) , Bar. zot ( ⅲ short) , Baz. zot(byte, char) となっている。 さてここで , クラス ListI の main メソッド の内側で , B のインスタンス myB に対し Java プロクラミングリファレンス 詳説 JDK 解体新 て , 加 t ( 10 , という呼び出しを行った場合 , どのメソッドが起動されるのだろうか。 まず実引数の型を調べると , (int,char) と なる。それに対してクラス Baz の zot は , 第 一引数が b e であり , int → b e の型変換は できないため , このメソッドは適用できな い。次にクラス Bar の zot は , 第一引数はⅲ t であって型変換可能 ( 恒等変換 ) であるが , 第二引数が short であり , char → short の型 変換はできないため , このメソッドもまた 適用できない。結局 , 適用可能なのはクラ ス Foo の zot であり , この場合ふたつの実引 数はいずれも double に型変換されて受け取 られる。もちろん , 実引数を明示的にキャ ストしたり , 変数を用いて型を指定したり することで , 特定のメソッドを適用可能に することもできる (Fig. 5 ) 。 もしも , 以上の条件を満たすメソッドが ひとつもなければ適用可能なメソッドは存 在しないということであり , コンパイルエ ラーである。逆に適用可能かつアクセス可 能なメソッドが複数存在する場合には , も っともよく適合するものを選択する。その 方法は Fig. 6 に示すルールに基づいて行う。 このルールは , スーパークラスよりもサプク ラスの側で定義されているメソッドのほう が , より引数の型を特定していれば , そち らがより適合するという内容である。いい 換えれば , サプクラスでのメソッドは , 引 数の型もサプクラスになっていればよい。 引数の型が数値型の場合には , サプクラス のメソッドの引数の型は , より表現範囲が 狭い型になっていればよい。つまりこれは , F1g. 3 に示した基本拡幅変換の図の矢印を逆 にした関係 ( たとえば , double → float , float →ⅲ t など ) であればよいということである。 このルールによって , もっとも適合するメ ソッドがひとつだけ特定できればそれを呼 び出す。しかし , その手順によってメソッ ドをひとつだけに絞ることができなけれ ば , 「呼び出しが曖味である」として , コン パイルエラーにする。この実例については 前回示したので , こでは省略する。 メソッド呼び出しの妥当性の検査 上記ふたつのステップを経て , 呼び出し Fig. 2 メソッド呼び出し変換として行われる 3 種類の変換 ( 1 ) 恒等変換 (identity conversion) (2) 基本拡幅変換 (widening p 「 imitive conve 「 sion) (3) 参照拡幅変換 (widening 「 efe 「 ence conversion) Fig. 3 基本拡幅変換 矢印の方向には基本拡幅変換が可能であり , 複数の矢印を経由してもよい。 たとえば , byte を dou e へ変換することもできる。 byte → short → int → long → float → double ↑ Cha 「 Fig. 4 代入変換の第 4 ルール ( 4 ) 基本縮小変換 ( na 「「 owing p 「 imitive conve 「 sion) ただしこれは ・式が int の定数式 ・変数の型が byte , sho 「 t あるいは cha 「 ・式の値が変数の型で表現可能な値のときにかきる 1 14 C MAGAZINE 20g 7 Fig. 5 List 1 のサンプルラン D:%cmaga%Javaref>java ListI F00. zot ( ( doub 厄 ) 10.0 , ( do 厄 ) 97.0 ) Bar. zot((int)10, ( sho て t ) 97 ) Baz. Z0セ((bYセe)10, (char)a) Fig. 6 もっとも適合するメソッドの決定ルール [ 前提 ] n 個の引数を持つメソッド m の呼び出しがあり , それに適用可能で , かっ アクセス可能なメソッドがクラス T とクラス U で定義されているものとする。 [ 条用 このとき , 以下の条件をともに満たせば T で定義されたメソッド m は U で定 義されたメソッド m よりもより適合するメソッドである。 ( 1 ) T はメソッド呼び出し変換によって U に型変換できる ( 2 ) 1 .. n のすべての j に対して , 仮引数工は対応する仮引数 U にメソッド呼び出 し変換によって変換できる ただし T で定義されたメソッドの仮引数を TI.. Tn とし U で定義されたメ ソッドの仮引数を UI ・・・ Un とする ー注意 ] この条件判断において , メソッドの返り型は考慮されない
J a フ恤クラミングリファレンス 詳説 JDK 解体新 呼び出し対象オプジェクトが特定されて パイルせずに古いバイナリを使うと実行時 static メソッドはコンバイル時に解決されている いれば , それにロックをかける。さもなけ にエラー (NoSuchMethodError) になる。 れば (static メソッドの場合 ) , ロック対象は Fig. 9 の ( 1 ) からもわかるように , 呼び出 P 「 ivate メソッドは仮想起動しない し対象メソッドが s ねⅱ c の場合 , それがどの 該当のクラスオプジェクトである。また該 F1g. 9 の ( 3 ) では , 起動モード "nonvirtual 当メソッドの実行が正常終了であれ中断終 クラスに属しているメソッドであるかはコ 了であれ , 完了したあとにはロックは自動 ンパイル時に決定されている。より正確に の場合の説明をしている。その影響を示す いえば , static メソッドの呼び出しコードが 的に解除される。 のが List 4 である。クラス F00 のなかで , メ 含まれているコンパイル単位をコンパイル ソッド b と zot を定義している。 baz は prote 注 . すべき動 した時点で , どのクラスに従属するメソッ cted であり , zot は private である。またこれ ドを呼び出すかが決定され , クラスファイ らを間接的に呼び出すメソッド callBaz と 以上の仕様からの帰結として , 呼び出す caIIZot を定義している。それから , F00 を ルのなかに指定される。したがって , 呼び 出される側のコンパイル単位で s ねⅱ c メソッ べきメソッドの解決については注意を要す extend したクラス Bar においても , 同様に ドを定義する位置をクラス階層の上に移 protected baz と private bar を定義している。 る動作が生じる。それらのいくつかについ て最後に簡単に触れておこう。 すような変更を行い , 呼び出し側を再コン そして , メソッド main のなかでは , シグネチャはコンバイル時に定まっている s 起動モード non ⅵ ua に起動モードⅵ「 tu 引 / * List5. javä * / * シグネチャはコンパイル時に定まっている class F00 ( public 0 土 d 20 日 in セ n, double x) { SY em. ou し prin れ ( ” F00. zo こ ( (int)* public void zot(byte b, do 曲地 x) ( system. out. printIn("F00.20日 (byte)" 十 b 十な public void qux(int れ , double x) { / * st4. java * / * 起動モードれ onv 辷 tu 引と起動モード v 近 t ー class F00 { protected void ) ( system. out.println( ” F00. baz っ private void 名 0t ( ) ( system. ou し . p て土 n 目 n ( ″ F00.20 セつ public void caIIBaz( ) { / / v 土て tu モード baz(); public void ca 日 20 セけ ( 〃れ 0 れ辻 u 引モード 20t ( リ 十れ十 % (double)" 十 x 十つ” ) ・ ( do 曲厄ド + x + 物尸わ ( do 面厄尸十十つつ・ system. 0uしPてin凵n(”F00. qux((int)" 十 n 十” class Bar extends を 00 { public void zot(byte b, int m) ( system ・ out.println("Bar. 20t( (byte)" 十 b 十 public void x ( 土北 n, dO x) { system. out. printIn("Bar. qux( (int)" 十 n 十 public void qux(byte b, do 面 le 幻 ( class Bar extends を 00 { protected void baz( ) ( system. out. println("Bar. baz 0 て土 va セ e void 20t ( ) ( system ・ 0uしPて土n日nに Bar. 20 し (int)" 十 m 十つ″ ( do 面厄尸十 x 十”ド system. out.println("Bar. qux( (byte)" 十 b 十第 , (double)t 十 x 十物尸リ 0 lass List4 extends Bar { public static void main(String[J args) F00 myFOO = new F00 ( ) ー て myBar new Bar( system. out. println( ” F00 つ myF00. caIIBaz( リ myFoo. callZot( system. out. println(" system. out. printIn("Bar"); myBa て . caIIBaz( myBar ・ callZ0t( system. out. println(* system. out. Pて土n凵nにF00 but holds a Bar" リ myFoo ま myBar; myF00. caIIBaz( myFOO. ca Ⅱ 20 日 c lass も土虻 5 { public static void main(string[ ] args) F00 myFOO ま new F00 ( ) ・ Bar myBar = new Bar( byte b ま 1 の system. out. Pて土n凵nにF00”リ myF00. zo 日 10 , 20 myF00. zot(), 20 リ myFOO. qux(10, 20 myF00. qux(), 20 リ System ・ 0uしPてin日れに system. out.println("Bar") 引 myBar. Z0t(10, 20 ) : myBar. zot(), 20 myBar.qux(10, 20 myBar. qux(), 20 潺 system. ou し printl n に system. out. println( ” F00 but holds a Bar"); myFoo = myBar; myFOO. zot ( 10 , 20 myF00. zot(), 20 myFOO. qux(10, 20 リ 叫 F00. q 皿 ( b , 20 ) を 1 18 C MAGAZINE 2 0 7
・空行忘れに注意 私が POD で作業したときにしよっちゅう ひっかかったのが「空行忘れ」です。コマン ドバラグラフのあとに空行を忘れたため , 通常のパラグラフまでがコマンドバラグラ フの一部になってしまったのです。 POD を書くときは , きちきちと行単位で ドキュメントを書くのではなく , ゆったり と空行で区切られたパラグラフを書くとい う気持ちになると間違いが少ないようです。 類似技術 組版することもできます。最新情報は以下 書かれたファイルはそのまま TeX を使って 閲覧することができます。また Texinfo で Emacs の画面上でハイバーテキストとして Texinfo を Emacs の info 形式に変換すると いは . texinfo になっています。 式で書かれたファイルは拡張子が . texi ある でマークアップを行います。 Texinfo の形 ァイル中に@で始まるコマンドを埋め込ん いるドキュメントの形式です。テキストフ Texinfo は GNU プロジェクトで使われて ・ Texinfo メントを混在させる技術を紹介しましよう。 に変換する技術 , またプログラムとドキュ ひとつのテキストを複数のフォーマット http://www.mathematik.uni-kl.de/ ・ Texi2html 換するプログラムは以下にあります。 また Texinfo 形式のファイルを HTML に変 http://www.texinfo.org/ ・ texinfo. 0「g を参照してください。 * / でくくられたコメントが書かれて Java で書かれたソースコードのなかに / * ・ javadoc -obachman/Texi2html/ いると , その部分は javadoc というツールを 使って抽出することができます ( コメントの 始まりが / * ではなく / * * であることに注 意 ) 。たとえば Hello.java という Java のソース javadoc He110. java があったとして , ツールとはいえません。 ないので , POD は文芸的プログラミングの グラムの順番を並べ替えたりするわけでは 在できますが , ドキュメントの順番やプロ POD でもプログラムとドキュメントを混 にもっともふさわしい順序で記述されます。 順序とは独立に , プログラムを解説するの やドキュメント記述言語 ( たとえば TeX) の 書かれ , プログラミング言語 ( たとえば C) は , ドキュメントとプログラムが混在して 現したものです。文芸的プログラミングで うプログラミングスタイルを C と TeX で実 ログラミング (Literate Programming) 」とい CWEB は D. E. Knuth が提唱した「文芸的プ ・ CWEB plain2/plain2-j. html http://shika.aist-nara.ac.jp/products/ ・ plain2 fan 下の U Ⅲどが参考になります。 クアップを行うときに有効だそうです。以 とえば RFC などのプレーンテキストにマー です。私は使ったことがないのですが , た ストにマークアップを付けるというツール plain2 はマークアップされていないテキ ・ p 回 n2 javadoc/ http://java.sun.com/products/jdk/ ・ Javadoc TO 引 Home Page については以下を参照してください。 に非常に強力なツールとなります。 javadoc れはプログラムの API 仕様書を作成する際 む HTML ファイルを生成してくれます。 抜き出し , クラス階層図やインデクスを含 とします。すると He Ⅱ o.java からコメントを Pe プログラミング の楽しみ 文芸的プログラミングについて , 詳しく は以下の U 糺を参照してください。 ・ The CWEB System of Structured Doc umentation http://www-cs-staff.Stanford. EDU/ -knuth/cweb. html ・ Literate Programming Library http://www.desy.de/user/projects/ LitProg. html ・ Literate Programming Propaganda and T00 http://www.cs.cmu.edu/- vaschelp/ Programming/Literate/Iiterate. html ・ MakeWeb 最後に , 私が自分のサイトを構築すると きに愛用している Perl スクリプトも紹介し ておきます。おもに - で始まるコマンドを埋 め込んだテキストから HTML を生成するツ ールです。私のサイトにある HTML ファイ ルはすべてこのスクリプトで作成していま す。詳しくは以下を参照してください。 ・ MakeWeb http://www.hyuki.com/makeweb/ 次回は「リファレンスの楽しみ」 今回は POD について学びました。いかが でしたか。次回は「共同作業の楽しみ」と題 して , perl で作った文字コードチェッカー のお話をします。これはインターネットの 図書館「青空文庫」向けに作成したツール です。どうぞご期待ください。 もしも , ご意見やご質問がありましたら , 本誌綴じ込みの編集部へのハガキでお知ら せくだされば幸いです。また , ご遠慮なく 結城浩くhyuki@hyuki.com/ へメールをお送 りください。本連載に関するメールには表 題に [ M 日という文字を含めていただけると 助かります。本連載に関する U 糺は , http://www.hyuki.com/mp/ です。 perl プログラミングの楽しみ 97
MONTHLY HEADLINE Events AMD DeveIoper's Conference ℃ O Spring 日本 AMD は 5 月 11 日 , 都内のホテルに おいて「 AMD Developer's Conference ' 00 Sp 「 ing 」を国内のテべロッパ数十社 を対象に開催した。現在のプロセッサ市 場の動向や AthIon の技術概要をはじめ , NEC 製 3D グラフィックアクセラレータ 「 TE4 」や nVlDlA 製「 GeForce2 GTS 」を使 用したデモンストレーション , さらにサ イバーリンク社の「 power DVD 2000 」 , 「 PowerVCR Ⅱ」によるエンハンスト 3D Now ! テクノロジによる M P EG 1 / 2 のソ フトウェア工ンコード / デコードの最適 化技術 , 同クロックの Pentium Ⅲとの工 ンコード対決も行われるなど意欲的なカ ンフェレンスとなった。 現在の市場動向と Du 「 on / Thunderbird AM D は , 確実に売り上げを伸ばして いる。とくに世界第 2 位の市場である日 本では , バリュー PC の拡大によって , コストパフォーマンスに優れる K6-2 が テスクトップペースでは実に 40 % を超 えるシェアを獲得し , トップシェアのプ ロセッサの地位を築いている。ノート PC においても , 0.18 ミクロンに移行し 工ンハンスト 3DNow ! に対応した K6-2 + , K6- Ⅲ + を登場させ , Super7 べースによ るコストパフォーマンスを追求している。 ハイエンドにおいては 1 G Hz 動作の At hlon を lnte はりも早く発表し , 高クロッ ク C P U の生産能力においても lnte 陸上 回ることを証明した。 VIA 製の KX 133 チ ップセットも登場し , 対応マザーポード じゅんたく も潤沢に市場に流れている。さらに , N EC, 富士通 , Gateway など大手 PC メー ◎ URL URL http://www.amd.com/japan/ 160 C MAGAZINE 2000 7 カーも続々と AthIon 搭載モデルを登場さ せるなど , AM D にとっては追風が吹い ている。また , 本誌が発売されるころには , Ath lon の K75 コアにフルスピードの 2 次 キャッシュを搭載し , SocketA に対応し たバリュー PC 用の「 Duron ( テュロン : コードネームは Spitfire ) 」が登場してい るはずだ。さらに次世代 Ath lo n として D u ro n よりも大容量の 2 次キャッシュを 内蔵した Thunderbird の登場も近い。 GeForce2 GTS による AMD プロセッサへの最適化 nVl 引 A のセッションでは , 最新グラ フィックチップ「 GeForce2 GTS 」が , At h lon をはじめとする AM D プロセッサに シリコンレベル / ソフトウェアドライバ レベルで最適化されており , 性能が大幅 に向上していることを示した。とくに At hlon の強力な処理能力とエンハンスト 3 DNow ! との組み合わせによって最速の 環境を構築できるとしている。 Power DVD 2000 と Power VCR Ⅱにおける 工ン、ンスト 3DNow ! の効果 サイバーリンク社のソフトウェア DV D 「 power DVD 2000 」とソフトウェア VC R 「 power VCR Ⅱ」では , MPEG1/2 のテ コード / 工ンコードにおけるエンハンス ト 3 D Now ! の効果が著しいことが示さ れた。 とくに , Power VCR Ⅱのエンコード においては P e n t i u m Ⅲの S S E と At 用 on のエンハンスト 3DNow ! の両方に最 適化した場合の同クロック対決のデモが 行われ , コマ落ちが著しい Pentium Ⅲに 対して , AthIon は滑らかな映像を再現し た ( 数値化した場合 , AthIon/700MHz は PentiumIII/866MHz にほば相当 ) 。 こ , 命令セットごとの貢献度は , 3 DNow ! < MMX < 工ンハンスト 3DNow ! の順に大きくなっていることも示された。 工ンハンスト 3DNow ! の意義 X86 プロセッサは MMX Pentium の MM X ( 57 命令 ) の搭載を皮切りに , K6-2 の 3DNow ! ( 21 命 -TZ ) , Pentium Ⅲの SSE ( 69 命令 ) , Athlon のエンハンスト 3DNO w! ( 24 命令 ) というように 3D グラフィッ クス , イメージング / ビテオ , 音声認識 などの分野に効果的な命令セットを追加 してきた。 しかし , 豊富な命令セットもソフトウ ェアが対応していなけれは何ら意味がな い。これまでも 3DNow ! や SSE の命令 を使用すると , 劇的にパフォーマンスが 改善することが指摘されてきた。旧回製 CPU がほとんどのシェアを占有してい た時代ならば , SS E にだけターゲット を絞ればよかったが , AM D が今後も勢 力を伸ばした場合には , 3 DNow ! への 最適化も無視できないことになる。とく にエンハンスト 3DNow ! のうち SS E と 機能が同じ 1 9 命令は , SS E とニモニッ クが同じなので , プログラマの負担が軽 減されている。 高速化のためにあれこれ苦闘するより も , 拡張命令を使用するだけで劇的なパ フォーマンスアップが期待されるとなれ ば , それを使わない手はない。 ( 高橋良明 )
List 37 デストラクタ内の例外対策 いい気軽さを狙って , 間があるものの筆者がよく利用する手法で TestMain で auto_ptr を使っています。 す。たとえば , 先ほどのクラスは , List 35 のようにすると , 初期化関数で例外が起こ りますが , きちんとデストラクタは呼ばれ , デストラクタ内で例外を起こす また mBu 肥が不定値にならないので , 不定 深刻度☆☆☆ 値の delete という事故を防止できます。 ところで , このコンストラクタ内で例外 [ 症状 ] 資源の解放忘れやメモリリークを引き起 をさせない , という筆者の方針ですが , わ こし , その結果で起きるバグに悩まされま りあい反発を受けることがあります。まず いという意見もあります。ただし , チーム コピーコンストラクタが使えなくなる場合 す。 開発などで , ほかのメンノヾのスキルが怪し [ 原因 ] があるとか , 記述がスッキリしないなどで そうな場合は , なるべく避けたほうが吉だ デストラクタ内の例外の問題点を把握し す。それと初期化関数を呼び出すことを亡 と思います。 ていないためです。 れる , という別のトラブルも起こりそうで [ 備考 ] [ 対策 / 予防 ] す。実は初期化関数の呼び忘れを防止する これもコンストラクタ内の例外と似たよ デストラクタ内では , いっさい例外を起 テクニックとして「ファクトリ・メソッド・ うな状況ですが , 後始末処理をする副作用 こさないようにするか , 例外が起きても解 パターン」と呼ばれるテクニックがありま で例外が起こるケースもありえます ( たと 放忘れの弊害が起こらないような対策をと す。 えばファイルクローズで書き込み処理が行 るとよいでしよう。 これは , List 36 のようにコンストラクタ われ , そのときに書き込み工ラーを知らせ [ 例外 ] と初期化関数を p ⅱ vate メンバにして外部か る例外が起こるなど ) 。したがって , 例外 デストラクタ内で例外が起きても , それ ら呼び出せないようにし , 代わりにインス が起こりそうな部分に関しては , そこから をリカバリする対策を考慮しているならよ タンスの発生と初期化をする sta ⅱ c メンバ関 外に例外が飛び出さないように try-catch で 数 ( ここでは create という名前にしている ) ファクトリ・メソッド・バターンの例 「蓋」をしておくとよいでしよう。たとえば を作る , という手法です。ただしポインタ 社れ clude <memo て List 37 のようにします。 を返す関数なのが問題です。ここの例では , 0 ね BadCIass { 細かいことにこだわる人だと , デストラ 自動変数的な明示的に後始末をしなくても ghar* mBuff1; char* mBuff2; クタで例外が起きたことをあとから知りた 初期化関数を用意する BadCIass( ) ( いという , ある意味 , ないものねだりをし ( 中略 ) ,. class BadCIass ( ますが , どうしても知りたいなら「例外告 void lnit(void)( char* mBuff1 char* mBuff2 知」用の sta ⅱ c メンバ変数を用意して , 例外 public: public: BadCIass( ) { &BadClass()( のときは , それを書き換えるというのはど cout く物 *C start**nn mBuff1 キ NULL; うでしよう ? mBuff2 = NULL; cout くく一 * C e れ d * n 引 gtatic BadCIass* create( ) { BadCIass* theAns ま NULL• lass ( ) ( ポインタを th 「 ow する , 00u しくく "*D start**n theAns new BadClass; delete[ 1 mBuff1; 価「 ow new 例外クラス」とする theAns+Init( delete[J mBuff2; 00u に << D*D end*%nn catch (. 深刻度☆☆ 0 引 e し e theAns;- 0 土 d lnit ( void ) ( theAns NULL; mBuff1 = new ehar[SMALL-SIZE]; [ 症状 ] cout "mBuff1 ällocated.vnn return theAns ー mBuff2 = new char[LARGE—SIZEl; catch したポインタを解放しないことによ cout くく "mBuff2 allocated. 蕚n第 る資源の解放忘れやメモリリークを引き起 こし , その結果で起きるバグに悩まされま す。また解放してはいけないのに間違って 解放することによる弊害が起きる場合もあ りえます。 [ 原因 ] ポインタを throw する問題点を把握して Testc lass ( ) ( .. ( 中略 ) try( F ec se ( リ〃ここで例外が起こりうる catch( .. List 36 List static void TestMain ( void ) BadClasS theB; theB. lnit( . を ( 中略 ).. static void TestMain(void) auto—ptr<BadC lasss theB(BadClass: :Create( ) 32 C MAGAZINE 2000 7
って「性別不明の人間もカウントしたい」と で求めるというドジ ( 笑 ) をしていた場合は なったとき , 先ほどのメンバ変数を直接い 除きます ) 。 メンバ変数を pub ⅱ c にする じる例では人数の合計を単純に「女性の数 + メンバ変数を直接読み書きした場合 , そ 深刻度☆☆☆ 男性の数」で決め打ちしていますが , この の読み書きの正当性のチェックがたいへん [ 症状 ] 種の「決め打ち」をしている箇所をすべて洗 になるケースがあります。直接メンバ変数 直接メンバ変数をいじられることで , プ い出して , 性別不明の人間の数の加算を付 に加算せずに AddFemale や AddMale を使っ ログラムの挙動がおかしくなったり , クラ け加えていかないといけません。修正箇所 たほうは , 加算する数値がマイナスでない が少なければいいのですが , 多数にわたる ことをチェックしていますが ( ここではマイ スのバグ取りやバージョンアップがしにく 場合は , そのすべてを探し出し , 正しく修 くなります。 ナスだったら例外が起きるようにしていま [ 原因 ] 正できたかを検証する手間がばかになりま す ) , メンバ変数を直接いじった場合でも メンバ変数を pub ⅱ c にすると弊害が起き 同じことをしようとすれば , メンバ変数が せん。 一方 , 合計を GetTo ね 1 ( ) で求める方式に ることをわかっていない。というか , オプ 使われている箇所をすべて洗い出し , その した場合 , 変更は Ge 。 tal ( ) の中身だけ , ジェクト指向の基本理念をわかっていない すべてに検証コードを追加していかないと つまりたった 1 か所の変更だけで済みます。 のです。 いけません。 [ 対策 / 予防 ] 検証作業も , たいした手間にはならないで メンバ変数を直接触るとマズいほかの例 勉強しなさい : - ) 。 しよう ( ただしクラスを使う側が , 合計を としては , 仕様変更によって変数では表現 [ 例外 ] GetTotaI ( ) でなく GetFemaIe ( ) + GetMaIe ( ) しきれない状況が出るケースです。たとえ なし。 メンバ変数を直接いじらせない例 [ 備考 ] #incl ude kiostream> 残念ながら , これはオプジェクト指向の ~ *include <exception> using namespace std; 「理念」をわかっていないゆえに起きる現象 之 class countpeople ( です。というか , わかっていれば , 最初か / / 女性の数 土 n し mFemale; らメンバ変数を public にするという思かな ノ / 男性の数 一土 n mMale; public: 行為はしません。メンバ変数を public にし class 00 n し Peop 厄を xcept 土 0 れ ipublic 、 exception { public: v 辷 t リー const char* what( ) ℃ 0 れ s し ( return "CountPeopleException"; ているかどうかを調べることは , そのプロ グラマがオプジェクト指向を理解している countpeople( ) ( Reset(); void Reset( ) ( mFemaIe = mMaIe = かどうかのリトマス試験紙代わりに使える int GetTotaI(void) const { return mMale 十 mFemale; ånt GetFemaIe(void) cons し ( て e セ u てユ mpemale; といっても過言ではありません。 土 n セ GetMaIe(void) const ( return 心危 void AddFemaIe(int inAdd) { メンバ変数に直接アクセス可能にした場 if(inAdd > 0 ) { mFemale 十 = inAdd; 合 , 将来的に変更があって , そのメンバ変 )else{ throw CountPeop leException( 数が消滅したり , あるいはまったく内部の 実装が変わってしまったときに , クラスを void Ad 硼 e ( 土北 inAdd) 。 { if(inAdd > ま -0 Ⅱ 利用する側も同じように変更せざるをえま 心 ! 引 e 十ま inAdd; )e lse{ throw CountPeopIeException(); せん。 たとえば , List3 のような男女の数をカウ ントするという単純なクラスがあったとし ましよう。見てわかるとおり , 完全にクラ スを構造体と勘違いしている例です。とこ ろが , これでは何のためにオプジェクト指 向を導入したのかわかりません。 List4 はメ ンバ変数を pub ⅱ c にせずに「きちんと」プロ グラムした例です。こうすることで何がよ くなるかというと , まず仕様変更に強くな ります。というのも , こで仕様変更があ 18 C MAGAZINE 2000 7 List 8 セ a セ土 0 void TestMain (void) CountPeopl e theCounter ー theCounter. AddFemaIe(1); thecounter. AddMale(2); 冖 ( 中略 ) を 00u しくく "female = くく theCounter. GetFemale( ) endli cout く "male か << theCounter. GetMale( ) くく endl; cout くく”セ Ota ーキ”くく theCounter. GetTotal ( ) くく endli
Wjflf1011JS P 第踟 m 第 8 回 tatS uya(tatsuya3@mtci.ne.jp) ファレを操作する 前回は , ファイルのさまざまな情報を取得するシェル関数を使った Tips を紹介しました。そこ で今回は , ファイルに対して操作を行うシェル関数 , SHFileOperation を紹介します。 / SH 系関数によるファイル操作 今回は , ファイルを扱う SH 系関数の SH FileOperation 関数を利用します。この関数 削除 , 移動 , リネ は , ファイルのコピー ームの四つの動作を設定できます。 シェル関数なので , シェルに密接に関連 した動作をするのが大きな特徴です。 Win32A との違い 上記の四つの動作をする関数は , 通常の Wm32API でも網羅されています (Table 1 ) 。 では , SHFileOperation 関数と Table 1 の API とでは何が違うのでしようか。 たとえばファイルのコピーを行う C 叩 yFile API では , コピー元とコピー先 , 動作内容 を設定するだけなので , 非常に簡単です。 しかし , 工クスプローラでコヒ。ーを実行し TabIe 1 Win32A 曰によるファイル操作 たときのようにプログレスダイアログボッ スを表示できるわけではありませんし , 削除のときに自動的にゴミ籀に移動できる わけではありません。そのような動作をす るようにコーディングすることは可能です が , そのためには細かなコーディングが必 要になります。しかし SHFileOperation 関数 を使うことによって , このような動作設定 がフラグ設定だけで可能となるのです。 また , このようなことはユーザに対して インタフェイスを統一するという観点から も非常に大きなことでしよう。あるアプリ ケーションではファイルがゴミ箱に移動せ ず直接削除され , 工クスプローラではゴミ 箱へ移動するというようにバラバラな挙動 サンプルプログラムを起動すると Fig. 1 【サンプルプログラムの動作 をしていては , 迷うのはユーザです。 Fig. 1 サンプルプログラムの動作画面 ファイル情幸り通知 DOSIME. SYS Favo 「汁 FRUNLO(). TXT intersync_ce 9. SYS 、 = jperl ~ JRTraNavi fo 「 Palm kaoime98u. C C MAGAZINE dow 「扣 ad 。 Delete Rename Copy Cancel BOOL CopyFile(LPCTSTR IpExistingFileName, LPCTSTRlpNewFileName, BOOL bFaiIIfExists); 内容 引数 返り値 ファイルをコピーする IpExistingFiIeName 既存ファイルのファイル名が入った文字列へのポインタ lpNewFileName bFaillfExists 新しいファイルのファイル名が入った文字列へのポインタ する るとコピーは行わず関数は失敗し . FALSE を指定すると既存のファイルを上書きして関数は成功 NewF ⅱ eName 引数で指定したファイルが存在していたときの動作を指定する。 TRUE を指定す 成功時は T 日 UE. それ以外は FALSE BOOL DeleteFiIe (LPCTSTR IpFiIeName); 内容ファイルを削除する 引数 lpFiIeName 削除するファイルのファイル名が入った文字列へのポインタ 返り値成功時は TRUE, それ以外は FALSE BOOL MoveFile (LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName); 内容 引数 返り値 ファイルを移動する。もしくはファイル名を変更する lpExistingFiIeName 既存のファイル名またはディレクトリ名が入った文字列へのポインタ lpNewFileName ファイルまたはディレクトリの新しい名前が入った文字列へのポインタ 成功時は T 日 UE , それ以外は FALSE のダイアログボックスが表示されます。 右側にある五つのボタンは , 上からファ イル削除 , リネーム , コピー , 移動となっ ており , 最後のボタンがシェルへの通知ポ タンです。ファイル削除はリストボックス で選択したファイルをゴミ籀へ移動します。 リネームでは newtes ⅲ le というファイル名 に変更します。コピーおよび移動はフォル ダ選択リストで指定したフォルダへコピー 移動します。シェル通知については後ほど 紹介します。 Windows Programming Tips 133 イルへの操作内容を設定します田 st 1- ② ) 。 U ロ、構造体が必要です。この構造体にファ SHFiIeOperation 関数では SHFILEOPSTR ファイルの削除 送信しています ( List1- ① ) 。 ( リストボックスから文字列を取得する ) を ックスに対して LB_GETIEXT メッセージ また , ファイルの選択部分では , リストボ プに限定してコーディングしてあります。 左側にあるリストボックスは , C ドライ リストボックスの処理
C マガ テクニック第 24 回「ペントミ らせます。また禁止ゾーンを設けずに済む S : Windows 98 SE 0 ノの箱詰め」 , 松田晋 , C MA ので , 8X 8 の盤でもビットパターンで無理 コンパイラ : Borland C + + Builder 4 GAZINE, June 1994. オプション : -02 -3 なくプログラムできます。 実行時間 : 0.14 秒 さていちばん重要な対称解の排除ですが , ( ( 正解者からのメッセージ・ 参考文献 : なし 盤を回転・裏返しにした際に , 最初に置か こ 2 か月の問題では再帰でプログラム れたピースより前の位置にくるピースを , 筆者注 : こでは本質的な問題ではないが , をうまく作れなくて , 苦労しました。 初めから除外するようにしています。ただ コンパイラによっては平田さんのソース内 ( 東京都廿日出悟 ) これだけでは完全に対称形を排除できない の時間表示部 ( 353 行目 ) でエラーが発生す 正解が得られるまでのパソコンの実働 ので , 籀詰め終了後に対称解を調べていな る。そのときは double でキャストするとよ が 200 時間 ( 就寝時間も含む ) 必要でした。 いかチェックしています。 ( 神奈川県山内忠雄 ) ・感想 木村和人さんの解答 対称解を排除するような拘束条件を見つ そのほかの正解者 ( 順不同・敬称略 ) ( プログラムは付録 CD - 日 OM PUZZLE02. C) けられなかったことは残念ですが , けっこ ういい枝刈りができたようで , 実行時間に ・プログラムの説明 奧田芳史 ( 奈良県 ) ・岡本治 ( 京都府 ) ・花田康守 は満足しています。 F ペントミノを 8X8 の盤に置く場合 , 置 ( 大阪府 ) ・後藤俊介 ( 東京都 ) ・高森啓輔 ( 石川 C P U : MMX Pentium 166MHz き方は 288 通りあります ( 向きが 8 通り , 位 県 ) ・高田庸介 ( 兵庫県 ) ・佐々木康朗 ( 大阪府 ) ・ S : Linux Version 2.2.5-22 ⅳ 3 0 置が 36 通り ) 。このプログラムでは 288 枚の 佐藤武史 ( 栃木県 ) ・小林貴之 ( 東京都 ) ・小林和 (LASER5 Linux 6.0 ReI.2) ピースをすべて作成し , これを先頭の位置 人 ( 千葉県 ) ・松村克己 ( 神奈川県 ) ・上島一彦 ( 東 gcc (egcs-2.91.66 ) コン / ヾイラ . ( いちばん上の左端 ) によってハッシュテー 京都 ) ・石井幸一 ( 埼玉県 ) ・竹綱久次 ( 大阪府 ) ・ オプション : -02 -funroll-loops プル ( ね ble [ ] [ ] ) につないでいます。 竹内真一 ( 東京都 ) ・中根吉正 ( 愛知県 ) ・武田靖 実行時間 : 1 .36 秒 これによって盤の外にはみ出た置き方を 彦 ( 香川県 ) ・北光二 ( 東京都 ) ・網野秀昭 ( 福岡県 ) 参考文献 : 実践アルゴリズム戦略解法の 調べずに済むので , 演算数が約 8 分の 6 に減 応募の規定 パズルの回答を導き出すプログラムを作成 し , 下記の応募規定に従って下記の宛先に解 答をお寄せください。 締め切りは 7 月 18 日必着。 ・パズルの表題 , 解答の明記 ・作成するプログラムは c 言語のみ ( C + + は不可 ) ・ CPU , OS , コンパイラ , オプションスイツ チおよび実行時間の明記 ・プログラム作成に参考とした文献 , プログラム ・ 800 字以内のプログラムの感想と説明 ・連絡先 ( 氏名 , 住所 , 電話番号 ) ・ペンネームは不可 上記をすべてテキストファイルに記述し , 関連ファイルと共に下記方法で送付。 LHA / ZIP 形式による圧縮アーカイプを推奨。 ・電子メールで応募する場合 , 添付ファイル , ish ファイル形式のいずれか ・ディスク送付にて応募する場合 , メディア は MS-DOS フォーマット なお , お送りいただいたディスクなどは返 却できません。ご了承ください。 【宛先】 〒 107-0052 東京都港区赤坂 4-13-13 ソフトノヾンクパプリッシング ( 株 ) c マガジン編集部「 c マガ電脳クラブ」係 E-Mail : cmaga@softbank.co.jp 月のパズルー ラドクリフの六角陣 Fig. 4 の 19 個の正六角形のなかに , 1 から 19 までの 19 個の数すべてをダブりなく 入れる。このとき , 直線上に並んた数 ( 図中の A ~ 0 ) の和がどこも 38 になるように したい。何通りの配置が考えられるだろうか。全体を回転した解や , 裏返した解は 別の解とはしない。 Fig. 4 ラドクリフの六角陣 <( cn O L.u c マガ電脳クラブ 169