ノード - みる会図書館


検索対象: 月刊 C MAGAZINE 2001年10月号
105件見つかりました。

1. 月刊 C MAGAZINE 2001年10月号

支援ツール」は , BorIand C + + Complier 5.5. 1 をインストールする際に必要な環境設定 をウイザード形式で行えるツールです。 このプログラムは , WmdowsNT4. O(SP 6 ) / 208 / 98SE で動作確認をしています。く \ BorlandYBcc55Y> ディレクトリ , およびく \ tool}setbcc> ディレクトリにある各 READ ME. "IXI 、もご覧ください。 このプログラムは Borland C + + Builder 5 Professional で作成しました。また , このプ ログラム ( ソースコードも含む ) は配布や改 変を自由に行うことのできるフリーウェア として公開します。ご意見・ご要望を寄せ られたみなさまに感謝いたします。 Free Pascal CompiIer Ver. 1.04 81 べージから始まる特集 2 「フリー開発環 境でアプリケーションを作ろう Free Pas cal Compiler 編」はご覧いただけたでしよう か。 Free pascal CompiIer は , 純粋な Pascal 言語だけでなく BorIand DeIphi や BorIand KyIix で採用されている Object Pascal のソ ースも処理できるコンパイラで , GNU Ge neral public License のもとで公開されてい るため無償で利用可能です。 く FPC> ディレクトリには , DOS, Windo ws , Linux, FreeBSD , OS / 2 , Amiga 用 Free pascal Compiler とドキュメントが収 録されています。 Ruby 1.6.4 「 Ruby 」は , まつもとゆきひろ氏が開発 した純国産のオプジェクト指向スクリプト 言語です。同氏のご協力により , 最新版 1. 6.4 が 281 年 6 月 4 日にリリースされました。 く YrubY> ディレクトリに最新版の Ruby 1.6.4 を収録しました。また Windows 環境で利 用するためのモジュールを , 作成者である 有馬氏のご協力により , <}ruby}rbcw> ディ レクトリに収録しました。 それぞれのインストール方法や詳細に関 しては , 展開後に生成されるドキュメント ファイルをご覧ください。 ・ CD - ROM のディレクトリ構成 index. html ・ Borland DeIphi ・・・ CD - ROM 収録プログラムの紹介 ( HTML ファイル ) deIphi6personaI ・・・ BO and Delphi 6 Personal Borland Delphi 6 Enterprise 60 日トライアル版 delph i6triaI• Kylix kylixopenedition ・・・ Borland Kylix Open Edition kylixtrial• Lhasa t00 Ruby LS ℃ FPC bcc55 bcc ・・ TOKU2 ・・ TOKUI ・・ C MAGA SETBCC ・ jscript , ・・ Borland Kylix Server DeveIoper 60 日トライアル版 Ruby 1.6.4 ・・ LSI C -86 Ver 3.30C 試食版 BorIand C + + CompiIer 5.5.1 ・ JavaSc 「 ipt 編 ・・ Borland C + + CompiIer 5.5.1 編 ・・特集 2 「フリー開発環境でアプリケーションを作ろう」 ・・・特集 1 「プログラムはもっと速くなるプログラムの高速化・最適化」 •••Borland C + + CompiIer 5.5 インストール支援ツール Ver. 1.5a ・・•lzh/zip 解凍ツール "Lhasa" eMbedded VisuaI T00 3.0 編 Free PascaI CompiIer 編 wince fpc TOUKOU ・・ CPP ・ Java ・ StdCCPP ・・ episteme ・ ・・・・、・・一一・、・読者投稿セレクト Di 「 ec Ⅸ 8.0 による 2D プログラミング ・・・ Ge 目 nto C WorId!! ー C 言語入門講座ー ・・・ C プログラマのための C + + 入門実践 C + + ゼミナール ・・スタートアップ Java —Java 言語事始ー ・・ Standard C ℃ + + どなこびてククのオブジェクト工房 Enjoy PerI Programming モジュールを活用しよう Perl Ruby ・・ TAKARA NETWORK ALGO PUZZLE ・ APPARE ・ LANG lnfoBarrier ・ BorIand DeIphi 6 PersonaI ・・・ Ruby マスターへの道 アルゴリズム入門プログラミングの宝箱 ・・・画像処理を極めるアルゴリズムラボ ネットワークプログラミングのアトリエ ・・・ C マガ電脳クラブ ・・フィンローダのあつばれご意見番 ・・・学問のススメ千言万語 ・・・真紀俊男のローテク講座 Copyright 02001 Borland S0ftware Corporation. AII Rights Reserved. ・ BorIand DeIphi 6 Enterprise 60 日トライアル版 Copyright ( 02001 Borland S0ftware CO 「 PO 「 a 哲 on. AII Rights Reserved. ・ BorIand Kylix Open Edition Copyright 02001 Borland Software Corporation. AII Rights Reserved. ・ BorIand Kylix server DeveIoper 60 日トライアル版 Copyright 02001 Borland Software Corporation. AII Rights Reserved. ・ BorIand C + + Compiler 5.5.1 Copyright 02000-2001 Borland Software Corporation. AII Rights Reserved. ・ LSI C -86 Ver. 3.30C 試食版 Copyright 01993 LSIJAPAN CO. ,LTD. AII Rights Reserved. ・ Ruby 1.6.4 Copy ⅱ ght01993-2001 Yukihiro Matsumoto. AII Rights Reserved. ・ Ruby Entry Package fo 「 Win32 ・ Free Pascal Compiler Ver. 1.0.4 ・ LHASA Ver. 0.17 Copy 「 ight 01994-2001 Takemura. AII Rights Reserved. ・ BorIand C + + Compiler 5.5 インストール支援ツール CD-ROM Contents 20 /

2. 月刊 C MAGAZINE 2001年10月号

のでしようか。 Web サーバでは環境変数 "CONTENT LENGTH ' にバイト長を設定 して CGI を起動してくれます。 CGI では環 境変数 "CONTENT_LENGTH" に収められ たバイト数だけ標準入力 ( cin ) から読み出 せばいいのです。 フォームから CGI へのメソッドには POS T のほかに GET があります。 List8- ①を , く fO て m method= get に書き換えてください。 GET のときはフォ ームに入力されたデータは , 環境変数 " Q UERY_STRING" に設定されています。ま た , " PO 訂 " か " GET " かは環境変数 " QU EST_METHOD" の値で判別できます。 cp p—trial. cpp (List 9 ) の実行形式を /cgi-bin に 置き , ボタンを押すと Fig. 4 のよ うな出力が得られます。 フォームデータの処理 text=&password=&texta て ea=&se ー ec t=C%2B%2B Fig. 4 によると CGI はこんなデータを読み 入力データを・ & で切り分ける関数テンプレート split_cgi 10 #inc lude <string> / / string temp ー ate<typename OutputI terator> Output I terator り分けた結果 ( " く名前 > = く値 > " ) の数となり ます。入力データに現れる、 & ' の数 + 1 が切 文字列の切り分けは関数 strt 。 k ( ) を使い ・ step-l : 客で切り分け 付けていきましよう。 という 3 段階の手順を踏みます。 1 つずつ片 3. [ 2 ] に現れる ' %.. ' を数値に変換 2. [ 1 ] を ' = ' の前と後に分割する 1 . ' & ' を区切り文字として切り分ける 前 > とく値 > の組を取り出すには , というわけで , フォームデータからく名 えられています ) 。 されています ( 例外的に空白は。 + ' に置き換 どがあれば、 % ' に続く 2 桁の 16 進数に変換 ASCII コードでは表せない文字や冒・ & ' な ります。さらに名前や値の中に漢字などの ません。、く名前 > = く値 > ' を、 & で連結してあ いっても復号規則はそれほど難しくはあり つを復号 ( ? ) しなければなりません。とは 文字列に変換したものです。 CGI 側でこい ームに入力されたデータを長い長い ASC Ⅱ 込みました。暗号めいたこのデータはフォ #include <string> / / string # inc lude く functiona I> / / unary—function #include く u し土はし y > / / pair = ' で分割する関数オブジェクト split return result; POS = amp 十 * て esu ーセ十十 = input. substr(pos, amp-pos); } 引 se ( break; *result 十十 = input. substr(pos); if ( amp = = std: :string: :npos ) { std: :string: :size—type amp = input. find( ' & ' ,pos); while ( true ) { std: :string: :size—type pos = 0 ー split—cgi(const std: :string& input, OutputIterator result) return std: :pair<std: :string,std: :string>(input. substr(0,pos) を input.substr(pos 十 1) std: :string: :size—type pos = input.find( ' std: :pair«std: :string,std: :string> operator( ) (const std: :string& input) const { struct split : std: :unary—function く std: :string,std: :pair く std: :string,std: :string> 〉 { char * * out = new char * [n]; char * * pout ou fO て ( char* p = s してし ok ( 土 n , ” & " 店 p = strtok(), ”に ) ) { *pout 十十 = p; こんなんでいけるはずです。 C + + 屋の僕 はちょっと生意気 ( ? ) な関数テンプレート を作りました (List 10 ) 。これを使うと , #inc ー ude <vector> #inc ー ude く土し e て a し 0 て > std::string in; / / 入力テータ std: :vector<std: : string> ou セー split—cgi (in, std: :back—inserter (out) これで out の中に " く名前 > = く値 > " が挿入さ ますから , char in[N]; / / 入力データ int n = std: :find(in, in 十 N, ' & ' ) これも簡単 , ・ step-2 れます。 = ' の前にある文字列と後 = ' で分割 ( ℃ ' - 、 9 ' , 'A'- 'F' ) から脈 00 ~ OF に変換 6 進文字とみなして変換します。 16 進文字 に、 % ' を見つけたら , それに続く 2 文字を 1 これは少しだけめんどうです。文字列中 ・ step-3 %.. ' の変換 れることでしよう。 というように使えば , " lang / C + + " と出力さ くく result. second くく endl ー cout くく resul し . first くく ' / ' result = sp ( 自 ang = C 十十”潺 split : :result—type result ー split sp; した (List 11 ) 。たとえば , を戻り値とする関数オプジェクトを作りま ing を引数 , std::pair<std::string, std::string> にある文字列に分割するだけです。 std::str するのは , char to—hex (char (h) { if ( ' 0 ' く = ch & & ch く = ' 9 つ 1 イ 2 C MAGAZINE 2g1 10

3. 月刊 C MAGAZINE 2001年10月号

ます。 ・使用処理系ごとのデータ型のサイズを 取得する場合 sizeof( テータ型名 ) ; ・使用変数や配列などの単項式のサイズ を取得する場合 sizeof 単項式ー たとえば int 型のデータの場合でも , 使用 する処理系によって確保されるメモリの大 きさが異なることについて , データ型の解 説時に説明しました。これらの違いをプロ グラムに反映するために , 処理系ごとにデ ータ型のサイズを取得する必要が生じます。 その際 , size 。 f 演算子を使用します。また 使用している変数や配列などのサイズを随 時取得する場合にも使用することができま す。 先ほど文字配列の文字数を取得するため に s 国 en 関数を使用しましたが , strlen 関数 では領域のサイズとは無関係に NULL まで の文字数を返します。それに対して sizeof は , メモリ上に確保されたサイズを取得し ます。 strlen は関数呼び出しが発生します が , sizeof は演算子であるため , コンパイ ル時に指定した領域のサイズに置き換えら れます。使用例を Fig. 3 に示します。 ◆メモリ管理関数の使用例 では , 標準関数を使用してメモリ管理 を行うプログラムの例を見てみましよう ( Li st 4 ) 。 List4 ではまず , double 型のポインタ d を 宣言します。次に 8 行目で sizeof 演算子を使 用して double 型のサイズを取得し , double 型のメモリサイズ 100 個ぶんを malloc 関数 で確保します。その結果を準備しておいた double 型のポインタ d に格納します。 mallo c 関数でメモリの確保を失敗した場合 , 変 数 d には NULL が格納されます。 10 ~ 14 行 目ではメモリの確保に失敗した場合の処理 を行っています。 13 行目で exit 関数によっ てプログラムの処理を終了し , 終了コード 1 をシステムに返しています。 16 , 17 行目で はメモリを確保した変数 d に値を格納しま す。そして , 22 行目で仕 ee 関数により先ほ ど ma Ⅱ oc 関数によって確保したメモリを解 TabIe 5 文字処理を行う標準関数 関数 isalnum( c ) isalpha( c ) iscntrl( c ) isdigit( c ) isg 「 aph( c ) islower( c ) isprint( c ) ispunct( c ) isspace ( c ) isuppe 「 ( c ) isxdigit ( c ) tolowe 「 ( c ) toupper( c ) 6 ロロロロ 処理 英文字または数文字なら真 ( 1 ) を返す 英文字なら真 ( 1 ) を返す 制御文字なら真 ( 1 ) を返す 数文字なら真 ( 1 ) を返す 図形文字なら真 ( 1 ) を返す 小文字なら真 ( 1 ) を返す 印字可能文字なら真 ( 1 ) を返す 区切り文字なら真 ( 1 ) を返す 空白系文字なら真 ( 1 ) を返す 大文字なら真 ( 1 ) を返す 1 6 進表示文字なら真 ( 1 ) を返す 文字 c を小文字に変換する 文字 c を大文字に変換する lSt 2 : 3 : 6 : 7 : 8 : 9 : 10 : 11 : 12 : 13 : 14 : 15 : 16 : 17 : 18 : 19 : 20 : 21 : 22 : 23 : 24 : 25 : 26 : 28 : 29 : 30 : 31 : 32 : 33 : 34 : 35 : 36 : } 文字処理関数の使用例 1 : / * 文字処理関数の使用例 * / #include <stdio. h> #include «ctype. h> 4 : void main( ) int printf( ”蕚 n くく isalnum >>*nn fo て ( 土 = 土く = 12 土十十 ) if p て in セ f ( ”基 n くく isalpha >>%nn for ( 土 = 土く = 12 土十十 ) if (isalpha printf ( ” n くく iscntr ー >>%n fo て ( 土 = の i く = 12 土十十 ) if (iscntrl p て土 ntf ( ” n くく isdigit ”基 n ” fo て ( 土 = i く = 12 土十十 ) if p て土 ntf ( ” n くく isgraph >>*nn for ( 辷 i く = 12 土十十 ) if printf("h<< islower >>%n" fo て ( i=0; 土く = 12 i 十十 ) if printf("%n くく isprint 〉 > ” fo て (i=0; 土く = 12 土十十 ) if printf( ″ n くく ispunct 〉 > n ” for ( 土 = の i く = 12 土 + + ) if (ispunct printf( ”基 n くく isupper > 〉 n ” (isalnum(i)) putchar(i); ( isdigit (isgraph (i) ) putchar(i); (islower ( 土 ) ) putchar(i); (isprint (i) ) putchar(i); fo て ( 土 = の i く = 12 i 十十 ) if (isupper printf("%n"); るか , 数字であるかなどの判定を行うこと がしばしばあります。また , 1 文字ごとに 大文字 , 小文字に変換する処理を行うこと があります ( これらの関数については以前 こではこれらの処理を 紹介しました ) 。 行うための関数を紹介します ( Table5 ) 。 れらの関数を使用するためには ctype. h へ (i)) putchar(i); (i)) putchar(i); ( 土 ) ) putchar(i); ( 土 ) ) putchar(i); putchar(i); ( i ) ) 放します。 このように , malloc 関数 , 仕 ee 関数など を使用することで , C 言語では実行時に動 的にメモリを取得したり , 解放したりする ことができます ( 豆 CoIumn) 。 文字処理関数 ( c 加 e. h ) プログラミングではある文字が英字であ ッダファイルが必要になります。 Getlnto C World ! ! 121

4. 月刊 C MAGAZINE 2001年10月号

を終了し , 終了コードを返すことが可能に なります。これらの関数を使用するために は stdlib. h ヘッダファイルが必要です。 こでは , これらのうちの system 関数に ついて見ていきましよう。 system 関数は呼 び出しているプログラム ( 親のプログラム ) を一時的に中断して , コマンドや他プログ ラムを実行します。そして , そのコマンド やプログラムが終了した時点で呼び出し側 のプログラムを再開します。呼び出し元の プログラムでは処理が中断しているため , 当然呼び出された側のプログラムの動作を 監視することはできません。しかし , 起動 が正常かどうかということについてのみ状 態を確認することが可能です。使用例を ータ Fig. 3 sizeof の使用例 char int int S1ze SIZe S1ze SIZe S1ze b , c [ 5 ]; SIZe; = sizeof (char); sizeof ( int); sizeof c; sizeof b; sizeof a; 変数 size の値は 1 変数 size の値は 32 ビット系の処理系では 4 , 1 6 ビット系の処理系では 2 変数 size の値は 32 ビット系の処理系では 20 , 16 ビット系の処理系では 10 変数 size の値は 32 ビット系の処理系では 4 , 16 ビット系の処理系では 2 変数 size の値は 1 lSt 3 : 6 : 7 : 9 : 10 : 11 : 12 : 13 : 14 : 15 : 16 : 17 : 18 : 19 : 20 : 21 : 22 : 23 : } malloc 関数 , f 「 ee 関数 , exit 関数の使用例 1 : / * malloc 関数 , 仕 ee 関数 , ex 辻関数の使用例 * / 4 : void main( ) #include <stdlib. h> 2 : #include <stdio . h> doub * d = ma Ⅱ oc ( 100 * sizeof(double)); if( d = ) p て土 ntf ( ”メモリの確保に失敗しました。″ーメッセージを出す 。面厄型のポインタを宣言する 血Ⅱ。。関数でメモリ領域を確保する 日。 c 関数の結果を確認する メモリ領域の確保に失敗した場合、 Fig. 2 に示します。 メモリ管理 ( std ⅱ b. h ) 1 20 C MAGAZINE 2001 10 に利用される sizeof 演算子についてまず説 こで , これらのメモリ管理関数で頻繁 ッダファイルが必要になります。 これらの関数を使用するためには stdlib. h へ リを随時操作することができます ( Table4 ) 。 標準関数を使用して , プログラムからメモ 任意の時点で確保し , また解放するための 動的メモリ割り付けがあります。メモリを 操作するための機能として , 前回紹介した またメモリの使用状況を効率的に把握して そこでメモリのムダ遣いを解消するため , しておくことはあまり望ましくありません。 状況では , あらかじめ配列の最大数を宣言 しているパソコンもあります。このような いパソコンもあれば , 512M バイトも搭載 ん。メモリを 32M バイトしか搭載していな ソコンなどが規定されるわけではありませ どを作成する場合は , 配布先や使用するパ です。しかし , ツール類やフリーソフトな で配列の最大数を宣言しておくことが可能 れます。そのため , ある程度プログラム内 や処理可能なデータ数の上限などが規定さ ソコンの仕様 ( メモリやディスクの搭載量 ) ムでは , あらかじめ設計時に使用すべきパ た。実際に仕事で作成する業務用プログラ ってメモリを確保できることを紹介しまし 前回 , 記憶クラスの説明時に , 関数によ ex 辻 ( 1 free(d); printf( ″ d [ 49 ] printf( ″ d [ 00 ] d [ 49 ] d [ 0 ] = 567. = 123. , d [ 49 ] 戻り値 1 ( 0 以外はエラー ) で終了 d 。曲型変数に値を格納する 格納された値を画面に表示する ェ ee 関リを解す 豆 COIumn メモリ割り付け関数 ( m 訓。 c , c 訓。 c , 「 e 訓。 c ) の引数の型と関数の型 m 訓 oc 関数の仕様を見てみましよう。 void * malloc( size_t size ) m 訓 oc 関数の引数のデータ型は size t と なっています。 ANSI 規格では , size t とい うのは sizeof 演算子が返す「符号のない整数 型 (unsigned long int) 」を示しています。 の size t というデータ型は stddef. h, stdlib. h, stdio. h, string.h, time.h のヘッダファ イルをインクルードすることで使用可能に なります。 なお , calloc, 「 e 訓 OC 関数についても確 保する領域のサイズを指定する引数型はす べて size t となっています。つま去これら の関数で確保する領域のサイズは必ず正の 整数の範囲内でなければならないというこ とです。 次に関数の型 ( 戻り値型 ) を見てみましょ sizeof 演算子では , 変数名またはデ ◆ sizeof 演算子について 明します。 う。 m 訓 OC の戻り値は ANSI では void * と なっていますが , ANSI より前は char * で した。このような処理系 ( 昔の UN Ⅸ系で仕 事をするような場合 ) において , cha 「以外の 領域を割り付けたい場合は、キャストによ り使用する型に変換することになります。 たとえば , int 型へのポインタを使用する場 合 , 次のような形式で記述します。 int * pi; pi = (i nt * )malloc(sizeof(i nt)); 同じポインタ型であっても , int * から c har * へのような型が異なる代入は , War ning が出力されるのでキャスト演算子が必 要となります。しかし void * からほかのポ インタ型へ , もしくはほかのポインタ型か ら void * への代入は Warning が出力されま せん。 型名のいずれかで項目のサイズを取得する ことができます。 sizeof 演算子は次のような書式で使用し

5. 月刊 C MAGAZINE 2001年10月号

DVD-ROM 連動企画 協 al Studio . NET 〃 2 日本語版最初の一歩 Fig. 2 Visual studio . NET の製品内容 ・エンタープライズ開発ツール ・ VisuaI StudiO AnaIyzer ・ VisuaI SourceSafe Application Center Test ・ Visual StudiO 工ンタープライズテンプレート ・ ViSiO ・言語ツール ・ VisuaI Basic . NET ・ VisuaI C# . NET ・ VisuaI C + + . NET ・ライプラリ・ランタイム NET Framewo 「 k ・ MFC ・ ATL ・ C-RTL を利用してインストールしてみます。 Studio . NET 本体を本誌付録の DVD - ROM ge をインストールします。後半では Visual ントロールバネルを利用して IIS と FrontPa 分かれています。前半では Windows のコ す。インストール手順は大まかに 2 段階に dio . NET のインストール手順を説明しま Windows 2000 の場合を例に Visual Stu に必要な環境は Fig. 4 のとおりです。 ET をインストールしてみましよう。動作 それではいよいよ実際にⅥ sual studio . N インストール することができます。 ーゲットを自分の得意な言語を選んで開発 ます (Fig. 3 ) 。プログラマは , これらのタ 方で , 開発ターゲットも実に多岐にわたり このように多くの言語をサポートする一 び出すこともできます。 らさまざまな . NETFramework クラスを呼 用が可能となります。逆に , C + + コードか ⅸに対応したほかのあらゆる言語からの利 (wrapper) を記述することで . Framewo C + + マネージ拡張を用いて簡単なラッパー スが実現できます。 C + + クラスに関しては , amework クラスと C + + クラスの相互アクセ C + + マネージ拡張の適用により , . NETFr ・ . NET Framework アプリケーションとの連携 す。 し , 移行を迅速化するうえで大きな利点で 可能です。このことは , 移行の負担を軽減 だけに C + + マネージ拡張を適用することが Fig. 3 VisuaI Studio . NET の開発ターゲット ・クライアントサイド ・ Windows フォームアプリケーション Windows フォームコントロール ・コンソールアプリケーション ・サーバサイド ・ ASP . NETWeb アプリケーション ・ . NET コンボーネントライブラリ ・そのほか ・ Windows NT サービスコンポーネント ・ Web コントロールライブラリ ・ ASP . NETWeb サービスコンポーネント こでは V1sual Studio . NMI 、に必要 項目 ) 。 アップデートを行います ( Fig. 6 の 1 番目の ( 1 ) 最初に Windows コンポーネントの 各段階のインストールが行われます。 めます。 Fig. 6 の各項目をクリックすると た 3 段階の手順に従ってインストールを進 起動します (Fig. 6 ) 。インストーラが示し プに挿入すると , インストーラが自動的に V1sual Studi0 . NFT の DVD-ROM をドライ 0 Visual Studi0 . NET のインストール ールを完了します。 ( 5 ) ーをクリックして , インスト クします。 ontpage 2000 server Extensions 」をチェッ ( 4 ) ーボタンをクリックし , 「 Fr ンサービス ( Ⅱ S ) 」をチェックします ( 日 g. 5 ) 。 ( 3 ) 「インターネットインフォメーショ ンポーネントの追加と削除」を選択します。 ションの追加と削除」を実行し「 Windows コ ( 2 ) コントロールバネルの「アプリケー 選択します。 「設定 ( s ) 」→「コントロールバネル ( c ) 」を ( 1 ) Windows のスタートメニューから , な Web サーバです。 Web プロジェクトを作成するために必要 rontPage は , コンピュータ上にローカルな FrontPage) をインストールします。 IIS と F と FrontPage 2000 Server Extensions ( 以下 , nternet lnformation Services ( 以下 , IIS) Visual Studio . NET の導入に先立って , I 0 IIS と FrontPage のインストール Fig. 4 Visual Studio . NET の動作環境 ・開発環境の OS ・ Windows 2000 ( 推奨 ) , Windows NT 4.0 ・実行環境の OS ・ Windows 2000 ( 推奨 ) , Windows NT 4.0 Windows ME , Windows 98 ・クライアントサイドで必要なマシン性能 ・ Pentium 90MHz 以上 ・ 32M バイトの日 AM ( 96M バイト以上を推奨 ) ・サーバサイドで必要なマシン性能 ・ Pentium 133MHz 以上 ・ 128M バイトの日 AM ( 256M バイト以上を推 奨 ) ・その他 ・ lnternet ExpIorer 5.01 以上 , および MDAC (Microsoft Data Access Components) 2.6 以上が必要 ないくつかのコンポーネントをインストー ルします。インストールされるコンポーネ ントは , 以下のとおりです。途中で数回マ シンを再起動する必要があります。 ・ Windows lnstaller ・ FrontPage 2000 Web Extensions Client ・セットアップランタイムファイル ・ lnternet ExpIorer 6.0 ・ Data Access Components NET Framework ( 2 ) 次に , VisuaI Studio . NET 本体のイン ストールを行います ( Fig. 6 の 2 番目の項目 ) 。 オプションページでは , インストールする 項目を選択できます。たとえば言語ツール なら , ・ Visual Basic NET ・ Visual C + + NET ・ Visual C# . NET のおのおのに関してインストールの有無を 指定できます。デフォルトの設定で必要な ードディスクの空き容量は約 1.3G バイト です。かなり膨大なファイルをインストー ルするので , インストールに数十分 ~ 1 時 間程度かかる可能性もあります。 (3) 最後に Service Release のチェックを 行います ( Fig. 6 の 3 番目の項目 ) 。インター ネットもしくは Service pack ディスクを使 って , システムを最新の状態にアップデー トします。すでに最新の状態ならば何も作 業は行われません。 これでインストールは完了です。とくに 難しいところはないのですが , IG バイト あまりの空きディスク容量を確保するのは VisuaI studio . NET 滝 2 日本語版最初の一歩 97

6. 月刊 C MAGAZINE 2001年10月号

アプリケーション 0 作ろう フリー開発環境で のような情報が出力されます。 PPLlmve ppumove は複数のユニットから , 共有お よび静的ライプラリを作るプログラムです。 Turbo Pascal に添付されている tpumove と 同様のもので , バイナリで配布されていま す。もちろんソースもあります。 利用方法は次のようにし , ここで指定で きるオプションは Table 4 のものがあります。 ppumove [ OPt 土 0n8 ] unitl. ppu unit2 ・ ppu ・ unitn. ppu ppumove は , 各ユニットファイルからコ ンパイラがライプラリ内でユニットコード を探せるように変更します。新しいユニッ トファイルは拡張子 . ppu を持ち , これは - e オプションで変更可能です。その後オプジ ェクトファイルをすべて 1 つのライプラリに まとめます。そのライプラリを静的にする か動的にするかは - s オプションで指定しま す。ライプラリの名称は - o オプションで指 定しなければなりません。もし必要なら , Lin 皿では接頭語として lib が付けられます。 拡張機能として , Linux では , スタティッ クライプラリには . a を , 共有ライプラリに は . so を , また Wmdows NT と OS / 2 では . d Ⅱ を作ります。 たとえば , 次のようなコマンドを使うと , Linux では Fig. 3 のように出力します。 . /ppumove ー 0 bOth -e ppl ppu ・ ppu セ土 me て . ppu このコマンドは Table 5 のようなファイル を生成します。これで libboth. so , timer. ppl , ppu. ppl を利用したり配布したりできるよう になります。 fpcmake GNU のソフトなどをダウンロードすると , 特集 2 pc を読み込んで , GNU make 用の Mak ② fpcmake を起動。 fpcmake は Makefile. f ァイルに一定のルールなどを記述する ① Makef ⅱ e. fpc というプレーンテキストフ 次のようになります。 ティです。 fpcmake と GNU make の連携は をサポートする FPC 用のメイクユーティリ リティは , このような GNU make コマンド てインストールします。 fpcmake ユーティ といったコマンドでソースをコンパイルし $ make a Ⅱ $ make insta Ⅱ $ make ば , 通常は , ばなりません。ソースをダウンロードすれ ローカルなホストにインストールしなけれ ・ GNLJ make について 述することになります。 MakefiIe を作る代わりに MakefiIe.fpc を記 ルを行う ③ GNUmake でコンパイルやインストー efile を作成する MakefiIe には , 基本的に次のような要素 ずしも実行ファイルとは限りません。 いいます ) を生成します。ターゲットは必 の実行ファイル ( 一般的にはターゲットと されている内容に従ってアプリケーション ディレクトリ内で探して , Makefile に記述 make は Makefile というファイルをカレント みと記述法を確認しておきましよう。 GNU GNU make で使う MakefiIe の簡単な仕組 を一定の方式で記述します。 ・依存関係 : 生成するファイルがどのよ うなソースファイルに依存しているか ・ルール : ターゲット作成方法のルール , 手順 ・マクロ : コンパイラ自体 , コンパイラ のオプションや環境を定義しておく ょにすればいいわけです。 各オプジェクトを作成して , それをいっし コマンドラインでコンパイルするには , いる ・ testB. c は other. h の定数配列を利用して ・ testA. c は TestB. c の関数を利用する いる。つまり依存関係がある ・ testmake は TestA. c の関数を利用して ・ターゲットを testmake とする 次のプログラムで考えてみましよう。 $ gcc -Wa Ⅱ $ gcc -Wa Ⅱ $ gcc -Wa Ⅱ $ gcc -Wa Ⅱ -c TestA. c —c TestB. c —c testmake. c ー 0 testmake testmake. 0 TestA. 0 TestB .0 MakefiIe は単に上記のような順次的なバ ッチ処理をするだけではありません。依存 関係を調べ , コンパイルが必要かどうか つまりソースファイルの日付とオプジェク トの日付を比較して変更部分だけをコンパ イルします。 List 11 は testmake を生成する Makefile です。 target は , maketest. 0 , Test Ao, TestB. 0 という 3 つのオプジェクトファ イルから生成されることを表しています。 この生成のルールが次の行「 gcc... 」の部分で す。ルールはタブで始まる行で記述されて いる必要があります。スペースではルール として認識されません。以下同様に , make List target : testmake を生成する Makefile maketest. 0 TestA. 0 TestB. 0 q00 —Wall -0 maketest maketest. 0 TestA. 0 TestB. 0 lSt insta Ⅱ : maketest. 0 : maketest. C で estA. 0 : TestB. 0: clæn: g00 ー 0 maketest. c TestA. 0 gcc -0 TegtA. 0 Tes に B. 0 other. h g00 —c TestB. 0 rm maketest ketes セ .0 TestA. 0 で e 日 tB. 0 make install target @if [ -d / てハ 00 引 / bin then \ 叩 maketest / us て月引 / b 土 n ハ 0 755 / Ⅱ 8 て月 oc 引 /bin/maketest ハ echo "lnstalled 加 / て月引 / b 加”ハ 8h0 ”て 0 て , / て月引 / b does れ ot is ビハ else 、 fi 特集 2 フリー開発環境でアプリケーションを作ろう 85

7. 月刊 C MAGAZINE 2001年10月号

アプリケーション 0 作ろう フリー開発環境で 特集 2 その基本中の基本だけを提示してみます。 ます。機能は TabIe 2 のようになります。 of const は Delphi の Format 関数のパラメー c 血 nc. c 田 st8 ) のような関数を用意しま objpas ユニットを利用できないモードでは タになっているものです。 OOP は使えず , OOP でコードを記述するな す。次のようにすると , cfunc. 0 というオプ $ L , $ LINK と $ LINKL 旧コンバイラ指令について ジェクトファイルが gcc で生成されます。 ら DELPH モードか OBJFPC モードにしま す。 DELPHI モードと OBJFPC モードでは , リンクについて一般的な説明を加えてお $ gcc -c cfunc. c ojbpas ユニットは system ユニットの後にロ きます。 $L, $LINK は , オプジェクトフ FPC では List 9 のようにし , List 8 の testcf ードされます。これから派生することの 1 unc 関数と C の標準関数 s 国 en をリンクしま ァイルをリンクします。利用方法は { $ LfiIe つに , lnteger が LongInt として再定義され した。標準関数をリンクするには , {$linkl name) または {$LINK filename} です。ライ ibc } を指定し , testc 血 nc をリンクするには プラリをリンクするのではありません。ラ るといったことがあります。 FPC モードと オプジェクトファイル名を {$L name} で指 イプラリのリンクには $LINKLIB を使いま OBJFPC モードでは , PChar は自動的に 定します。 C 言語の関数は cdecl 呼び出し規 す。コンパイラは以下の手順で該当のオプ strings に変換されます。 TabIe 2 の手続き型変数は List 6 のような 約に従うので , 関数の宣言の後にそれを指 ジェクトファイルを探します。 ①オブジェクトファイル名で指定された 言を指します。 DELPHI モードでは , ク 定し , さらに外部関数なので external を追 ラスメソッドを手続き型変数として利用す 加します。後はコンパイルするだけです。 パス る場合に object という修飾が必要です。 ②ソースファイルがあるカレントティレ $ PPC386 callc 代入は通常 DELPHI モードでは List 7 のよ testcfunc は標準出力に「 this is a test c fun クトリ ③オブジェクトファイルの検索パスで指 c ⅱ on 」という文字列を出力します。標準関 うに行いますが , これにアドレス演算子 「@」を使えるかどうかという区別が「手続 数 s ⅵ en はパラメータで与えた文字列の長 定されたすべてのティレクトリ き型変数への割り当て」になります。 さを返します。実行結果は , オプジェクトファイルの検索パスを - Fo オ プションで追加できます。 Linux システムで this is a test c function C の関数を使う は , 名称は大文字と小文字を区別するの 20 という単純なものですが , きちんと C の関 で , システムで使われている正確な名称を FPC は , Pascal と C 言語の両方の資源が 使う必要があります。わざわざこれを書く 活用でき , さらに巨大な GNU の資産も利用 数を呼び出しています。 のは PascaI が伝統的に大文字小文字を区別 C の printf のような関数は , パラメータに できます。 C 言語のオプジェクトファイル しないからです (Lisp も区別しません ) 。な 任意の数の変数を指定できます。 ObjectPa やライプラリなどの利用時にいろいろな困 sc のオープン配列に相当するものですが , お , リンクしようとしているオプジェクト 難にも遭遇するかもしれません。 こういった関数をリンクするには , {$MO ファイルはリンカで認識できるフォーマッ C の関数 トでなければなりません。これはプラット DE DELPHI} か {$MODE OBJFPC) を指定 します。なお , オープン配列が DeIphi で利 ホームに依存します。 用できるようになったのは , それほど昔の $LINKLIB は , ライプラリをリンクしま す。 {$LINKLIBname} でライプラリ名称を ことではありません。 List 10 のように れも cdecl と external を付けて関数宣言し , 与えます。これはリンカに - lname で渡すの あとは「 a 仼 ayofconst 」の利用方法に従って と同じ働きをします。 {$LINKLIBname} を 任意の変数を文字列に埋め込みます。 array 使えば , オープン配列 こでは , 8 * cfunc. c - test C function #include く std 土 0. h> void testcfunc ( ) printf("this 土 8 a test 0 f リ nc セ土 on 第 n 新 List ・ st C の関数を使う 9 * call c ・ pp - C の関数をインポートする。 program ca Ⅱ { 引土は b c) {$L cfunc. 0 } { DecIaration fo て the C function ) punction strlen(): : longint; cdecl; external; procedure testcfunc; cdec 嵭 external; * caIIc2. pp - C の printf を使う。 program callc2; {$mode ー幻 const P: PChar = example'; F: PChar = 'This 宅 8 Ⅱ 8e8 printf セ 0 print れ一て 8 (d) and gt て土 ngs. ' # 1 procedure printf(fm: PChar; args: array 0f 00n8t cdecl; ex セ e てれ引 begin p て土 n ( p , [ 123 ] testcfunc ー 翫址 eLn ( 8 ー ( 'programming 地 sy 卩 ) 83 特集 2 フリー開発環境でアプリケーションを作ろう

8. 月刊 C MAGAZINE 2001年10月号

アプリケーション 0 作ろう フリー開発環境で 特集 2 テータスパイトの下位 4 ビットの値に 1 を加 ら得てタイミングを図る方法が考えられま ( 3 ) は , 先ほど書きました SIeep ( ) です。 えることになるので 1 から 16 までの表記に す。いろいろ試してみてください。 れで , 音を鳴らす間の時間を作っています。 ( 4 ) では , 「 00583C90 」の「 58 」が「 00 」になっ なるのです。しかし , プログラムをする際 ショートメッセージの再生 ています。これは「音を鳴らす強さは 0 」とい には , 0 ~ 15 で表記するのでチャンネル 1 の 次にショートメッセージの出し方を説明 う内容になります。つまり , 「音を止める 音を鳴らす場合には , 「 0 」を書きます。先 ( ノートオフ ) 」ための命令になります。⑤ ほどのべロシティ , 音階に続けて書くと ' ℃ したいと思います。 1 音だけ出したいとき X00603C90 " となります。この音を鳴らした に使います。このショートメッセージのプ の文で開いた MIDI デバイスを閉じていま す。演奏を終わりにしたいところで必ず書 ログラミングは , あまり利用されることは いときは , midiOutShortMsg(hMidi , 0X00603C90 潺 ないかもしれませんが , MIDI の基本の仕組 きます。 こで鳴らす音の強さ ( べロシティ ) と音 となります。 みを理解するためにとても役に立ちます。 これらをまとめると List 6 になります。 Sle 次のように書きます。 階 , チャンネルについて話しておきましよ ep() は , 演奏を始める部分と終える部分の (1)midiOutOpen(&hMidi ,MIDI MAPPER,NU う。 Fig. 4 は音の強さを表しています。 10 進 間に加えて演奏を終える部分の後にも書き LL,NULL,CALLBACK—NULL); 数で 1 がいちばん弱く 127 に近くなるほど強 ( 2 土 diOutSho て sg ( 土 d 土 , 0X00583C90 くなります。この数値は , あくまで 10 進数 ましよう。 ( 3 ) 引 eep ( 504 なので 16 進数に変換してください。たとえ ショートメッセージを連続させる ば , 96 の f ( フォルテ ) で強めに音を鳴らした (4)midiOutShortMsg(hMidi , 0X00003C90 次に連続して鳴らす場合です。このプロ いときは , 16 進数の「 60 」を " 阪 00 " に続いて (5)midiOutC se ( 土 d 土 グラムには , とくに音符を表すものはあり ( 1 ) で MIDI デバイスを開きます。②で音 書きます。 ませんが , Sleep ( ) を使って時間をずらし , 音階も 10 進数で決まっているのでこれも を鳴らしています。 " 00583C90 " の部分が テンポや音符の感覚を作ります。たとえば , 16 進数に変換して書くことになります。 Fig. 音を鳴らすために必要なデータで , 16 進数 1 小節で四分音符 2 つ , 八分音符 4 つ ( ターン , 4 は , 中央の「ド」が C4 の場合です。中央の で書きます。「脈 00 」に続いて書かれている 「ド」が 10 進数で 60 と設定されています。半 ターン , タン , タン , タン , タンとなりま 「 58 」という数値は , 音を鳴らすときの強さ す ) という設定でプログラムを書いてみます 音ごとに 1 ずつ変化していきます。 B3 ( シ ) ( べロシティ ) を表しています。次に書かれ ( 付録 CD-ROM に収録 ) 。どうですか ? 「ド なら 59 ですね。 ている「 3C 」という数値は , 音階を表してい ミ」とピアノの音が 中央の「ド」の場合は , 10 進数を 16 進数 ます。低い「ド」と高い「ド」では , 書く数値 このプログラムの場合 に変換すると阪 3C となっています。先ほど 鳴ったと思います。 も違ってきます。この場合は , 中央の「ド」 のべロシティに続けて書くと " 阪 00603C " と Sleep ( 504 ) が四分音符の代わりになってい になります。最後の「 90 」という数値は , 左 ます。また , 自動的に Sleep ( 504 ) の時間が の「 9 」が音を鳴らせという意味です ( ノート 表記できます。 テンボになります。テンポを速くしたけれ 最後の 2 桁の数値のうち「 9 」は , ノートオ オンという ) 。右の「 0 」がチャンネル「 1 」であ ば , Sleep ( ) の数値を全体的に小さくすれば ることを示しています。このコードは , 「 ンを表すステータスです。右側の数値は , いいわけです。八分音符は , 四分音符の半 58 の強さで 3C つまり " 中央のド " をチャン チャンネルを表します。 MIDI チャンネル 分の長さですから , この場合では SIeep ( 252 ) ネル " 1 " で鳴らしなさい」と命令しているこ は , 1 から 16 までです。しかし , 4 ビットの になります。そのほか 16 分音符は , 四分音 2 進数値は 0 から 15 となります。よって , ス とになります。 符の 4 分の 1 , 32 分音符は , 四分音符の 8 分 Fig. 4 べロシティと音階の指定値 の 1 ですから , それに合わせて時間を変化 させてください。 〇べロシティ なお , SIeep ( ) は環境によって必ずしも正 1 0 進数 1 6 確な時間 , 停止するというものではありま PPP せん。正確な時間計測には W1n32API の get p →弱く , f →強く 第 ckCount ( ) などを使ってください。 16 進数に変換するのに便利な計算機を使 うのもいいでしよう。スタートメニューよ り [ プログラム ] → [ アクセサリ ] → [ 電卓 ] で [ 電卓の種類 ] → [ 関数電卓 ] を選択すると 10 進数と 16 進数が一目瞭然です。 特集 2 フリー開発環境でアプリケーションを作ろう 57 ミ、 127 1 1 2 80 64 48 mp mf P 96 32 PP 〇音階 1 0 進数 21 音名 AO 108 C8 高い 9 0 8 0 6 0 ・中 2 5 . 8 3 ド 3 0 24 フ・・ 低い

9. 月刊 C MAGAZINE 2001年10月号

ials> ディレクトリに収録されています ) 。計 以上の計算精度を得るには自力で精度を向 りよくないことになります。たとえば 1.0 の 測のため巨大なループを回るので , 実行 逆数 , つまり 1.0 / 1.0 を計算すると結果は 1.0 上させなければいけないことになります。 ( 測定 ) が完了するまでしばらく時間がかか となるはずですが , 実際には 1.0 になってく より精度の高い近似値を得る方法として れません ( 近い数値だが ) 。たいして計算精 る場合があります。 もっとも有名なニュートン・ラフソン法を 度を必要としないケースでは誤差というこ 使って , 計算精度を向上させることにしま 精度の問題 とで許容できますが , もっと高い精度を求 す。しかし , ニュートン・ラフソン法なん められるケースはよくあることです。 て , たいそうな名前を聞くと何だか難しそ SSE 命令には rcpps/rcpss という逆数を求 AMD の K 伝 2 や Athlon に搭載されている 3 うな感じがするし , そんなのを自前で用意 めるための命令があります ( rcpps はパック DNow ! テクノロジでは p 仕 cp という命令で逆 するなんてイヤだなあ・・ などと思って ド形式 , rcpss はスカラ形式の命令 ) 。実行 数の近似計算を行うことができますが , や しまいそうですが , 実はとっても簡単な計 されたときに比較的時間のかかる除算命令 はりこの p 斤 cp 命令も単体ではあまり精度は 算で済みます。 List45 をご覧ください。 を使わないで , 除算したときに求められる よくありません。ただ , これを補うために この計算で逆数の精度を向上させること 数値に近い値 , いわゆる近似値を高速に得 3DNow! テクノロジには pfrcpitl , pfrcpit2 と ができます。コードの ss 部分を ps にすると ることができるので , とても便利でよく利 いう逆数の計算精度を向上させる特別な命 4 つ同時にパックド演算することもできま 用される命令の 1 つだと思います。しかし , 令が用意されています。このような精度を す。ニュートン・ラフソン法を用いると単 この rCPPS/rCPSS 命令には弱点があります。 向上させる命令が SSE 命令にも用意されて 純に rCPPS/rCPSS 命令を実行した場合と比べ その弱点とは計算誤差が 1.5X212 となかなか いれば話は早いのですが , あいにく SSE に て倍近くの精度を得ることができます。蛇 大きいことです。要するに計算精度があま そのような命令はありません。つまりこれ 足ですが , この逆数の近似値を利用すれば , Fig. 13 期待する結果 Fig. 14 高速化されていることが確認できる z [ 0 ] = y [ 0 Ⅱ 0 ] * x [ 0 ] 十 y [ 0 ] [ 1 ] * x [ 1 ] 十 y [ 0 Ⅱ 2 ] * x [ 2 ] 十 y [ 0 Ⅱ 3 ] * x [ 3 ] 2 [ 1 ] =y [ 1 ] [ の * x [ 0 ] + y [ 1 ] [ 1 ] * x [ 1 ] + y[ 1 Ⅱ 2 ] * x [ 2 ] + y [ 1 ] [ 3 ] * x [ 3 ] z [ 2 ] = y [ 2 ] [ 0 ] * x [ 0 ] 十 y [ 2 ] [ 1 ] * x [ 1 ] 十 y [ 2 ] [ 2 ] * x [ 2 ] 十 y [ 2 ] [ 3 ] * x [ 3 ] Result 朝 ma セⅸ c らに u t Q-Q-a. C• version FPU versm SE v s 1 List 4 St 7 SSE の命令で逆数平方根の近似値を求める void pagtNormalizevector( VæTQ4 *pv, float x ) 00 れ日 t static ALIGNED 日 oa に一 0 ー 5 [ 41 = ( 0.5f , 0.5f , 0.5f , 0.5f 00n8t 日に a セ土 0 ALIGNED float -1-5 [ 4 ] = { 1.5f , 1.5f , 1.5f , 1.5f mov d 響 0 て d ptr[pvl mo 、 8 ー 0 movaps = 2 ー 0 て d ptr[eax] て日 q て tp 日一 1 , ー 0 ;anrox mulps = 0 , 1 0 , ー 1 ー 0 , ー響 0 て d P [ ー 0 ー 5 ] mulps mulpg 1 , 響 0 て d p [ ー 1 ー 5 ] ー 1 , ー 0 引 subps ゆ日 1 , 2 mov 叩日 ー響 0 て d ptr[eaxl, ー 1 ニュートン・ラフソン法を用いて逆数平方根の精度を上げる / / ニュートン・ラフソン法による逆数平方根の精度向上 逆数平方根から精度の高い平方根を求める 〃反逆数を用いて平方根を求める て gq て t 日日一 1 , ー 0 ;approx -2 / 05 を ck mulgs 冖 0 , ー 1 一日 ta 【に mulss 0 , 1 重 u 一日 8 冖 0 , ー 1 0 , 0 て d pt て [ ー 0 ー 5 ] ー 1 , 。て d pt て [ ー 1 ー引 u 地日 sub 日日 = 1 , 0 ;final 4 Fig. 15 SSE バージョンのほうが高速化されている Result of norm 引に e vector catculatnn SE). 0. 〕 207. -1 . 愈 414. -0. 0 7.0 価 2000 : OPU time = 111253 0.9 207. -1.8 414. -0.9 圓 7.0 旧 0 : OPU time = 197 @22x) verSlOn SSE version イ 0 C MAGAZINE 2 側 1 10

10. 月刊 C MAGAZINE 2001年10月号

特集 1 加殤ムの高速化・最適化 分岐から再度読み込む必要が出てくること ある条件のもとでは List 10 に示したように になってしまいます。この動作は命令を実 条件分岐をまったくなくすこともできます。 行する際 , 非常に大きなへナルティとなり また , List 11 の例では AND の論理演算を利 用して条件分岐をなくしています。ここで ます。 行っている , 変数 i を 1 増やして 16 ( 2 の X 乗 ) したがって最近のプロセッサを実行のタ 以上になったときに 0 に戻るような計算の ーゲットとする場合は , なるべく条件分岐 場合には , 1111b ( 16-1 ) でビットマスクして をさせない工夫を凝らします。 やれば値は 16 ( 10000b ) を超えることはあり List 9 のような場合 , 最小の数値が 0 にな るような数を足し , 符号なしの型にキャス ません。 理由 : 条件分岐をなるべく減らすため トすると , 2 回必要だった条件分岐が 1 回で 使用される場所 : マスク処理などの計算 済みます。整数を比較するときに使うこう によって条件を満たすことができる分岐 いったケースのキャストにペナルティはな いので , うまく利用すればプログラムの高 処理 速化に直接つながります [ 1 い 2 ] 。 バック演算 理由 : 条件分岐をなるべく減らすため 通常であれば 1 バイトずつ処理するとこ 使用される場所 : 条件の範囲がある程度 ろを , 複数バイト同時に処理することでパ 特定されている分岐 フォーマンスを向上させることができます 0 条件分岐をなくす List 12 では long ( 32 ビット ) 型を使って 4 ノヾ イト同時に計算しています。ただしループ 先ほどの応用といえなくもありませんが の数を 4 で割り切ることができる場合にの 命令の優先順位 ( データのシフト ) み使用できるという条件が付きます。ルー プ数が 4 で割り切れない場合は , なるべく 4 バイトずつまとめて処理した後 , 余りを 2 バイトまたは 1 バイト単位で処理すればよ いでしよう。この手の最適化は配列の数が 大きければ大きいほど効果があがります。 理由 : 複数の要素を同時に計算して高速 化させるため 使用される場所 : 比較的少ないビット数 で同じ計算が繰り返されるようなところ。 ただし計算結果がオーパフローまたはア ンダーフローするような場合は使用でき ない lSt 条件分岐をなくす① 2 ス ス ケ oB て anchl ( ) return (x = 100 ) ? true : falge; 引 0h1 ( ) return ! ( (l) (x - 100 リ List 条件分岐をなくす② 2 ス ス ケ ケ unsigned int 製 OB て anch2 ( ー日土 61 ・ d int 土 ) 土十 if ( 土》 = 16 ) 土 = の ェてれ新 新 gned 加に 8 て 50h2 ( int 土 ) て e 加工 n & ( 16 - 1St バック演算 1 ・ケース 1 void char ね [ 256 ] ) ・ケース 2 void packed( char ta [ 256 ] ) ng *lp = い 0n9 * ) data; fo で ( int 土 = 土く 256 / of い ong 土十十 ) ゆ [ 幻 & = 0X7f7f7f7 新 List 7 ・ケース 1 int de て Of io て土 ty ( int n ) return n * 32 ・ケース 2 int de て Of 土 or 址 y ( int n ) return ((n« 8 ) 十 ( れ 6 ) fo て ( int 土 = 土く 25 研土十十 ) data[il & = 0X7 新 List 不変式のループ外移動① 条件分岐の順序 8 ・ケース 1 void Out deO れ 00P ( に社第 int a, セ b ) fo て ( int = 土く 1000 土十十 ) て [ 幻 = a 十 ・ケース 2 void Outs 土 deO れ 00P ( int 社 , int int b ) int t = a 十 b; fO て ( れヒ土 = 土く 1000 土十十 ) ・ケース 1 void Branch( int seldom, int frequently ) ・ケース 2 void Branch( int se 0 叫 int ) 迂 ( frequently & & 日引 dom ) 不変式のループ外移動 何度も繰り返される List13 のようなルー プ内のコードには , ループ中に値が変化し 変数はレジスタに格納されます。一般的に ないこともよくあります。こういった式の レジスタへのアクセススピードはメモリへ ことを「不変式」といいます。このような不 のアクセススピードよりも高速なので , か 変式はループの実行前に 1 度だけ計算され なり効果があります [ 1 い 3 ] 。また List 14 のよ るようにしておくことで高速化することが うなケースもループ外に移動することがで できます。この例では t という一時変数を使 っていますが , ほとんどの場合こういった きます。 て [ 幻 = IS 9 条件分岐を減らす ・ケ - ス 1 void 土 n ヒ x if ( x く = 2 & & x -1 ・ケース 2 void Decreageranch( int x if ( ( int) (x 十 1 ) ← ( 2 + 1 ) 特集 1 プログラムの高速化・最適化 23