= 3 最新の dm ⅱ ght. def ・・・・・・モジュール定義ファイ 能ですが , ⅲ t64 [ 注 4 ] をサポートしていない ・ L 旧 RARY 文・・・・・・ DLL の名前を指定 場合は dmusici. h でエラーとなるので注意し ・ DESCR 旧 T ℃ N 文・・・・・・ DLL の目的につ の 3 つです。これに加えて , デバッグ時の てください。なお , ファイナルのソース , いて記述する 情報として関数のエラーコード「 e or. ⅸ t 」 コンパイル / リンク済み DLL は , それぞれ \ d ・ EXPORTS 文・・・・・・エキスポートする関 mlight ディレクトリ内の }source , in に収 ( Fig. 4 ) も用意しておきました。 数の名前を順に記述 「 VisuaI C + + 6.0 」と「 BorIand C + + BuiIder 5 」 録しています。 提供されるファイル [ 注 4 ] 「 int64 」は 64 ビット整数のデータ型です。 でのプロジェクト生成方法をコラム 1 にま 初期のころの Windows C ℃ + + 開発環境ではこの とめておいたので , 必要に応じて参照して DLL を構成するソースファイルは , データ型に対応していないものもあります。 Dire ctMusic のコードをコンパイルする際にインクル ください。 ・・コード dmlight. cpp ・ ードする dmusici. h には、 そのほかの C / C + + 開発環境でもビルド可 ・・ヘッダファイル dmlight. h typedef ——int64 REFERENCE_TIME; のような定義があり , i 猷 64 をサポートしてい ない開発環境はここでエラーとなります。 Fig. 4 関数のエラーコード ( e 「「 0 「 . txt ) ーエラーコード表ー dmlight. dll の関数 1 -10 : 関数の引数に問題がある場合 1 : 1 番目の引数の値が不適切 , もしくは何らかの問題がある dmlight. dll で利用可能な関数は Table 1 に 2 : 2 番目の引数の値が不適切 , もしくは何らかの問題がある 3 : 3 番目の引数の値が不適切 , もしくは何らかの問題がある 示すとおりです。以下 , それぞれの関数に 4 : 4 番目の引数の値が不適切 , もしくは何らかの問題がある ついて順に解説します。 1 1 -30 : COM 関連のエラー 1 1 : Co ⅶ tia ⅱ ze の呼び出しが失敗した , もしくはまだ呼び出されていない。 12:CoCreatelnstance の呼び出し失敗 , インタフェイス : lDi 「 ectMusicLoade 「 8 への ポインタが獲得できない。 13:CoC 「 eatelnstance の呼び出し失敗 , インタフェイス : IDi 「 ectMusicPerformance8 へのポインタが獲得できない 31-50 : ローダ関連のエラー 31 :lDirectMusicLoade 「 8 のメソッド , SetSearchDi 「 ectory が失敗 , 指定されたバスが セットできない。 32 : ローダーオブジェクトのインタフェイス : lDirectMusicLoade 「 8 へのポインタは まだ獲得されていない。 33:lDi 「 ectMusicLoader8 のメソッド , GetObject が失敗 , インタフェイス . IDi 「 ectMusicSegment8 へのポインタが獲得できない。 51 -70 : パフォーマンス関連のエラー 51 :lDi 「 ectMusicPerfo 「 mance8 のメソッド , ⅶ tAudi0 が失敗した。 52 : パフォーマンスオブジェクトのインタフェイス :lDi 「 ectMusicPerformance8 への ポインターはまだ獲得されていない。 53:IDirectMusicPerfo 「 mance8 のメソッド , PlaySegment が失敗した。 54」Di 「 ectMusicPerformance8 のメソッド , 曰 aying が失敗した。 55」Di 「 ectMusicPerfo 「 mance8 のメソッド , SetG10balParam が失敗した。 56:lDirectMusicPerfo 「 mance8 のメソッド , GetGIobaIParam が失敗した。 57:lDirectMusicPerformance8 のメソッド , C 「 eateStanda 「 dAudioPath が失敗した。 58:lDi 「 ectMusicPerformance8 のメソッド , PIaySegmentExt)\ 失敗した。 71- : その他のエラー 71 : 引数で指定されたセグメントオブジェクトのインタフェイス : IDi 「 ectMusicSegment8 へのポインターはまだ獲得されていない。 72 : Win32 API MuItiByteToWideChar が失敗した。 73」Di 「 ectMusicSegment8 のメソッド , DownIoad が失敗した。 DllMain 関数 DWORD fdwReason, LPVOID lpvReserved) BØも WINAPI DllMain(HINSTANCE hinstDLL switch(fdwReason) ( cage DLL—PRWESS—DETACH: CIeanUp( break; ・ DllMain DLL のエントリポイントを設定する際に オプションで初期化 / 終了処理用の通知コ ードを指定することができます。ここで指 定可能なタイミングは TabIe 2 に示す 4 種類 ですが , dm ⅱ ght. d Ⅱでは DL し冬了時の処理 で確実にクリーンアップをするために , List 3 に示すように DLL_PROCESS_DLTACH を 指定しています。 ・ OpenDmIight OpenDmlight は Dmlight ライプラリの初 期化処理を行います。 List4-(1) に示すよう に , まず CoInitiaIize を呼び出して COM ライ プラリを初期化し , 次いでバージョン情報 の通知 ( 必要なら ) を行っています (List 4- ② ) 。 COM に準拠したコンポーネントを使 用する場合は事前に必ず CoIni ⅱ alize を呼び 出してライプラリを初期化しておかなくて はならないので , dm ⅱ ght. d Ⅱの関数を使用 するときにはほかのすべてに優先して , ま ずこの関数を呼び出しておく必要がありま す。 CoInitialize の呼び出しをエントリポイン ト DIIMain で行うという考え方もあります が , 今回の実装では DLL 初期化用の関数と 特集 3 最新の DirectMusic を使う 5 / List て e セてれ TRUE;
Java フ恤クラミングリファレンス 詳説 JDK 解体新斟 Fig. 8 整数除算の定義 N / D という式があるとして , N と D にニ項数値プロモーションを施した結果の整数値をそれぞれ n と d と する。このとき , n / d の商 q は次の不等式を満足するなかで絶対値が最大の整数である Fig. 9 List 4 のサンプルラン akida: ¯/cmaga/javaref$ java List4 10 / 4 10 / ー 4 = ー 10 / 4 = -10 / ー 4 = 2147483647 / 1 = 2147483647 2147483647 / ー 1 = -2147483647 ー 2147483647 / 1 ー 2147483647 ー 2147483647 / ー 1 = 2147483647 -2147483648 / 1 = -2147483648 -2147483648 / ー 1 = ー 2147483648 つるつつみ なおコ n は一田のとき , q の符号は以下で定められる n と d が同符号ならば , q は正 n と d が異符号ならば , q は負 田であれば , q はゼロである ただしこのルールの例外として , n が該当する型で表現可能な最大の絶対値を有する値で , かっ d が -1 の 場合にはオーパフローが発生し , 商 q は n に等しい Fig. 10 浮動小数除算の演算ル ール 〃ここでは「ゼロ」と記しているが , ゼロには符号があることに注意 if (ー方が NaN) { 結果は NaN; } else if ( 無限大 / 無限大 ) { 結果は NaN, }else if ( ゼロ / ゼロ ) { 結果は NaN; } else { 〃以下において , 結果の符号は , / / 除算の両オペランドが同符号であれば正 , / / 異符号であれば負となる。 if ( 無限大 / 有限の値 ) { 結果は符号付きの無限大 : } else if ( 有限の値 / 無限大 ) { 結果はゼロ : } else if ( ゼロ / 非ゼロの有限の値 ) { 結果はゼロ : } else if ( 非ゼロの有限の値 / ゼロ ) { 結果は符号付きの無限大 : } else { 結果は数学的な商を表現可能な近似値に丸めたもの : 〃ただしオーパフローして無限大になることがある Fig. 11 List 5 のサンプルラン akida: ¯/cmaga/javaref$ java L 土 s セ 5 123 . 4 / NaN = NaN NaN / lnfinity = NaN lnfinity / lnfinity = NaN 0 . 0 / 0 . 0 = NaN 0 . 0 / ー 0 . 0 = NaN lnfinity / 123.4 = lnfinity lnfinity / ー 123.4 = -lnfinity -lnfinity / 123.4 = -lnfinity -lnfinity / ー 123.4 = lnfinity 123.4 / lnfinity = 0 123.4 / -lnfinity = -123.4 / lnfinity = -123.4 / -lnfinity = 0 . 0 0 . 0 / 123.4 = 0 . 0 / ー 123 . 4 = ー 0 . 0 / 123.4 = ー 0 . 0 / ー 123.4 = 123.4 / 0.0 = lnfinity 123.4 / ー 0.0 = -lnfinity -123.4 / 0.0 = -lnfinity -123.4 / ー 0.0 = lnfinity のものだ。たとえば , 「 10 / 4 」と「 -10 / -4 」は ないということに注意してほしい。 C/C + + 「 2 」になり , 「 -10 / 4 」も「 10 / -4 」もともに「 -2 」 では , このどちらになるかは処理系依存の になる (Fig. 9 ) 。ちなみに除算の場合 , 「結 項目である ( それに起因する移植上の問題 果を小さいほうに丸めて整数値を得る」と を回避するために ANSIC では , Java と同 いう流儀もある。もしそうした流儀が取ら じく「ゼロ方向に丸める」除算を保証して なお , Fig. 8 で最後に述べている「例外」 れている場合は , 「 -10 / 4 」や「 10 / 4 」の いるライプラリ関数として div と ld ⅳが用意 のケースとは , 具体的にいうと , int 型の除 結果は「 -3 」になるのだが , Java はそうでは されている ) 。 算では , 符号付き 32 ビットで表現可能な最 Java プログラミングリファレンス詳 DK 解体新書 99
わけではなく , すべての Java 処理系で共通 であると考えてよい。 誤解のないように補足すると , こうした 現象は浮動小数というデータ表現形式を用 いているためであって , 有限のビット幅の 内部表現によって , 本来表現したい有理数 の近似値を扱っていることに起因するもの である。したがって , 決して Java 固有の問 題ではなく , ほかの言語でも同様の現象は 生じるものであり , むしろ演算順序を未定 義としているほかの言語を利用する場合に こそ , より気をつけなければならない。 a = 3 .14E100 b = 1.8E300 aNan = NaN a * plnf = lnfinity -a * plnf = -lnfinity —a * nlnf nlnf * plnf = —lnfinity system. 0uしPて土n凵nに土 = g * h = を十土リ y = 1 . OE -300 yzx2 = 3.14E -100 z 1 = 3.14E -100 整数のオーパフローの例 public static void main(string[ 1 args) Cp 0 ね ss も土 st3 ( * 整数のオーパフローの例 な st3. java int a = 6500 Java フロクラミングリファレンス 詳説 JDK 解体新 さらに Java が採用している IEEE 754 形式 の浮動小数データは , 正負の無限大 (lnfini , および非数 ( NaN ) という特殊な値を 取り得るが , これらが関連する乗算に関し ては特別な計算ルールがあり , それを示し たのが List2 である。まず 2 つのオペランド の少なくとも一方が NaN であったら , 他方 がどんな値であろうとも結果は NaN になる (Fig. 6 ) 。また , ゼロと正負の無限大の積は NaN になる。それ以外の演算では , 仮に 方もしくは両方のオペランドが正負の無限 大であったとしても , 乗算結果の符号は数 学的な積に従って付けられる。 一方 , 整数については無限大といった特 別な値は定義されていないため , 乗算の結 果オーパフローが発生した場合 , 数学的な 積の 2 進表現から , 該当データサイズ ( ⅲ t あ Fig. 5 List 1 のサンプルラン 土 b 6530 int 0 a * b; System. 0uしPて土n凵n()a = ”十 a); system. out. println()b = ”十 b)i system. 0uしPて土n凵nに system. ou し 0 て土 n 目 n げ int d ま 3300 土 n セ e = -6600 土 n し f = d * system. 0uし . println()d = 物十 d); system. out. Pて遍t所()e = ”十 e); System. out. println()f = d * 0 system. out.println(" int g = ー 65 圓 int h = ー 3400 int 土ま g * system. out.println()g = ' 十 g); system. 0uし . println()h = ”十 h); system. out. println(" c = a * b = るいは long のどちらか ) で表現可能なビッ トの数だけ下位ビットから取り出し , それ を 2 の補数表現として解釈したものが結果 の値となる ( この取り扱いは , C / C + + でも 同じである ) 。 たとえば , List3 をご覧いただきたい。 int と long のそれぞれについて , 乗算がオーノヾ フローするために正 x 正が負になるケース , 正 x 負が正になるケース , 負 x 負が負になる ケースという数学的な積とは符号が逆にな る ( 当然数値的にも正しくない ) 結果が得ら れる実例になっている。 Java の long は符号 付きの 64 ビット整数であるため , めったな ことではオーパフローしないような気がす るのだが , 億単位の計算をする場合には やはりオーパフローに対する注意が必要に b = 1.8E300 a = 3 .14E1 圓 akida: ¯/cmaga/javaref$ java L 土 s セ 2 Fig. 6 List 2 のサンプルラン なることがわかる (Fig. 7 ) 。 -lnfinity lnfinity 第十 f); akida :¯/cmaga/javaref$ java List1 c = 5 .555555555555555E ー 301 bcal = 3 .1399999999999995E100 abc2 = 3 .1399999999999995E100 abcl = lnfinity = 9 .999999999999999E299 x = 3 .14E -100 cab2 = lnfini ty cabl = 3 .14E100 bca2 = 3 .14E100 Z z 2 = 0.0 xyz 1 = 0.0 yzxl = 3.1399999999999994E ー 100 z2 = 3.1399999999999994E -100 plnf nlnf aNan * b a * aNan = NaN aNan * aNan = NaN aNan * p I nf = NaN plnf * aNan = NaN aNan * n I nf = NaN nlnf * aNan = NaN = NaN long 引 = 4200000000 long = 4280000000 long 引 = 引 * bl; system. out ・ Pて土n凵n()引 = ”十引 system. out. println("bl system. 0uセ . println("cl = 引 * bl = 朝十 cl) system. 0uしPて土n凵n( ” long 引 2200000000 れ g 引 = -4200000000 long = dl * el; system. 0uしPて土n凵n( ”引 = ”十引 system. out. println( ″引 = ”十引 system. out. Pて土n凵n()日 = 引 * 引 = ″十 fl) system. out. Pて土n凵nに long 引 ー 420000 圓 00 long hl -2300000000 long Ⅱ = * hl; system. out. println( ” = ”十嶹 system. 0uむ・ println("hl ”十 (l) ー system. out.println( ”凱 = 引 * hl system. out. Pて土n凵nに 0 . 0 * plnf = NaN 0 . 0 * nlnf = NaN -lnfinity lnfinity -lnfinity lnfinity plnf * plnf = lnfinity a * nlnf nlnf * nlnf plnf * nlnf Java プログラミングリファレンス詳説 JDK 解体新書 9 /
真紀俊男の ローテク講座 lSt 2 次元配列の動的な確保 ( パターン A ) int 土 n ( vo 土 d ) printf ( ″ * test start * 基 n ” TestMain(3,4); printf( ” * test end * 基 n ″ retu て n 0 ー void **Alloc2Dim(int inx,int inY,size_t inEIemSize); void Free2Dim ( void * *inMem , int inx static VOid TestMain(int inX, int inY) int * * theDim2 ー int theX,theY; for(theX = thex く inx; thex 十十 ) { theDim2 (int **)Alloc2Dim(inX,inY,sizeof(int) for(theY = theY く inY; theY 十十 ) { for(theX = の thex く inx; thex 十十 ) { theDim2[theX][theY] = thex * 0X10 十 theY; for(theY = の theY く inY; theY 十十 ) { printf( "theDim2[%d] [%d] = %Xh%n" ,theX,theY,theDim2[thexl [theY] VOid **Alloc2Dim(int inX,int inY,size_t inEIemSize) 注意 : Ⅱ oc 失敗時のことを考慮していない inEIemSize は sizeof(HogeType) を設定すること 見かけ上 oge array [ i Ⅱ土 nY ] である 2 次元配列を動的に確保する Free2Dim ( ( void * * )theDim2 , inX 潺 return theAns ー theAns[theI ] = malloc(inY * inElemSize); for(thel = の thel く土 n 馮 thel 十十 ) { theAns = malloc(inx * sizeof(void * ) int thel; void **theAns; / * 答え * / free(inMem); free(inMem[01 for(thel = の thel く土 n thel 十十 ) { int thel ー VOid Free2Dim ( void **inMem , int inX ) 注意 : A Ⅱ oc2Dim 失敗時のことを考慮していない A Ⅱ oc2D 土 m で確保した領域を解放する もう少し工夫をしないといけないが は次回のお楽しみとする。 [ 注 ] [ 1 ] 勘違いしてはいけない これ 「いくらなんでも , こんな勘違いするや つはおらんだろう」と思わないこと。「キャ ストを使えば , 何でも自分の思うとおりに できる」という勘違いは , さほど珍しくは ない。おまけに , これでもコンパイルでき 叩 eratornew() 」と記述されているもの。 文 :placement syntax と呼ばれる」 , 「 " 配置 " 訳では「 new ( buf ) X という構文は , 配置構 4.11 「オプジェクトの配置」を参照。日本語 「プログラミング言語 C + + 第 3 版』の 10. [ 2 ] placement new イルできても正常に実行できる保証はない。 ・・。もっとも , コンノヾ てしまうのだから・・ む 募集 プログラマ テクニカル・エンジニア フレックス ( 入社当初コアタイム 10 ~ 16 時 【動務時間】 飯田橋 【動務地】 IJNIX 、 WinA 円のいずれかに知識がある方 ) 学歴年齢不問、要経験 (C 、 C + + 、 Java 、 【資格】 分散オブジェクトシステムの開発 【仕事内容】 私たちは求めます。 真の技術者を、 世界と戦うことのできる えております。 外の市場へ提供していきたいと考 システムのプラットフォームを国内 めており、今後、新たな分散共有 現在海外企業との共同開発も進 おります。 唯一、通産省より事業採択されて 当社は純国産 ORB の開発を国内 www.avail.co.jp 東京都千代田区飯田橋 1 丁目 5 番 9 号精文館ビル 3 階 〒 102 ー 872 株式会社アベイル TEL 03-52164755 ご持参ください。 電話連絡の上、履歴書及び職務経歴書を 【お問い合わせ】 資本金 / 8000 万円、 1992 年 5 月設立 【会社概要】 ソフトウェアベンダー 【事業内容】 保険完備 昇給年 1 回、賞与年 2 回、交通費支給、社会 【待遇】 経験年齢等考慮の上優遇します。 【給与】 完全週休 2 日 ( 土・日 ) 、有給、年末年始 【休日休暇】 あり ) く資料請求番号 14 / 〉 真紀俊男のローテク講座 1 イ /
求む。未来派コーダー ! WWW•OPUS•CO•JP オーパス開発ソフト PS2 「 Su 市」 PS2 「井出洋介の麻雀家族 2 」 PS 「うたうたウ ~ 」 PS 「 ULTIMATE FIGHTING CHAMPIONSHIP 」 PS 「æat PlanetMusic 」 「紋」 02 〔Ⅱ C び 0 の 20 ) 引下 C ( RP 「井出洋介び・家 2 」◎ 20 TAC 〔引ロ、レ 02 引 / 02 0 ー l.JSaF 「うたうたウ ~ 」き : 2 〔工戸 uSC 〔 RP オ ( s ′を“ 20 ) 〕 「 T 供正ー石 0 や第ト 1 、や」 @( RA 、モ E 、一田 TA 人モ NTP よ合」び d び 0 師 C ( am 工 0 イ紀 e を 010 凱名 「日をイ M 】」 ( 2C0 〕 S ) 1YC010 ぎ En に 1 置貰 Ccr1V / れき朝ま ・ケームプロクラマー ( 正社員・プロジェクト契約スタッフ ) 仕事内容 : PIaystation2 、、、 pc 関連等のプログラム開発。 資格 : 学歴・職歴不問、 C 言語の知識・経験。 勤務時間 : 10 : ~ 19 : ( 実働 8 時間 ) 給与等委細面談。 ・ CG テサイナー ( 正社員・プロジェクト契約スタッフ ) ・ネットワーク管理者 ( 正社員・アルバイト ) 仕事内容 : Playstation2 、 Xbox 、、 PC 関連等のグラフィック制作。 仕事内容 : インターネットサーバー管理業務。 資格 : 学歴・経験不問、デッサンカのある方。 資格 : Unix/windows2000 se Ⅳ er の知識のある方。 応募方法 : 電話または e - 沼ⅱでご連絡の上、作品・履歴書を郵送して下さい。書類選考の後、面接日をご連絡させていただきます。 二一 〒 141 -0021 東京都品川区上大崎 3-14-12 社ヒル 5F ーをし① 3-544 1775 最寄駅 : JR 山手東急目黒都営三田営団南北線目黒駅 E-mail jobs@opus.co.jp ( 担当 : 大和田 ) 「 AX. 03- M47-177 ① く資料請求番号 003 〉 UN Ⅸ / Linux ユーザーのための活用情報誌 2 0 0 1 」 A サープレット / JSP 利用環境の構築から 実践的なグループウェア活用まで サーパーサ 特別付録 CD - ROM2 枚組 FreeBSD .2-REL ASE JBuiIde 4 、 Foun ation JDK 1.3 ほか 特別定価 1380 円 AV 大特集 好。評連載 ! リナちゃんと楠木くんの Begin! Linux ・エデイタに挑戦 ! Pragmatic IJNIX ・ rc ?. d の動作を検証する ※予告なくぐ , 内容に変更のある場合があります。 」 AVA ソフトバンクバブリッシンク株式会社〒 107-0052 東京都港区赤坂 4-13-13 最新情報はこちらへ http://www.softbankpub.CO.jP/ SOFT NK ・お近くの書店でお求め・ご注文下さい。・コレクト便 ( 現金引き替えにて宅急便でお届け ) でご注文の場合は直接小社までお申し込み下さい。送料は一律 380 円です。◎注 : 一部配達不可 Publish ing 能地域がございます。・小社発行の領収書は発行できませんのでご了承下さい。 E メール :magazine@softbank.co.jp/Tel: 03-5549-1200 く表示価格は税込 )
読者一ゼ、 1 名 A Borland Delphi 5 名 2 名 C Visual C + + 6.0 プ 2 名 B Excel 2000 バック VBA の応用 80 例 ログラミング入門編 提供インプライズ ( 株 ) 提供ソフトバンクバブリッシング ( 株 ) 提供ソフトバンクバブリッシング ( 株 ) TEL 03 ( 5350 ) 9380 TEL 03 ( 5549 ) 1200 TEL 03 ( 5549 ) 1200 Ⅵ馳 0 に + + 6.0 フログラミング 0 Excel 2000 1 Borland C + + Builder 5 提供インプライズ ( 株 ) TEL 03 ( 5350 ) 9380 、、ⅲ dow 、 High•per10rmance ANSIC+ + ⅵ s 聞届叩 me With 0 曲 a and 佩 ern T00 C プログラマーのにめの W ⅸプログラミングス↓ 田中正・ー 法いやすいにジュアル貸ま境 ・に 0 以上のコンホーネント ・メ土リバグを検出する 0 こ女儀謝 d ・インターネット第応 、ミ ) ・多彩なデーみペース機 。社物のをすの物川キ 井上【を】 応用 80 例 元的な竄性を誇り、多様なニーズに応える ( ーで実現されたピジ三アル開発ツーノい ild 5 VisuaI C + + 6.0 を使いながら , アプ リケーションを実際に作成するまで を解説した書籍 Exc 引上で VBA を使った応用事例と その仕組みを解説した書籍。詳しく は 164 ページを参照のこと バックナンバー情報 03-5549-1200 ( 2000 年 12 月 18 日現在 ) 【モニタ募集要項】 1999 年 特集「 MFC6.0 最新機能と活用テクニック」 ・ 2 月号 新連載「徹底解説画像と音のアルゴリズム」 ◇応募資格 : プログラミング経験者 , お ADERS ' ROOM モニタ係」宛に投函い 提携翻訳「バランス型デイザリング技法」ほか 特集「アルゴリズム入門」 ・ 4 月号 よびプログラミング学習者。 ただくか , あるいは E-mail アドレス宛 レポート「 UN Ⅸサーバアプリケーションの Windows NT への移植」 ◇モニタ期間 : 商品受領より 3 か月間 ( モ に電子メールを送信ください。 新連載「 c 言語入門」 , 「実践入門 c + + 」 , 「デザインパターン入門」 ほか ニタ商品によっては発送に日時を要す ◇レポート発表 : 提出いただいたレポー 特集 1 「 STL 」 ・ 7 月号 特集 2 「組み込みプログラミング入門」 るものがあることをご了承ください ) 。 トは , 編集部到着月日から 2 か月後に 特別記事「 PC - UN Ⅸプログラミング開発環境ガイド」ほか ◇モニタレポート : モニタ期間中に最低 2000 年 発売する本誌上 , または付録 CD - ROM 特集 1 「 XML c ℃ + + による実用的な利用方法」 ・ 2 月号 2 回のモニタレポートを提出していた にて掲載収録する予定です。 特集 2 「 Windows 2000 でこう変わる ! 最新 Windows プログラミ ング」 ◇選考発表 : この号のモニタ選考結果は だきます。レポートはテキストファイ レポート「 Wi 0WS208 におけるデバイスドライバの開発」ほか 特集 1 「セーフテイプログラミング」 ・ 6 月号 ルとし , フロッピーディスクにて「 RE 2001 年 6 月号にて発表いたします。 特集 2 「 MNG 」 特集 3 「 Windows と Linux のクロスプラットホームを実現するクラ スライブラリ作成術」ほか 特集 1 「プログラミングの禁じ手 c + + 言語編」 ・ 7 月号 特集 2 「 Windows 用 X68000 工ミュレータの仕組み」 読者プレゼント応募の注意 モニタ応募の注意 特集 3 「べクトル量子化のアルゴリズム」ほか 特集 1 「悩めるプログラマに効くアルゴリズム」 ・ 1 1 月号 特集 2 「 COM をマスターしよう」 ◇綴じ込みの葉書に必要事項を明記の ◇綴じ込みの葉書に必要事項を明記の レポート「新バージョン Borland C + + Compiler 5.5 」 , 「 Fo e fo 「 Java 」ほか うえご応募ください。 うえご応募ください。 特集 1 「 TwinVQ 」 ・ 12 月号 特集 2 「インターネットプログラムの基礎知識」 ◇記入もれやモニタ番号が複数記入さ ◇雑誌公正競争規約の定めにより , 懸賞 レポート「インプライズ K ⅵⅸプロジェクトに迫る」ほか 2001 年 当選者 , モニタ該当者はこの号のほか れている場合 , 綴じ込み葉書以外で 特集 1 「 C # 言語仕様とプログラミング」 ・ 1 月号 のご応募は無効とさせていただきま の懸賞に応募できない場合がありま 特集 2 「 Wave 回の新アルゴリズム」 レポート「 Borland JBuilder4 」 , 「 CodeWarrior fo 「 Windows Ve 「 .6 」 す。 す。 ほか ◇締め切りは 2 月 18 日必着です。 ◇締め切りは 2 月 18 日必着です。当選結 ※ lnside Ⅷ ndows の在庫については , 上記の電話番号まで御連絡ください。 果は 2001 年 6 月号にて発表いたしま 綴じ込み葉書裏面の記事評価アンケートには す。 下記の数字をご記入ください。 ①特集 1 「 XML 入門」 ⑩ VCL 解体新書 ②特集 2 「 Di 「 ec Ⅸ 8 の徹底解説」 00 遊びのレシピ fo 「 WonderWitch ⑩インタビュー「 21 世紀のホビープ ③特集 3 「音声を自由に操るライブラ リの作成」 ログラミング」 ④ C 言語プログラミング学習塾 ⑩ローテク講座 ⑤ど 0 てククのパワーアップ C + + ⑩ C 言語フォーラム 最新開発環境レポート「 iPEX fo 「 ⑥プログラミング相談室 ⑦ Enjoy perl Programming Java 」 ⑧伝授 ! 極めよ Ruby 道 OMONTHLY H EADLI N E ⑨ Java プログラミングリファレンス @C MAGA Bookends ⑩アルゴリズムラボ の学問のススメ ⑩ E 猷 e 「 The 3D P 「 ogramming あつばれご意見番 @Linux programming Tips $C マガ電脳クラブ @Windows Programming Tips $R EADERS'ROOM @Java Programming Tips BorIand De や hi のロゴが印刷された バック。高さ約 30cmx 横約 42cm 。 色は濃緑色。 BorIand C + + Bu ⅱ de 「の最新版。デバッ グ機能を強化し , 最新の A 円や AN 規格に対応したビジュアル開発環境 READERS'ROOM ではみなさ 原文を手直しさせていただく場合 まのご意見・ご感想をお待ちして もあります。ご了承ください [ 宛先 ] おります。ほかにも , コンピュー タをめぐるさまざまなこと , 何で 〒 10 た 0052 もけっこうです。質問もどしどし 東京都港区赤坂 4 ー 13 ー 13 ソフトバンクバブリッシング ( 株 ) お寄せください。 投稿原稿 , 自作ソフトも受け付 C マガジン編集部「 R & R 」係 [ 電子メール宛先 ] けております。採用分には弊社規 定の薄謝を進呈いたします。お送 cmaga@softbank. CO. jp [Web ページ ] りいただいた原稿・ソフトは , 原 則として返却いたしません。また , http://cmaga.zdnet. CO. jp/ 0 173 READERS' ROOM
ぶんと多くのチェックが必要になる。 こんなときのために C には setjmp/long jmp というライプラリ関数があり , これを 用いると深いネストから一気に脱出できる。 だが , これはかなり取り扱いが難しい関数 であり , 不用意に使うとプログラムが暴走 してしまう。 例外 こうした問題を一気に解決できるのが例 外 (Exception) である。例外は , たとえば PL/I , Ada , Mesa , CLU , Common LISP EiffeI , ModuIa-3 , C + + , Java といった言語 で採用されている。また , ML のような関 数型言語にも例外機能を備えるものがある。 もちろん , thon や Ruby のようなモダンな スクリプト言語にも例外処理は用意されて いる。 / * 工ラーチェックありのプログラム * / List 工ラーチェックありのプログラム return EXIT—SUCCESS ー fclose(fp); fprintf(fp, 6d n % 土 fo て ( 土ま土く 1 十十 i ) int FILE *fp = fopen(argv[l] , ” w ″ int main(int argc, char **argv) ( #define BUFSIZE 16 #include く stdlib. h> #include く stdio.h> / * 工ラーチェックなしのプログラム * / IS 工ラーチェックなしのプログラム 日常生活では , 複雑な条件が付くことで もまず正常に物事が進行している場合のこ とを記述し , そのあとで特別な場合につい て言及することが多い。たとえば , 「この 宝くじの 1 等賞金は 1 億円です。ただし , あ る週で 1 等の当選者がいなければ次週の賞 金に加算されます」といった「ただし書き」 がまさにそれである。この「ただし書き」を プログラム言語においても表現可能にした のが例外だともいえる。 List2 と同様の処理を , th 。 n を用い , 例 外を利用してコーディングすると List4 のよ うになる。例外は一種の飛び越し命令で , 例外が発生 (raise) したときに飛び越す先 は , ~ except 文によって用意された exce pt のところである。例外には複数の種類が あり , システムに組み込まれた例外だけで なくユーザも任意の例外を自前で定義して 用いることができる。 t Ⅳ文は何重にも入れ 子にすることができるし , プログラムソー ス上の静的な入れ子ではなく実行時の動的 な入れ子が影響する。複数の except 節が同 じ例外を指定していたとしても , 例外発生 時に制御が移るのはもっとも内側で実行さ れた文の except 節になる。 th 。 n の場合 , 叩 en によって生成される 「ファイル」オプジェクトに関するエラーは , オープン , 書き込み , クローズのいずれの 工ラーも IOE 仼 or という例外であるため , コ ーディングがいっそう簡単になっているこ とはあるのだが , それにしても List4 は List 2 に比べてはるかにすっきりしている。 れが例外の効能である。しかも例外は setj mp / longjmp とは違って取り扱いが簡単で 安全な機能である。 深い場所のエラー int zo 日 ) { if ( ある条件 ) return 1 ー else { / * この条件がトップレベルに伝わるまで * 何度戻り値のチェックが必要か ? * / ist return 0 ー if ( f00 ( ) ) int main ( ) { return 1 ー / * 残りの処理 * / return 0 ー int f00 ( ) { return 1 ー / * 残りの処理 * ノ return 0 ー if い zot()) 土北 bar() { # inc lude く stdio. h> #include <stdlib. h> #define BUFSI ZE 16 int main(int argc, char **argv) if (argc く 2 ) { fprintf ( stderr , nusage : eXit(EXIT—FAILURE); } 引 se { FILE *fp; list2 OUTPUTFILE%n"); ist printf( ” 0 に Python で例外を用いたプログラム if ((fp = fopen(argv[l], ” w ” ) ) = ) { fprintf(stderr, "can't create %sn, argv[l] exit(EXIT—FAILURE); ) 引 se { fo て ( 土 = 第土く 1 十十土 ) { siz = strlen(buf); sprintf(buf, 6d 基 n ″ , 土 size—t Siz; char buf[BUFSIZE]; if (fclose(fp)) { exit(EXIT—FAILURE); fprintf(stderr, "file %s write er て 0 て n ” , argv[l] if (fwrite(buf, sizeof(buf[0]), siz, (p) ! = siz) { exit(EXIT—FAILURE); fprintf(stderr, "file close e てて 0 て蕚 n % argv[l] return EXIT—SUCCESS; # ! /usr/bin/env python # 取ヒ hon で例外を用いたプログラム import sys try : FiIe = open(sys. argvtl], ” w ” ) fO て i in range(), 11 ) : File. write( 6d \ n ”宅土 ) FiIe. close() except IndexError : sys. stderr. write("usage: list3 OUTPUTFILE*n") sys. eX土日1) except IOEr て 0 て , reason : sys. stderr. write("%s%nn 宅 reason) sys. exit(l) sys. exit(0) 学問のススメ 千言万語 1 6 /
0 / いノノミ / ノ 1 ' ロ王 今回は , 条件演算子とインデントについて解説します。特に後者は慣れで身に付けることが多く , 初心者にはなんでこうなるのか , どのようにすればいいのかがよくわからない部分です。簡単な方 針をあげておくので , ふだんから読みやすいソースコードを書くように心がけてください。 れます。あまり使われないので , 解説本に if 文を使えばほば同等のことができるの で必要となる場面は少ないのですが ( List よっては書かれていないかもしれません。 1 ) , 関数形式マクロなどでは便利なことが これは , ( 毛呂宗夫 ) あります。 A ? B : C と記述し , A が真 ( 0 以外 ) だったら B が全体 の値になり , A が偽 ( 0 ) だったら C が値にな (H さんからの質問 ) 「 x = num%4 ? O : 1 : 」と同等な if 文 ります。質問の式の場合 , num が 4 で割り これは条件演算子というもので 切れなければ x の値は 0 になり , 割り切れれ if(num 4 ) x = else x = す。しばしば三項演算子とも呼ば ば x に 1 が代入されます。 誤してきており , インデントにおける大筋 if 文などで { } を使わない場合は 1 行に書く の方針のようなものがあります。そのなか こともありますが ( Fig. 2- ( a ) ) , 2 行に分け からいくつかを紹介しましよう。 る場合はやはり 1 段下げます ( Fig. 2- ( b ) ) 。 まず , 「 { } 」で挟まれた区間 ( プロックと いう ) のなかは 1 段下げる ( 右へ移動する ) こで大事なのは " { " と " } " の対応をと ることです。 if 文や wh ⅱ e 文に付く " { } " の使 のが基本です。 1 段とは , 通常タブ 1 個の幅 い方は大きく分けて Fig. 3-(a) , (b) の 2 方 を示します (Fig. 1- (a) ) 。使用するエディ インデントはソースコードを見や 式がありますが , 下の " } " の位置を ( a ) のス タの設定にもよりますが , 半角スペース 4 すくする工夫の 1 つであり , AN タイルなら文の先頭に , (b) のスタイルな 個ぶんになることが多いようです。ただし , SI C のような規定はありません。ただ , ら対応する " { " に並ぶようにします。また , れまで多くの開発者が時間をかけて試行錯 switch 文や goto 文のラベルは下げません (F 対応する if と else は同レベルのインデント Fig. 3 "{" と丁の対応 Fig. 1 { } で挟まれた部分を 1 段下げる に置くようにします (Fig. 3- (c) , (d) ) 。 foo(); f00 ( ) : bar(); ある C 言語のソースコードに x = num%4 ? 0 : 1 ; という箇所があったのですが , これは 何ですか ? List 1 インテントはどうすればいい のですか ? 何か決まりなどがあるの でしようか ? (N さんからの質問 ) ( 毛呂宗夫 ) 質問募集 ここでは , 読者のみなさまからいただい た疑問や質問を , C MAGAZINE の筆者陣が お答えしていきます。 C / C + + 言語で疑問に , じ、うこと , またプログラミングをしていて わからないことがあれば , 具体的な疑問点 と氏名 ( 誌面掲載時はイニシャルになります ) を明記して C マガジン編集部 (cmaga@soft bank. CO. (p) までメールをお送りください。 なお , 「ゲームの作り方を教えてくださ い」のように疑問点が明確に示されていな い質問にはお答えできません。あらかじめ ご了承ください。 質問にあたっては , メールの件名 ( Subj ect ) に“ [ QA ] ”とご記入ください。 例 : [QA] 行端記号の見分け方は ? 質問の技術レベルは問わないので , 初心 者の方やプロフェッショナルの方も遠慮な くご質問ください。みなさまからの質問を お待ちしております。 (b)l if(X>O) ( タブ 1 個分の幅 ) (b) : switch(i){ lcase 1 : f000 : break; case 2 : b 「 eak; ldefault; baz(); break; f00 ( ) : f00 ( ) : : }else{ f00 (); else Fig. 2 if に続く文を 1 段下ける (a) 第 ( x > 0 ) f00 ( ) : ba 「 0: (b) : if(X>O) f00 ( ) : 81 プログラミング相談室
LiIlllX 世・Ⅷ 111 腿 TIPS List 3 List メッセージキューサーバ側サンプル (mq-server. c) return 1 ー T1is program is one 0f the server implementations for message queues ・ Written ′ Kazutomo Yoshii / * tO inform 0 more data. ' セ 0 client * / data[01.Ien = し a [ 1 ] コ = - if( msgsnd(msgid, ( s セ c し msgbuf*)&(data[0] ),sizeof(MsgBuf) , 0 ) = てて 0 て ( ” gsnd ( ) ” return 1 ー if( msgsnd(msgid,(struct msgbuf*)&(data[1]),sizeof(MsgBuf),0)== perror("msgsnd( ) ” return 1 ー #inc lude く stdiO. い #include く s に d は b. い #include く fcntl . い #include く山 listd. #include く e てて no. い #include 温臨 . #include <sys/stat. #include *. #include く sys/ipc. い #include く sys/msg. い #include - comon. h ” static char char-sin( int d, int p ) return (char)( sin ( ( ( do 厄 ) d / 180.0 * M—PI) 十 ( ( do 厄 ) p / 180.0 * M-PI) ) * 127 / * wait fo て client * / printf("waiting f0 て client terminated%n"); data[0] . len = data[l] . len = ー struct msgbuf rcvbuf ・ if( msgrcv(msgid, &rcvbuf, sizeof(struct msgbuf), 1 , IPC—N(MAIT) ! = printf("client teminated : い宅 d 基 % 1 data[0].Ien = の if( msgrcv(msgid, &rcvbuf, sizeof(struct msgbuf) , 2 , IPC—NOWAIT) ! = printf("client teminated : tYFE 宅 d n % 2 潺 data[l].len = の if( ta [ 0 ] ヨ = 0 & & ta [ 1 ] ヨ = = 0 ) break; static int send—messages—wait(int msgid) MsgBuf ta [ 2 int = の int し一 ta [ 0 ] ヨ = data[l].len まー data[0] . = ta [ 1 ] . t ) = return の int main(int argc, char * 矼 [ ] ) key-t key; int msgid; int while( t く 360 ) { data[0] . 加 f [ pos ] = char-sin( t, 0 ね [ 1 ] . 加 f [ ] = char-sin( し , 90 if( pos = BUFLEN ) { ta [ 0 ] ヨ = [ 1 ] 印 = if( msgsnd(msgid, (struct g 加 f * ) & ( [ 0 ] ) , s 土 zeof ( gB し 0 ) = 0 て ( ” gsnd ( ) ” return 1 ー if( msgsnd(msgid,(struct msgbuf*)&(data[1]),sizeof(MsgBuf),0)== 0 て ( ″ gsnd ( ) ” return 1 ー / * generation Of key * / key = ftOk(KEYFILE—PAN,PRO.J—CHAR); if( key = ー 1 ) { てて 0 て ( ” ftok ( ) ” return msgid = msgget(key, IPC-CREAT ー IPC—EXCLI 0666 ) ・ if ( msgid = msgid = msgget(key, IPC—EXCLI 0666 ) ・ if( msgid ー 江 0 て ( ” et ( ) ” return 1 ー rc = send—messages—wait(msgid); if( rc ) return data[O].Ien = ta [ 1 ] ヨ = if( msgsnd(msgid,(struct msgbuf*)&(data[0]),sizeof(MsgBuf),0)== perror("msgsnd( ) ″ return if( msgsnd(msgid, (struct msgbuf*)&(data[l] ) ,sizeof(MsgBuf) , 0 ) = = rprror("msgsnd( ) ” / * close * / msgctl (msgid, IPC—RMID, NULL); return 0 ー 必ず先頭に long m pe が必要なことです 1 回のメッセージ送受信を 1 ノヾイト以上で これはメッセージのタイプで , 今回の実装 行いたい場合は , 上記の構造体を変更して , 例では , sin テープルが 1 , cos テープルが 2 関数 msgsnd() , msgrcv() に渡すことがで に割り当てられています。 typedef struct { きます。 今回の実装では , 以下のような構造体の long mtype; / * type 0f message * / 言をしています。ここで注意したいのは , Size tlen ・ は以下のようなものですが , これでは 1 バ イトずつしか送れないように見えます。 struct msgbuf { long mtype, / * message type, must be > 0 * / char mtext [ 1 ] ; / * message data * / 0 1 1 / Linux Programming Tips
[ 注 3 ] 「一 stdcalIJ とは関数の乎ひしに「 PascaIJ 発環境によって関数名の変形が起こるもの 通常 , コンパイラは , C + + のコードをコン の呼び出し規約 ( 厳密には若干異なるか ? ) を適 と起こらないものとが出てきてしまいます。 パイルするときに関数の引数の型をコード 用するためのもので , 普通の C ℃ + + 呼び出し規 約の関数と比べるとスタッククリア用のコード 試しに , わざと V1suaI C + + 6.0 で——declsp 化したものを含む関数名を生成します ( つ ぶんだけ実行コードが小さくなります ( C / C + + 呼 ec(dllexport) キーワードを使用して作成し まり関数名の変形 ) 。 C + + の場合はこれによ び出し規約では呼び出しごとにスタッククリア 用コードが必要になる ) 。 た dmlight. dll の中身を dumpbin. exe (VisuaI ってオーバロードなどの処理が可能となる Windows では実行時のコードを小さくするた C + + 6.0 付属のユーティリティ ) でのぞいて わけですが , DLL が特定の開発環境に依存 めに Win32 A 日のほとんどでこの呼び出し規約 を採用しています。たとえば , windef. h では「 pas みます。コマンドラインから , しないようにするためにはこれはかえって caIJ 「 CALLBACK 」「 WINAPIJ 「 APIENTRY 」「 A 曰 不都合になります。そこで , dumpin /exports dmlight. 引 PRIVATE 」「 PASCAL 」が _stdcall として定義さ ・・・つまりおなじみの「 CALLBACK 」 れています。 と入力すると , Fig. 2 のように工クスポー extern ” C ” 「 WINAPIJ は「 stdc 訓の別の呼び名」だというこ トされる関数名が表示されますが , 付録 CD を宣言して工クスポートする関数について とになります。 誤解のないように念のため追記しておくと , - ROM に収録されているリリース版の dmlig は C の規約を適用することをコンパイラに stdcall はあくまで制作者の意志によるオプシ ht. d Ⅱの中身を表示した Fig. 3 とは関数名が 指示しておきます。 ョンで , 普通の C / C + + 呼び出し規約でも DLL から 関数をエキスポートすることができます。 dmlight 異なり , コンパイラによって名前の変形が もう片方の呼び出し規約に関する部分で . dll では , もし実行時のコードが少しでも小さく 起こっていることがわかります ( インポー すが , モジュール定義ファイル (. DEF ) を使 なるのならそのほうがよいだろうと思って stdc 訓を採用しています。 トライプラリを使用して DLL を実行プログ 用すると関数名の変形を回避できます。 dm ラムに接続し , 同一の開発環境ですべての ⅱ ght. d Ⅱでは工クスポートする関数について モジュール定義ファイル 作業をする場合は , この変形は問題となり はすべて一一 stdca Ⅱの呼び出し規約を適用す ません ) 。 るため , どのような開発環境でも同じ関数 モジュール定義ファイルは , DLL の属性 本稿で紹介する dmlight. d Ⅱは , 「特定の開 名にする必要があります。そこで , List2 に を記述するためのモジュール定義文で構成 発環境に依存しない」ということを目標の 1 示すようなモジュール定義ファイルを用意 されるテキストファイルです。 List 2 のよう つにしているので , 関数名の変形が起こら して DLL を作成します。 に必要な定義文を順に記述してリンカに渡 ないようにリンケージ ( 結合 ) に関する部分 しておくと , 内容に沿った DLL を作成して [ 注 1 ]_declspec(dllexport) キーワードは , コ ンパイル時に工クスポートを指示するための情 と関数の呼び出し規約に関する部分の 2 っ くれます。定義文のキーワードの部分と引 報をオブジェクトファイルに追加するためのも に注意してェクスポートする関数を作りま 数の間 , それから文と文は 1 つ以上のスペ のです。リンカはこの情報を元に DLL の工クス ポートシンポルテーブル , インポートライブラ す。 ース / タブ / 改行のいずれかで区切るように リを自動的に作成します。 まず , リンケージに関する部分ですがこ して記述していきます。 [ 注 2 ] コマンドラインなどで作業する場合には こでは ListI のように「 extern 'C" 」を宣言し dmlight. def で使用しているモジュール定 凵 NK コマンドで工クスポートの指定をすること ておくことで関数名の変形を回避します。 義文は次の 3 つです。 もできます。 ヘッダファイル ( dm ⅱ ght. h ) モジュール定義ファイル ( dm ⅱ ght. def ) extern ″ C ″ int stdcall OpenDmlight(int * , 加セ * , int * , int * LIBRARY dmlight extern ″ C ” int —stdcall CreateLoaderPerformance(HWND BOOL); DESCR. IPTION ” ( 0 ) 2000 Nagashima H 土 tosh 土” extern ” C ”土 n セ stdcall Se セ Se 02 近 ( STR extern ″ C ” int —stdcall CreateSegFromFile(BmL, int, LPSTR, BØも extern ” c ” int —gtdcall ⅵ ay 土て yse 日 in BØも , も extern ” C ”土 n し—stdcall PlaySecondarySegment(int, も extern ” C ” int —stdcall IsPlaying(int); ” C ”土 n し—stdcall int * extern extern ” C 第 int —gtdcall FadeOut(int); 1 extern ” C ″ int —stdcall StopMugic(BØL, int); ” C ” int —gtdcall Download(int, BØ extern ” C ” int —stdcall U oad ( 土れ t extern ” C ” int —stdcall CloseDmlight( extern List List EXPORTS OpenDmlight CreateLoaderPerformance SetSearchDir CreateSegFromFile 円 ayPrimarySegment 円 aySecondarySegment IsPlaying MasterGrooveLevel FadeOut StopMusic Download Unload CloseDmIight 56 C MAGAZINE 2 1 2