開発環境 西田啓ー レポート C / C + + 対応自動テストケース生成・テスト実行ツール C + + Test C + + Test は , プログラムのソースコードを解析してテス トケースを自動で生成し , それを基にさまざまなテスト を実行してくれるツールである。 ParaSof& c + + 、 es 、ま」 ParaSoft C 十十 test C + + Test の自動テストの流れは , 次のよ 創造的に変わりうる可能性を秘めたツール プログラムは楽しいけれど・・ である。本稿では , この C + + Test の機能を うになっている。 ( 1 ) C + + のソースを解析してソースプロ 紹介する。 プログラミングの作業は高度に知的で創 グラムの構造を分析 0 十 + Test はどのように ( 2 ) テストドライバ , Stub の自動生成 造的な作業なので , プログラマは楽しみな テストを実行するのか ( 3 ) ユーザプログラム , テストドライバ , がら作業を行うことができる。しかし , デ プログラムが完成すると , プログラマは バッグの作業はどうだろうか ? Stub をコンパイル , リンク ( 4 ) ホワイトボックステスト , ブラック デバッグ作業が重要なことは十分すぎる 完成したプログラムの単体テストを行うた ポックステストの自動実行 ほどわかっていても , 作業自体が単調であ めに , テスト対象となるプログラムを動作 ( 3 ) にあるとおり , C + + Test はユーザプ るなどの理由で , できれば避けて通りたい させるためのテストドライバを , また , プ ログラムと C + + Test が生成したモジュール のが本音ではないだろうか。まして , 単体 ログラム中から呼び出しているほかのライ を 1 つの EXE 形式にしてテストを実行する。 プラリが完成していない場合にはこの部分 テストとなると , このあとに控えている機 この一連の作業を行うためのオペレーショ 能テストの日程などから十分に行われてい を Stub として作成する必要がある。この作 ンも非常に簡単で , 次の手順で行える。 ないのが現状ではないだろうか。この結果 , 業は思いのほかめんどうな作業なので , 単 本来単体テストで発見されていれば予定ど 体テストが行われない理由の 1 つになって ( 1 ) [ スタート ] メニュー , もしくは , Micr osoft Visual StudiO 6.0 ( 以後 VC + + ) 上 おりに進んでいた作業に遅れをきたしてし いる。 C + + Test ではこの部分を自動化するとと に統合されたメニューから C + + Test を まい , 楽しみながらできるプログラムの作 起動 ともに , さらにテスト対象のプログラムに 業が , 難行・苦行の仕事に変わってしまう ( 2 ) テスト対象となるモジュールを選択 対してホワイトボックステスト , プラック ことになる。 (3)C + + Test のメニュー上にある [ bu ⅱ d te ポックステストの 2 つのカテゴリのテスト C / C + + の単体テストを効率よく行うこと 手法の自動実行をサポートしている。ホワ st] アイコンをクリック ができるテストツールは , すべてのプログ ( 4 ) [Test Progress] タブの旧 ecord] アイコ イトボックステストは , プログラム中のデ ラマが願っているツールの 1 つではないだ ータに境界値を与え , 例外データに対して ろうか。 C + + Test はまさにこの要望に応え ンをクリック 関数が十分対処されているかどうかを確認 あとは , C + + Test が生成したテストケー るべく登場したツールである。 するテストであり , プラックポックステス スでの実行結果を待つだけである。 Fig. 1 C + + Test は , プログラムのソースコード に C + + Test の概観とテストの実行の様子を を解析して自動でテストケースを生成し , トは与えられた入力データに対して関数の テストを実行してくれるツールである。も 出力が正しいかどうかを確認するためのテ 示す。 ちろん , すべての単体テストの作業を自動 ストである。また , プラックポックステス テトケース生成の仕組み 化できるわけではないがプログラマがめ トでは , ソースを修正したあとでも出力結 んどうくさがって避けていた作業の大半を 果に間違いがないかどうかを確認してくれ る回帰テストも自動で実行する機能も持っ C + + Test はどのようなテストケースを生 肩代わりしてくれるツールである。また , 成するのだろうか。生成方式があいまいな 使い方しだいでは , テストの作業も非常に ている。 1 イ 4 C MAGMINE 2001 3
プロクラミング 期末試験 実力チェック・ 特集 C/C + + /Java/PerI/Ru by ほとんとの方は , 入門書を読んたり連載 を読むなとをしてプロクラムを習得してき たと思います。自分のフロクラミングの実 力はとれくらいなのたろうかと思ったこと はありませんか。そこで , これからみなさ んのプログラミンクの実力をチェックする 期末試験を行います。今年は C , C + + , Jav a, perl, Ruby と , 5 科目を用意しました 受験するのは 1 科目でもかまいませんし , 5 科目すへててもかまいません自分のペー スに合わせて受験してくたさい。なおこの 試験はみなさんの実力をチェックするもの なので , テキストやノートなとの持ち込み は不可といたします。カンニングもいけま せん。それそれの科目は 100 点満点となっ 1 0 C MAGAZINE 2001 3 ています。この試験の結果て , がわかるはすてす。これを機会に , 自分の 弱点を知って克服しましよう 自分の弱点 か , OS 依存なのか ・その内容が古ロ = = 五規格準拠か , 処理系依存 ・プログラム言語 討しています。 題は , 誌面もしくは C マガ Web 上での発表を検 だけると助かります。お寄せいただいた試験問 さい。メールのタイトルは [EXAM] としていた cmaga@softbank. CO. jp 宛にメールをお寄せくだ 題のレベルは問いません。下記の内容も添えて , 語は , 今回の 5 言語とさせていただきます。問 解答を募集いたします。募集するプログラム言 編集部では , みなさんからの試験問題とその 編集部からのお願い
C + + を , 機能拡張された C 言語と捉えて使 うのも , 1 つの方向性でしよう。 イベント駆動型フログラム 最近の OS のインタフェイスは , GUI が標 準になっています。このため , GUI 上で動 作するウインドウアプリケーションを作り たいと考える人も多いと思います。 ANSIC は標準入出力をサポートしている ので , CUI 上で動作するプログラムを作成 することができます。ですが , GUI をサポー トする標準的な入出力の設定はないため , GUI 上で動作し , ポインティングデバイス ( マウスなど ) で操作できるプログラムを ANSIC の範囲内で作成することはできませ ん。 このため本連載では , Windows, Maci ntosh, X(UNIX のウインドウシステム ) でウ インドウを開き , その上にボタンなどを配 置し , マウスで操作するといったウインド ウブログラムの作り方について , まったく 言及してきませんでした。 割り込み処理 現在の一般的なウインドウ , すなわち GUI のプログラムは , OS にかかわらず , 実は同 じような骨組みで成り立っています。これ らは , イベント駆動型と呼ばれるタイプの プログラムです。イベント駆動型とは , 割 り込み処理の集合体で構成されるプログラ ムです。この「割り込み処理」とは , コンピ ュータが「ある状態になったときに実行さ れる処理」のことで , コンピュータのハー ドウェアとデータのやり取りを行う部分で よく使われています。 たとえば , キーポードからの入力を取得 する場合を考えてみましよう。まず考えら れるのは , 作成するプログラムの中で , とあるごとに何が押されたかキーポードを 監視する ( この手法はポーリングと呼ばれ る ) という方法があります。これは簡単で よさそうに見えるのですが , プログラムが 66 C MAGAZINE 2001 3 コラム 2 前回の演習問題の答え ・ゲームの作成 行っていても , キーポードの入力は履歴に ば , プログラム本体が時間のかかる処理を るシステムにするのです ( Fig. 2 ) 。こうすれ 文字列を取得する」プログラムで構成され み処理と , 「その履歴を利用して押された 押されたときに履歴を残す」という割り込 これを回避するために , 「キーポードが てしまうのです。 グラム側の都合で押していないことになっ ません。つまり , 押したはずのキーがプロ っていないときは押されたキーを検出でき ほかの計算などを行っていて監視状態にな 夫してみてください。 抑えることができるでしよう。いろいろ工 アの違い , 動作環境の違いによる悪影響を イミングを合わせたりすれば , ハードウェ ぶしではなく time ( ) を使ってより正確にタ うのが理想です。ループ処理による時間つ ち時間の調節をプログラム側で自動的に行 に大きなバラつきが考えられる場合は , 待 プラットホーム (OS) であっても動作環境 しなければなりません。このように , 同じ ってくるので , ほどよく遊べるように調節 よってループが回り切るまでの時間が変わ ムは , 実行するコンピュータの処理速度に 調節を行っています。このようなプログラ この ansl . c は , ループ処理で待ち時間の るでしよう。 ームプログラムを作成するうえで参考にな を行ったりしています。これらの手法はゲ 変わったり , ループによる動作時間の調節 とで , 動作させるたびに出題される問題が ansl . c では , 乱数の種を時間から得るこ きのような側面も持っています。 でキーを押すことを要求される , もぐら叩 ピングソフトです。ランダムなタイミング 収録しました。この ansl . c は , 一種のタイ VcmagaVCVans> ティレクトリに ansl . c を す。解答の一例として , 付録 CD ー ROM のく 簡単なゲームを作ってみようという問題で まず , 改行によるスクロールを利用した ・ラベルジャンプ 次に , ラベルジャンプを効率よく行うた めの方法です。これはたとえば , ラベルの インテックスを作成する方法や , ラベルを キャッシュする方法などを考えることがで きます。 ラベルのインテックスの作成をする方法 とは , あらかじめラベル名とそのラベルに fseek ( ) で到達するためのファイル先頭から の距離情報をセットにして準備することで す。プログラム起動時にすべてのラベルに ついて調べて情報を 1 回作成しておけば , 実際のラベルジャンプはこのテータを元に 行うことができます。 ラベルをキャッシュする方法も , 基本的 な考え方はインテックスと同じです。こち らは最初にまとまったテータを作らずに ラベル検索実行中に見つけたラベルに関し てそのつど記録していきます。 こで , シ ナリオファイルのどの位置までラベル検索 を行ったかも記憶しておきます。こうして おけば , ラベルジャンプの際には , まず記 憶しておいたラベル情報を調べてそこにラ ベル情報があればそれを使ってジャンプし , なかったらラベル検索を記憶した位置より 後ろで実施していきます。 この手法はインデックスの作成より複雑 ですが , 必要なときに必要なだけ検索する ので , 起動時にまとまった時間を取られず に済みます。 残っているので取りこばす心配がなくなり ます。一般的なコンヒ。ュータシステムでは , この割り込み処理の対象としてキーポード やマウス , 通信ポートやタイマなどを設定 できるようになっています。逆にいえば , 人力が取りこぼされると困るようなデバイ スは , 割り込み処理を設定する必要がある のです。 コンピュータサイエンスで習うタイムシ ェアリングによる並列処理も , タイマによ る一定時間ごとの割り込みによって実現さ れています。この場合の「ある状態」とは ,
作りたいものを , 自分の知識の範囲でがん ばって作るのが本筋で , ポインタの概念の 習得を重視するあまり , 論理的思考方法の 習得を放棄するのは本末転倒ではないでし ようか ? 最近のアプリケーション開発は , C 言語 一辺倒ではなく , 開発の用途に応じて言語 を使い分けるのが一般的になってきました。 C + + , VisuaI Basic , Java , Perl などと CÄ 語を比較してみると , C 言語というものに 対する自分なりの位置付けができてくるで しよう。「 C 言語 ! = プログラミング」になった とき , あなたはプログラミング初心者では 多くのすぐれた資産 なくなっているはずです。 List 「関数へのポインタ」の使用例 プログラミング言語としての特徴以外にも , が積み重ねられてきたのです。 C 言語には , り , 読んで勉強したりして , C 言語の歴史 プログラマが自分のプログラムで利用した す。こうして積み重なった資産を , ほかの 多くのすぐれたソースコードを書いていま た。そのため , 昔から優秀なプログラマが ミングを行う道具として利用されていまし C 言語は最初 , きわめて高度なプログラ 多くの先人たちの残してきた資産を利用で きるという利点があります。 私は , 初めて PC を買う人には「あなたの 親しい友人でコンビュータに詳しい人がい れば , その人と同じ機種を買いなさい」と いうアドバイスをします。プログラミング 旨に関しても同じで , インターネットな 「コロロ どを通じて多くの C 言語利用者の資産 , ノ ウハウが利用できるのが , C 言語の強みだ C と C + + , ついでに Java と思います。 たところなのに , まだ何か足りないという 語のプログラミングができそうになってき こともあるでしよう。やっとの思いで C 言 や職場の先輩が , C + + や Java を話題にする mming ps 」などの連載があります。学校 プログラミングリファレンス」「 Java progra んが , 本誌には「パワーアップ C + + 」や「 Java 読者で読んでいる人は少ないかもしれませ ぐらいは知っているでしよう。私の連載の 本誌の読者であれば , C + + や Java の名前 のでしようか ? List 1 オブジェクト指向 ータと手続きで構成されるオプジェクトを ことができます。この「拡張」によって , デ クラスにはそのメンバとして関数を入れる てデータしか入れることができませんが よいでしよう。構造体にはそのメンバとし 関数を入れることができるものだと考えて 乱暴にいってクラスとは , 構造体の中に ます (TabIe 1 ) 。 くとも「見かけ上では」理解することができ のなので , C 言語を理解していれば , 少な 形式上 C 言語の構造体を拡張しただけのも ています。実はこのクラスというものは , る型として , クラスという表現方法を用い C + + や Java では , オプジェクトを表現す の設計に関する概念です。 もらわねばなりませんが , 要はプログラム を超えるので , ほかの記事や書籍を読んで うものです。詳しい説明はこの連載の範囲 る " オプジェクト " というものを考える」とい として , データと手続き ( 関数 ) で表現され を大雑把にいうと「プログラムの構成要素 「オプジェクト指向」という概念です。これ C + + や Java を知るうえでのキーワードが #include <stdlib. h> #include <stdio. h> typedef struct ( int eyes—count , hands—count , int (*talk)(void); } HUMAN ー typedef struct ( int eyes—count , hands—count , 土 n し (*talk) ( VO 土 d } DOG デ 土 n し human-tal k ( 土 n し dog—talk( 土 n し main ( ) masaru. eyes—count = 2 ー DOG goro ー HUMAN C MAGAZINE 2001 3 go て 0. eyes—count ま 2 ー masaru. = human-talk; masaru コ egs—count = 2 ー masaru. hands—count = 2 ー ー egs—count ー ー egs—count ー g0て0. hands-count 咢の goro ヨ egs—count 4 ー go て 0. t 引 k = dog—talk; puts("masaru say"); ( * ( mas 矼 u. ね慊 ) ) ( pu s に go て 0 say"); ( * ( goro. t 引 k ) ) ( return 0 ー int human-talk( ) { puts ( ″日 e Ⅱ 0. ” return 0 ー 土 n セ dog-talk( ) { puts("BOW! BOW ! ” return 0 ー 6 イ
表現可能としているのです。 クラスにはほかにも継承などといった機 能がありますが , 構造体の中に関数を入れ るだけなら C 言語の構造体でも可能です。 実は C 言語だけでも , 「オプジェクト指向っ ばいプログラミング」が可能なのです。 構造体のメンバに関数を含めるには , 「関 数へのポインタ」を使います。 List1 では , t alk という関数へのポインタをメンバとする HUMAN DOG という名の構造体を作成し , それぞれの talk に human_talk ( ) と dog_talk ( ) を登録して , 実際に登録した関数を使用 しています (Fig. 1 ) 。関数へのポインタの 効果的な使用方法が理解できれば , C + + や J ava のソースを C 言語で書き直したり , オプ ジェクト指向を意識してプログラムの設計 をしたりできるようになるでしよう。 C + + or Java ? 最近では , オプジェクト指向の概念を理 解して使えることが , プログラマのスキル 各種テータ表現 を評価する 1 つの基準となりつつあります。 C 言語を習得したあとにオプジェクト指向 の勉強をするのであれば , 私は C + + ではな く Java をお勧めします。 みなさんがふだん使っているコンパイラ は , そのほとんどが C + + コンパイラだと思 います。 C + + は C 言語の上位互換言語のた め , 綿密なクラスの設計を行わなくても , または C 言語のソースコードが混ざってい ても , コンパイルできてしまうのです。 純粋なオプジェクト指向においては , ク 第 8 回「アルゴリズム①ソート・探索」 ( 2000 年 1 1 月号 ) で掲載したクイックソート を行うリスト (Iist5. c) が間違っていました。 正しくソートを行う修正版プログラム ( ⅱ st51. c) を付録 CD ー ROM に収録しました。 この場を借りて , お詫びと訂正をさせて いただきます。 コラム 1 お詫びと訂正 Fig. 1 「関数へのポインタ」実行画面 GMS-DOS フ刀。ト 0: Vc 磁 g ー s ね「 t ¥ 0S12 月 i st 1 「 t-l say He 日 0. go 「 0 S,ay Bow ! Bov• ! D: '$cmagVc-star±$csI 2 > TabIe 1 変数 配列 構造体 クラス ァータ表現 プログラミング 学習塾 同ロ ~ 格納できるもの 複数の型の複数の値と手続き ( 関数 ) 複数の型の複数の値 型の決まった複数の値の列 型の決まった 1 つの値 ラスに属さない手続きは存在しません。で すが , C 言語を包含する C + + の言語仕様で は , クラスに属さない関数を作ることがで きてしまいます。このことは実際のプログ ラミングでは便利ですが , オプジェクト指 向の観点からは好ましくありません。多く の C プログラマが , C + + プログラマに移行す る際に引っかかるのが , この点なのです。 その点 Java は , 基本的な文法が C / C + + と 同じなことに加え , クラスに属さない手続 きの存在を許さないので , オプジェクト指 向の習得には非常に向いているプログラミ ング言語だと思います。 C + + を使いこなせ るようになるためにも , 勉強の一環に Java を取り入れてみてもよいでしよう。 Java には , たいへん多機能なクラスライ プラリが付属しており , ネットワーク環境 を前提に設計されているため , ネットワー クアプリケーションなどをほかの開発環境 に比べて作りやすくなっています。一般的 な C + + 開発環境の標準的なクラスライプラ リは , Java ほど整備されていないのがほと んどなので , 強力なライプラリでラクをし てプログラミングしたい人にはとくにお勧 めです。 C + + についてオプジェクト指向言語とい う側面以外に目を向けると , C 言語よりも 便利な機能が用意されていることが見てと れます。たとえば , メモリ領域の確保 / 解 放を行う new や delete などを使うと , C 言語 で ma Ⅱ oc ( ) を用いるのに比べて直感的に理 解しやすいソースコードを記述できます。 c 言語プログラミング学習塾 65
渡ってきた場合無視して通過してしまいま す。 m 。 d を呼んだ側は文字列が修正され ることを期待しているので , その影響は , あとで同じ文字列データにアクセスしたと きに , 期待する形と実際のデータが異なる という形で発覚することになります。これ では , いつデータがおかしくなったのかの 特定が困難になってしまいます。なお , こに誤った引数が渡ってくるのは , ユーザ や環境のせいではなくプログラマのせいで あると期待されるので例外を投げるよりも asse れで止めてしまうほうが適切です では , B のようなコードを避け , A のよう なコードを書くにはどうすればいいでしよ うか ? もちろん最初からいい状態のコー ドが書けることはあまりありません。 C + + に限ったことではないですが , プログラム は最初に書かれたときはきれいでも機能拡 張やバグフィックスのために徐々に全体の 見通しが悪くなり , 保守性は劣化していき ます。そのため , ときどき立ち止まり , 「機 能を変えずにコードの品質を上げる」こと を目標にした作業が必要になってきます。 この作業を , ソフトウェア工ンジニアリン グの世界ではリファクトリング (refactoring) と呼びます。プログラムは自動車などと同 様 , ときどき整備・点検をしないといけな いものなのです。 リファクトリングにおいては , たとえば 次のようなことに注意が払われます。 ・クラス名 , 関数名 , 変数名には機能に 対し適切な名前が付いているか ・複数の場所で同じようなことをしてい る場合 , これを関数にまとめることは できないか ・ 1 つのクラスで多くの機能を実装して いる場合 , 分割できないか ・実行時のエラーのとき , 起こった場所 と理由がわかるようになっているか ・オブジェクトを操作する理不尽な制約 があるとき , これを取り外せないか ・関数の引数やオブジェクト間に無用な 32 C MAGMINE 2001 3 依存関係はないか ・同じ計算を何度もやっていて , 効率の 悪いことをしていないか ほかにもいろいろあると思います。リフ アクトリングを行うと , コードの品質が向 上するだけでなく , 自分自身の頭のなかで も全体の構造を整理し直すことになるので , 新機能を追加するにもどこをどう変えれば よいのかがわかりやすくなります。 私の経験では , 次のようなことが気にな りだしたらリファクトリングの実行を検討 すべき時期です。 ・コードの断片をコピーしてきて , ちょ っと修正して使うことが多い ・型のキャストを多用するようになって ・ 1 つのバグを修正するのにあちこちを 直さないといけない ・単純なコーティングミスによるバグか 多発している 機能を変えずにいろいろな修正作業を行 うという意味では , チューニングというも のもあります。こちらはパフォーマンスの 向上に主眼を置いているのに対し , リファ クトリングはプログラマの理解を高め , 次 の機能拡張への準備をすることが中心です。 コンピュータのためでも利用者のためでも なく , 製作者を助けるのがリファクトリン グの使命です。実際には , とくにビジネス の現場でのプログラミングでは , 短期間・ 低コストで完成させることが重要な課題に なりがちであるため , リファクトリングは おざなりになることがしばしばありますが 長期にわたってつきあうプログラムにおい てはときどきリファクトリングを実施する ことは高い効果があります。 「問 11 」 ②特定の型において異なる実装を与える ことができ , テンプレートの運用範囲 が広くなる ・解説 テンプレートに関する問題です。テンプ レートの specialization は , C + + のなかでもか なり高度なトピックなので知らない読者も 少なくないはずです。また , 今のところコ ンパイラによってはサポートが部分的にし かされていないこともあるので , どこでも 使えるというわけではありません。上級者 向けの話題として読んでください。 テンプレートとは , 何らかの型を引数に して初めて具体化するクラスや関数である ことを再確認しましよう。これにより , た とえば STL においてはタイプセーフなコレ クションクラスが手軽に利用可能になりま した。しかし , どのテンプレート引数にも 同じコードで期待する動作をするわけでは ありません。例題として , 2 つの引数の比 較結果を返す関数 c 。 mpare を書いてみます。 普通にテンプレートを使うと以下のよう になります。 template<class T> b06 compare (const T& l, const T& 「 ) { return ーく r; } これは , 型 T に対して " く " で比較をしてい るため , プリミテイプ型であれば通常の大 小比較を , ユーザ定義クラスであればそれ に対応した叩 erator くを起動することになり ます。しかし , T が char * である場合はど うなるでしようか ? この場合は , 単純に " く " で比較するとアドレスの大小による比 較になってしまいます。これはたいていの 場合 , char * の比較としては望ましくない 挙動でしよう。 そこでテンプレートの specialization を使 います。これは , テンプレート引数が特定 の場合に特定の実装を提供するものです。 この例の場合は , 次のように書きます。 template<> boolcompare<char* >(const char* し const char* 「 ) { return strcmp(), r) <0; } template く >" という語句が specialization
・仕事内容 ・募集職種 プログラマー、モーションデザイナー、アザ ①プログラマー②モーションデサイナー③ CG テサイナー ①プログラム作業等 ④ 2D デサイナー⑤プランナー ②イベント及びバトルモーション作成等 ③ 3D モデル作成等 ④プロダクションテサイン ( キャラクター設定、メカニック設定、美術設定等 ) ⑤企画立案及びそのデータ作成、演出、絵コンテ作成等 ・募集資格 18 ~ 30 歳位迄 RPG 開発経験者・ PS2 用ソフト開発経験者歓迎 1 必須使用言語 : C 言語 ( C + + のみは不可 ) 、その他使用言語 : アセンブラ等 2 主な使用ソフト : Softimage ・ Maya 3 主な使用ソフト : Maya ・ Softimage 4 主な使用ソフト : Photoshop ・ Painter ・ lllustrator ・待遇 【勤務時間】裁量労働制 【給与】年俸制 300 万 ~ 1000 万円・年俸を 16 で割り、 1 / 16 を月々支給。残りを賞与時に支給。 ※経験により優遇※報奨金制度有り 【待遇】昇級年 1 回、賞与年 2 回、社会保険完備、交通費支給、報償休暇制度、報奨金制度 【休日休暇】完全週休 2 日制 ( 土・日 ) 、祝日、夏期休暇 ( 9 日 ) 、年末年始 ( 6 日 ) 、有給休暇 【勤務地】横浜市神奈川区 ( 京浜急行「神奈川新町」下車徒歩 7 分 ) 〇〇〇〇 ロ新製ロ無 一口日当ロ ロロド認市第引 新寒当幇ロ巧 ロ蹣可ロロ アザ ・会社概要 【事業内容】ゲームソトの企画・制作・ ( 株 ) ナコ出資により設立した会社です ( 現在、 PS2 用大型 PG を制作中 ) 【会社概要】設立 1999 年 10 月資本金 / 00 万 ・応募要項 【応募】羸書 ( 写 ) 及び作品 ( 経験の方は職務経歴書・携わ。た作品の概略・担当バートが 分かる書類を面封こと ) を下記住所で郵送して下さい。書類選考の上、追って面接日時を通 知します。 【作品】①ハソコン上、またはゲー機上で実働できるプログラム作品②③ CG 作品 ( ビデオ、 プリントアトされたものいずれで可。データ上のものはプリントアウトして下さい ) ④ B4 サ イズまでのラスト、デサイン画等ジャンル問わず・コピー可。 B4 サイズを超えるものについ 、データ上のものはリントアウトして下さい ) ⑤ゲーム企画書、シナリオ等 ては縮小コ 〒 221-0031 神奈川県横浜市神奈川区新浦島町 1-1-32 ニューステージ横浜 株式会社下イリソフト採用係 ( T 年 L : 045-450-2227 ) URL:http://www.monolithsoft.co.jp ・応募の秘密は厳いたしす。・原則として応募書類、作品の返却は致しませんのでご了承下さい 、プランナーを募集 " "
standard することのほうがはるかに簡単なことだった。 最後に , 必要性の競合からくる問題がある。標準に適合する ことはいくつかの問題の 1 つにしかすぎない。標準への適合は , 顧客が理解し , 要求する範囲に限り重要なものにすぎない。コ ンパイラベンダは , それ以外の分野でも顧客を満足させ続けな くてはならない。パフォーマンスの改善 , 他言語との統合 , ウ インドウライプラリ , マルチスレッドライプラリの改善 , 開発 環境との統合の改善などなど。このリストには果てがない。 市場が求める機能は常に開発リソースを上回る。最低限言え ることは , 標準への適合がインプリメンタにとって重要になる のは , そのメッセージをやかましく聞かされたプログラマにと って非常に重要になったときに限る。 べンダによっては , (Microsoft はとくにそうだが ) 顧客を囲 い込むために標準を意図的に反古にしていると非難されること がしばしばある。コンパイラ業界に関しては , 少なくとも私た ちの顧客については , 誰かがこういうことをしたという証拠を ~ 見たことはない。しかし , " 標準への準拠 " がコンパイラベン ダのリストの筆頭に常に置かれるとは限らないことは言ってお いたほうがいいだろう。そして , 顧客が、・標準への準拠 " を自分 のリストの筆頭に置くまでは , コンパイラベンダも決してそれ をリストの筆頭に置くことはない。 く iostream. h > などの名前の従来の C + + ヘッ ダ全部に何が起こったのですか ? 名前の末尾が ". h " で終わるヘッダは標準 C + + ライプラリ △ の一部ではない。 (<iostream> のような ) 拡張子が付かな い新しい数ダースのヘッダが , 従来のヘッダに取って代わった。 多くのべンダは従来のライプラリの出荷も継続しており , ユ ーザはたとえばく iostream. h > などの古い名前で従来のヘッダを 呼び出すことができる。わずかながら , 従来の名前をつなぎと して提供しているべンダもある。つまり , 従来の名前のヘッダ は新しいへッダを適当にインクルードするように方向転換する ので , 既存のコードをそれほど変更しなくても済むようにして いる。 ただ , 古いへッダと新しいへッダを混在させないように注意 してほしい。そうすると , 一緒に動作させることを意図してい ないライプラリを混ぜてしまう結果につながる。ニュースグル ープには List 1 のようなコードを含む , 助けを求める嘆願が繰 り返し生じている。 List 1 では最初の #include で従来の iostream ライプラリのヘッ ダをインクルードする場合 , この従来のヘッダは最新の文字列 ライプラリのことをまったく知らない。それゆえ , クラス strin g が適切な挿入子を持たないという意味の謎のエラーメッセー 72 C MAGMINE 2 1 3 古いへッダと新しいへッダが混在 #inc lude く iostream. h> #inc lude く string> int main( ) { / / 文字列から he Ⅱ 0 を言う。 string str("He110, world" cout くく str くく end 嵭 return の } ジを受け取ることになる ( クラス string 自体は挿入子を持って いるのだが , 古風なクラス ios 仕 eam はそうではない ) 。 あるコンパイラが既存のコードを変更せずにコンパイルして くれたなら , それは大いにけっこうだが , そこにコードを付け 加えるときには注意してほしい。古いへッダと新しいへッダを 混ぜて使いたくなった場合 , ただちに深呼吸して落ち着いて考 えることだ。安易に新旧ヘッダを混ぜて使う前に , コードから 古いへッダを取り除くときがきたということだから。 新旧ヘッダを混ぜて使ってはいけないという事 情はわかりました。それで , List 2 のように "HeIIo, wo 月 d " のプログラムを変更しました。これ でもまだコンバイルできないのはなぜでしようか ? 標準 C + + がやったことは , ライプラリへッダの名前を変 更しただけではない。名前空間 (namespace) と呼ばれる 言語機能を新たに使えるようにした。 いちおう , プログラマが定義した名前とライプラリの名前 との衝突を最小限にとどめるためという理由で , 本質的には , すべてのライプラリにおける名前 ( 少なくともマクロは別だが ) は名前空間 std の中で定義されている。 List2 のプログラムは , List3 に示すように修飾子を追加して修正することができる。 もしくは , List 4 に示すように中力ッコの定義を追加して , 名 前空間 std のすべての名前をグローバル名前空間に持ち上げて もよい。 純粋主義者のひんしゆくを買うにしても , あとの形式のほ うが必要な変更をプログラムの先頭に局所的にとどめること ができる。先頭は , すでに include 指令 (directive) を書き換えて しまったところである。 この方法が既存のコードを新仕様に対応させるやり方とし ては常識的なものだと私は思う。既存の実装の間でも , 名前 空間のサポートはまだ出そろっていない。移植性のあるコー ドを書く必要があるならば , 同じ場所に # ifdef 構造を少々使う ことで対応することができる。 本来意図された目的にかなうようにするには名前空間をど
この rpm の場合 , ューザが手作業でやる べきインストールの最後のステップは , (l)/etc/lilo. conf ファイル中の Linux カーネ ル名を新カーネルの名前に書き換える ( 2 ) / sbin / Ⅲ 0 を実行して凵 LO プログラム に対し書き換え後のⅢ 0. conf を有効に する という 2 つの手順です。カーネルの自力更 新など過去にやったことのない私も , 今回 の distro のべンダに指摘されておばろげに 思い出しました。そういえば , どこかの本 か雑誌記事にそんなことが書いてあったな /etc/lilo. conf の中の , vmlinuz—の項 を , 更新したカーネルのファイル名に書き 換えるのです。たとえば , こんなふうに書 かれています : image=/boot/vmIinuz-2.2.17-2 そのべンダが作った rpm パッケージのイ ンストールスクリプトが , この 2 つの手順 をやんない理由は不明です。たぶん , パッ ケージの設計者が顧客のレベルではなく自 分のレベル ~ 古参べテランの Linux ユーザ のレベルに合わせて設計したせいでしよ う。べンダからのメールには「今後は自動 的に LILO の設定を上書きするよう , パッ ケージを作成しようと思う」と書かれてい ました。ぜひ , そうしてください。カーネ ルの自力更新経験のあるべテランユーザし か顧客として想定していない distro は商品 として成功しないと思うし , いずれにして も「この手順とこの手順はユーザ自身が手 作業でやってくれ」というドキュメントや メッセージは必要と私は常識的に思いま す。べテランユーザにとっても , そんなル ーチン的な仕事はスクリプトが自動的また は対話的にやってくれるほうが便利です。 自分で手作業でやる必然性が , まったくあ りませんから。 このカーネル更新の一件で 3 ~ 4 日がつ ぶれたように記憶しております。 LILO の 更新以外にもうひとつ , 無ドキュメントの 問題があったんですよ。その商用サウンド ドライバはターゲット環境の上で自分を m ake しインストールする際に適合カーネ ルのソースも必要とするのです。しかしべ 1 イ 0 C MAGMINE 2001 3 ンダの指定は「新カーネルの rpm をダウン ロードしてインストールしてくれ」だけで , ソースも必要とは言っていない。この件は , そのサウンドドライバのインストールの工 ラー終了時の make. log をたまたま見たため に気がついたことです。 Linux のソースは 現在非常にでかいですから , それをいちい ちダウンロードさせるというユーザサポー トはちと疑問に思います。まあ , CD-ROM か MO でも送ってくださいよ。 今回の私の一件にかぎらず , Linux の配 布系をめぐっては , 正式リリース後のトラ プルないしトラブル対応がよくあります。 それは Windows でも同じだと思いますが , アップデートのためにユーザに面倒な手作 業をさせないという点では , Windows が 優っているでしよう。 Linux べンダとして は , インストールスクリプト等の内容を充 実させるとともに , どうしてもユーザ自身 がやんなきゃならない部分に関しては , そ れを完全初心者でもできるようにドキュメ ンテーションを完備していただきたいと思 います。それと , パソコン用の主な周辺機 器はすべて , API の標準化が望まれます。 サウンドチップなんて , たかが D / A コンバ ータに毛が生えた程度の I ですから , せ めて最低限の共通基本機能に関しては各社 が協調して API を統一していただきたい。 そうすれば , どんなサウンドチップが搭載 されていようとも単一のドライパソフトだ けで対応できるようになります。もちろん 統—API を使うドライパソフトは , 私程度 の " 一般しろうとプログラマ " でも十分に書 けるでしよう。 Web ブラウジングの多機能化 今回作ろうと思っていたプログラム , 上 のような数々のトラブルに見舞われなけれ ば本稿締切までに最初のバージョンは完成 していたであろうプログラムは , 「複数の HTML に分かれている大きなドキュメント を一括ダウンロードする / させるアプレッ トまたはサープレットまたは Java アプリケ ーション」です。ドキュメント全体がひと つのファイルで提供されていなくて , 各章 / 各節が目次ページ上の個々のく A HREF= になっている場合 , 日本は電話料金が異様 に高いからそれらをのんびり見ているわけ にいきません。ひとつひとつを順に表示さ せてそのたびにファイルをセープするやり 方も章 / 節数がきわめて多いドキュメント ではかったるいです。 こういう目的ーー複数リンクー括ロード ーーのための市販ソフトは , Windows 向け には何種類か発売されています。しかしそ れらはいろんな余計な機能盛り沢山で , 値 段も高いです。 Java で自作しておけば , wr ite once, run anywhere ですから Windows 上 でも Linux 上でも同じプログラムが使える はずです。 Java では , インターネット上の WebV'k ージにアクセスするプログラムを ごく簡単に書けます ( ちょっと頑張ればプ ラウザの自作も可能 ) 。 まず , ページを表示させるためには , そ のページの絶対 URL を表している文字列 http://www....… " から java. net. URL オプジ ェクトを作り , その U 糺オプジェクトを jav ax. swing. JEditorPane の setPage ( ) メソッド に渡すだけです ( List 5 ) 。これで , 現在の 自機の上にインターネットへの接続状態が あれば , 目的の U 糺にあるべージが表示さ れます。そのべージの中のリンクを通常の マウスクリックでたどりたいときには , J EditorPane オプジェクト (List 5 では jep) に HyperlinkListener の自作実装クラスを登録 (addHyperlinkListener ( ) ) しておきます。 通常の Web プラウザ (lnternet Explorer, Ne tscape など ) ではリンクをクリックすると リンク先のページが表示されるだけです が , この方法でプログラムを自作すると , 何かほかの処理をさせることも可能です。 しかし今回の目的は , マウスクリックで いちいちリンクをたどるのではなく , その ページの中のリンクのリンク先ドキュメン トをすべて自動的に一括ダウンロードする ことです。そのためにはたぶん , そのペー ジ ( 目次ページなど ) の HTML ファイルをダ ウンロードし , その各行を読みながら <A H F = の部分を取り出し , これら H F 属
void f(X x) ; という関数に対し , えば , 28 C MAGAZINE 2001 3 は , ール ( 戻りアドレスを push してジャンプ ) し 数をスタックにブッシュし , 次に関数をコ 常 , アセンプリ言語のレベルでは , まず引 でコンパイルした関数呼び出し部分は , 通 インライン展開に関する問題です。 C + + ・解説 [ 問 7 」 ースパイケースになります。 便利なので , explicit を付けるかどうかはケ といった変換は暗黙にやってくれたほうが ス , フルバス文字列からファイルクラス , から文字列クラス , d 。 uble から複素数クラ は何の影響も与えません。しかし , char* もちろん explicit と書いても実行時の効率に なら暗黙の型変換を防ぐことができます。 xplicit を付けることになるでしよう。これ いては , すべての 1 引数コンストラクタに e わかりやすさを旨とするプログラムにお とする必要があります。 x x[3] = { 0 , 1 , 2 } ; (X ( 0 ) ) としないといけません。同様に で , f ( 0 ) はコンパイルエラーになります。 f を付けると暗黙の変換が行われなくなるの があります。コンストラクタ宣言に explicit こういうときのために explicit キーワード 数だと勘違いしているのかもしれません。 すプログラムを書いた人は f は数値を渡す関 が難しくなりがちです。あるいは , 呼び出 し X : : X で例外が投げられたときはその検出 出しているという印象を受けないので , も ( 0 ) はばっと見ではコンストラクタを呼び という呼び出しが可能です。こうなると , f ます。これに対してインライン展開をする と , 関数呼び出しが関数本体に置き換わる ため , 実行時に必要な CPU のインストラク ション数は減少します。 この機能は , # de ⅱ ne を使ってマクロで関 数を定義した場合と似ています。 2 つのう ち大きいほうを返す関数を書く代わりに #define max(A,B) ()A > B)? A : B) というマクロで代用する例を見たことがあ る人も多いでしよう。これは C 言語にもあ るテクニックです。こうして効率化できる かどうかは , 関数のサイズと呼び出される 箇所の数に依存します。パフォーマンスが 稼げるのは , 関数のサイズが小さく , ソー スコード中での登場回数の割に実行回数が 多い場合です。関数のサイズが小さいほど よいのは , 関数呼び出しにかかるコストが 相対的に大きくなるからです。また , 展開 すればプログラムサイズは増加するので , これは性能の低下要因になります。実際の ところ展開すべきかどうかは簡単には判定 できません。 inline キーワードの目的はまさにこれです が , マクロと違うのは展開するかどうかの 判断をコンパイラに任せる点です。 さて , 問題の答えです。まず ( ア ) は , 再 帰関数です。再帰関数は自分自身を呼び出 しているので , これを展開しようとすると 無限に展開が続いてしまいます。したがっ て , この関数 facto ⅱ al を展開することはで きません。いちおう , コンパイラが十分に 賢ければ , 定数による呼び出しを展開して 置き換えることは理論的には可能です。た とえば factorial(5) という呼び出しを見たら 定数 120 ( = 5 ! ) に置き換えてしまう , という具 合です。しかし現在はそこまでしてくれる コンパイラはまずない ( 研究室レベルでは あるかも ) でしよう。 ( イ ) は , 仮想関数になっています。仮想 関数は , 派生クラスによってオーバライド することができるので , 仮想関数テープル に関数のアドレスを格納し , 実行時には毎 度それを参照して実際の飛び先を決める , という処理が行われます。したがって , 仮 想関数はその関数が収録されているコード のアドレスがとれる必要があります。しか しインライン展開されてしまうと関数とし ては形をとどめなくなってしまうので , ア ドレスをとる操作はできません。したがっ てこれは展開できないことになります。 ( ウ ) は , 例外を throw しています。しかし これは展開できるかどうかには関係ありま せん。例外は for や if といった制御構造の一 種なので , インライン展開できるかどうか には関係ありません。 前述したように inline キーワードを使っ た場合は , 展開するかどうかはコンパイラ の判断に委ねられます。その結果展開しな いことになってもコンパイラは何も教えて くれないので , この出題のようにそもそも 展開できない関数に in ⅱ ne を付けてもコンパ イルエラーにはなりません。一方 , #define はコンパイラに渡る前にプリプリセッサに 渡されるので必ず展開されます。したがっ て再帰関数に使えばすぐ工ラーになります。 つまり , inline はプログラマがコンパイラに 対して , 「もしできるならこれをインライン 展開してくださいね」と頼むことなのです。 また , デバッグ時には展開されずにいた ほうが元のソースコードとの対応がとりや すいので , コンパイラはオプションによっ てインライン展開の決定について制御でき るようになっているはずです。 ⅲ line キーワードの導入により , マクロを 使ってトリッキーなコードを書く必要は少 なくなりました。普通に関数を書き , inline を付けたりコンパイラオプションを調整す ることで代用ができるのです。実行効率を 追求するときには関数のインライン展開は とても重要です。 なお , 関数の宣言部分に続けて直接に実 装を書いた場合 ( 問題の ( イ ) のような形式 ) , コンパイラは inline が付いているとみなすこ とになっています。