場合 - みる会図書館


検索対象: 月刊 C MAGAZINE 2000年4月号
127件見つかりました。

1. 月刊 C MAGAZINE 2000年4月号

五ロ = 一言編 特集 1 プログラミン % 禁じ手 凵 st 構造体で引数をまとめて見やすくする typedef struct イ 土北はけ , char * 嵭 char *m ー d0 曲町 , ) g—struc; いことが原因で , これも不勉強のせいだと かのスレッドや割り込みと共有可能な変数 いえます。 も同じように最適化をすると , うまくいか [ 対策 / 予防 ] なくなる場合があります。 割り込みやスレッドについて , たとえば , List14 のプログラムでは gvar よく勉強 することです。 という変数が割り込み ( interrupt ) のなかで [ 例外 ] 1 に変化することを利用し , 割り込みが実 なし。 行されたことを f() で検出しようとしていま [ 備考 ] す。ところが最適化によって , whiIe(gVar 「スレッド」や「割り込み」は , 昔は組み込 = 0 ) が見かけ上 , List 15 のようなプログラ みプログラムやデバイスドライバなどのデ ムになってしまった場合 , 恐ろしいことに ノヾイス周りの人だけ注意すればよかったの gVar の変化が検出できなくなります。 ですが , 最近はそうでもなくなっています。 なぜ , こういう最適化が起きるのでしょ スレッドというのはプログラムを並行に動 うか ? 一般的には , よく使う変数をレジ 作させる仕掛けです。割り込みは文字どお スタに割り付けておくとプログラムの動作 り , 通常のプログラムを実行している途中 が高速になります。そこで , コンパイラが で , 一時的に違う作業を要求する仕組みで 「気をきかせて」 gVar ではなくレジスタに す。たとえばキーポードを押したときに 時的に割り当ててしまう場合があるのです。 押されたキーの情報をどこかに保存する「キ この最適化は必ずしも起きるわけではなく , ーポード割り込み」は普通のパソコンでは プログラムをいじっている間に突然起きた [ 例外 ] 当たり前のように行われています。 り , 消滅することもあり , やっかいです。 試作段階や試行錯誤している場合は許さ スレッドや割り込みがやっかいなのはひ 出荷モードで不具合が出て , デバッグモー れるかもしれません。しかし , 本番では読 とつのプログラムの流れを考慮して高速化 ドでは現れないという不可解な症状の原因 みやすくまとめましよう。 を行うコンパイラが , 変数をレジスタに割 にもなります。 [ 備考 ] り付けしてしまうことです。このとき , ほ c 言語では , こういう最適化による弊害 List 12 のような感じのプログラムは , た を消すため「 vola ⅱ le 」というキーワードが用 割り込みと共有する変数 まに見ます。ギャグとしてわざと読みにく 意されています。 vola ⅱ le の付いた変数は最 くしているのかと思いきや , 多くの場合本 適化による不都合が起きないようコンパイ 人は真剣です。普通ならこれだけ引数があ ラが配慮をします。 れば構造体にまとめるはずですが , 案外 , その方法を知らないというケースがありま ポインタと配列を混同している す。それどころか「構造体恐怖症」みたいな 深刻度☆☆ ( 中程度 ) 人もいます。 List 12 のプログラムは構造体 を使って , List13 のように整えれば少しは [ 症状 ] 見やすくなります。 割り込みやスレッドで共用する 変数を v at ⅱ e にしない 深刻度☆☆☆ ( 重度 ) [ 症状 ] 不可解なバグに悩まされることになりま す。また , コードをいじるたびに症状が変 わる場合もあります。 割り込みやスレッド特有の制約を知らな void g(g—struc *ins)' マ 0 坦 f()- g—struct theG; theG.i キ theG. 」言 2 ~ theG. k = 45 研 theG.l キ "abc@• ・。 theG.m 物 de す theG. れ 789 を theG. p 10 畆 theG. q ま 1 theG. = 1 theG. s キ 1 theg. し第 14 ー theG. せ = 1 theG. v = 16 ー theG. w ま 17 、 0 ー 9 ( 阯 heG List 土れ t gVar = の void 土北 er て叩 t ( ) gVar = 1 ・ Ⅳ 0 坦 f() while(gvar== 0 ) ( うまくいく環境もあれば落ちる環境もあ るので , 悩まされます。また , うまくいっ ている場合でもプログラムの移植性は低く なります。 [ 原因 ] 不勉強が原因です。 [ 対策 / 予防 ] ポインタと配列の違いをしつかり勉強し て , きちんと使い分けることです。 LiSt 最適化で意図しない変化をする void f( ) register theReg; theReg = gVar; whiIe(theReg = = 0 ) ( gVar theReg; [ 原因 ] [ 例外 ] なし。 プログラミングの禁じ手 31 特集 1

2. 月刊 C MAGAZINE 2000年4月号

型の定義機能 (Java でいえば class) が備わっ 面をアクセスすることでダウンロードされ 種の条件 ( 強く型付けされ , 呼 pes e である ているのと同じであり , オプジェクト指向 るアプレットは , その実例である。 Web プ こと , アクセス制限の施さされたフィール ラウザ内では , ある種の Java アプリケーシ は汎用のプログラミング言語には必須の機 ドにはクラス外部からアクセスできないこ となど ) がバイトコードレベルでも成立し 能であるという認識が確立したためである。 ョンが動作していて , そのプログラムが しかも , オプジェクト指向がとくに有効と Web'X ージに指定された場所 ( おそらくは ているかどうかをテストするためのもので インターネットの向こうのサーバ上 ) から , されるのは GUI アプリケーションであり , Ja あり , これによって不正なプログラムコー va の主要なターゲットがここにあるのだか アプレットを実装しているクラスをダウン ドを実行してしまうことを防いでいる。 ら , オプジェクト指向を採用するのは当然 ロードし , 自プログラムのなかにロードす またサンドボックスモデルは , 日本語で ることで実行しているのである。こうした はむしろ砂場というよりは庭モデルと呼 のことである。 一方 , 動的言語 (Dynamic language) であ 機能がプログラムの柔軟性と拡張性に与え ぶほうがいいかもしれない。このモデルに るという特徴は , オプジェクト指向機能ほ る影響の大きさには想像を絶するものがあ おいては , ロードされたアプレットは , そ どはその必要性が明確ではないかもしれな れをロードした側のプログラムが提供する , る。 い。オプジェクト指向におけるプログラム 籀庭のような限定された空間のなかだけで セキュリティ の構成単位はクラスであり , 1 本のアプリ 動作し , その外側の世界一一口一カルマシ ケーションプログラムのなかには複数のク ンのファイルシステムやデノヾイスなどの資 分散型言語として , インターネット上の ラスが利用されるのが常である。 Java では , 源一一にアクセスすることはできない。そ そうしたクラスはプログラムの実行時にロ 任意の場所からクラスをロードして実行で れらを越えたアクセスが試みられた場合に ードされる。このことは , プログラムの実 きるという機能は , 一方では Java に無限の は , セキュリティマネージャが介入して阻 行途中に , そのプログラム自身の機能を自 拡張性を与えるものの , 他方では内容がよ 止する構造になっていたにの点は実行環 由に追加したり変更したりすることが可能 くわからないコードをネットワーク経由で 境側の機能と考えるべきであろう ) 。しか であることを意味している。さらに 入手し , それを実行することによって自分 しこの制限は , セキュリティの確保という リフ レクション ( Reflec ⅱ on ) という機能を併用す のコンピュータをセキュリティ上の危機に 観点からは非常にすぐれたものであったが , ることで , 実行中のプログラムが自分自身 さらしてしまうことを意味している。意識 逆にアプリケーションの自由度からすると について調査をし , 必要があれば機能を拡 しているかどうかは別として , アプレット 強すぎるものであった。このため , JDKI. 1, を含む Web ページをアクセスした場合には 張するといったことすら可能になる。 JDKI. 2 と段階的にセキュリティ関連の機 分散型言語 (Distributed language) という ( たいていは ) 見ず知らずの人間が作ったコ 能が拡張され , サンドボックスモデル以外 言葉は , Java においては「ネットワーク機能 ードを実行することになるのである。いわ に , 安全性を保ちつつ , 特定のコードには を標準でよくサポートしている」という意 ゆるコンピュータウイルスといったものも 必要なアクセスが許可できるような仕組み 味である。 java. net というパッケージを利用 実際には同じようにして広がるものである が実装されて現在に至っている。 したがて , ダウン 0 ードしてきた 0 ー FO することで , ローカルマシン上のファイル マルチスレッド が , 自分の ( あるいは自分の回りの ) コンピ を読むのと大差ない労力で , インターネッ ト上の任意のマシンからファイルを読み出 ュータに悪影響を与えないということが保 証されていなければ , どんなに動的で分散 すことができる ( もちろん , そのファイルへ Java ではマルチスレッドサポートを言語 のアクセス権限は必要である ) 。また , java. 型の言語に魅力があったとしても , 誰も使 レベルで行っている点も見逃せない特徴で rmi ( Remote Meth0d lnvocation) という名 ある。 GUI アプリケーションなどでば , と おうとはしなくなるだろう。 のパッケージを利用することで , リモート Java では当初からこの点にも重点を置き , くにユーザとのやりとり ( メニューを出す マシン上に存在するオプジェクトのメソッ とか , マウスの動きを追うとか ) とは独立 言語仕様に十分なセキュリティ対策が施し ドを , ローカルマシン上に存在するかのよ して別の処理・・・・・・たとえば時間がかかるス てあった。セキュリティを守るために JDK うに起動できるようになる。分散型でかっ 1.0 が提唱したのはコードベリファイア (co プレッドシートの更新処理とか , あるいは 動的であるということは , Java のクラスは , マウスが近づいた GUI コンポーネントの表 deverifier, コードの正当性の検証プログ インターネット上の任意の場所からダウン ラム ) と sandbox( 砂場 ) と呼ばれるモデルで 示を変えるとか , それに関連するヘルプを ロードして , 実行中のプログラムにロード 表示するとかといった作業をしたい場合が ある。コードベリファイアは , Java のソー できること意味している。現実に Web 画 スコードレベルでは保証されているべき各 ある。こうした場合にはマルチスレッド処 54 C MAGAZINE 20 4

3. 月刊 C MAGAZINE 2000年4月号

= 編 特集 1 プログラミン % 禁じ手 で安全なプログラムを作るためのものでは が不安定になる可能性があります。この場 グローバル変数が多い ありません。そこを勘違いして誤った期待 合 , a は不定値なので必ず「 case 0 」を通過す ( 外部変数が多い ) をすると , 見事に裏切ってくれます。 ると思っていると大間違いです。仮に 深刻度☆☆☆ ( 重度 ) のようなコードを含むプログラムを実行し て , 「 case0 」を通過したとしても , それは a [ 症状 ] 自動変数の不定値を使う の値が偶然 , a % 3 = 0 になるような値であっ プログラムの解読や改造が困難になり , 深刻度☆☆☆ ( 重度 ) ただけにすぎません。 バグが発生しても退治しにくくなります。 [ 症状 ] このプログラムは , わざとらしい例で , [ 原因 ] わけのわからないバグに悩まされること 実際にこういうドジをする人がいるとは思 グローバル変数の有害さを認識していな になります。また , たまたま期待どおりに えません。ところが , 関数の行数が多い場 い , すなわち不勉強が原因です。 動作している場合でも移植性や安定性に欠 合 , 変数の定義をした場所と実際にその変 [ 対策 / 予防 ] けるプログラムであることに変わりありま 数を利用する場所が離れていると , 変数が もちろん極力 , グローバル変数を使わな 不定値のまま評価されるような間違ったコ せん。 いことです。といっても , 「それならどうす [ 原因 ] ードを書く可能性はあります。 ればいいんだ」という話になってくるのが , ケアレスミスや C 言語の自動変数の仕様 あるいは最初は不定値になっていなかっ このグローバル変数問題のやっかいなとこ を理解していなかったなどの原因が考えら たプログラムを , 仕様変更などの修正でい ろでもありますが れます。 じっていくうちに不定値になっていたとい [ 例外 ] [ 対策 / 予防 ] うパターンもあります。 なし。 まず , コンパイラの出す warni に注意 コンパイラによっては「変数 a の値がきち [ 備考 ] して , デバッガで丹念に追いかけることで んと設定されていないのに評価された」と 変数に関して深刻であることを指摘して す。根本的に解決するためには C 言語の自 いう意味の警告 ( warning ) を出すものがあ おきたいのがグローバル変数 [ 注 1 ] です。グロ 動変数の仕様を理解することが必要です。 ります。この warn ⅲ g が出た場合は , きち ーバル変数は , どこで読まれて , どこで書 [ 例外 ] んと対応しないと動作は保証されません。 き換えられて , ・・・と実際に使用されてい また , できるかぎり , この警告を出す設定 る場所を探すのがローカル変数 [ 注 2 ] に比べ なし。 [ 備考 ] をするべきです。 ると広いため , グローバル変数にかかわる List8 のようなプログラムは , 自動変数の 人によっては , 以上のような不定値パタ バグの被害も深刻になります。しかし , 昔 不定値のためにプログラムそのものの動作 ーンを避けるためにていねいに自動変数に から「 goto 文の弊害」をいうプログラマがい 初期値を付ける習慣や規約を採用している ても「グローバル変数の弊害」をいうプログ 自動変数の不定値 例もあります (List 9 ) 。ただ , 筆者個人は , ラマが少ないのは世界の七不思議に入れて こまでする必要性があるとは断言できな もいいぐらい不思議なことです。 いので何もいいませんが , 不定値パターン 実をいうと , 筆者はプログラマの有能さ で悩んでいる場合にはこのような方法も検 ( あるいは無能さ ) を見るとき , どのくらい 討する余地はあると思います。 「グローバル変数の弊害」に気づいているか 先ほど [ 対策 / 予防 ] のところで「デノヾッガ グローバル変数の削減に努力しているかを で丹念に追いかける」と書いたものの , や ポイントにしているほどです。どういうわけ っかいなことに自動変数の不定値はデバッ か無能なプログラマほどグローノヾル変数を ガを使ったときと使わないときで , 値が変 偏愛し , 有能な人ほど避けるものです。 わってしまうことが多く , 本番ではうまく ところが , それほど害のあるグローバル 不定値を防止するために初期値を付ける 動かないのに , デバッガでうまく動く ( あ 変数が偏愛されたり , 害があることに気づ るいは , その逆のパターンもありますが ) かなかったりするのはなぜかというと , ま ためにデバッガで調べられないという困っ さにグローバル変数の持つ強力さ , つまり , た状況も起こります。そのためにハード的 どこにでも簡単に導入できたり , 関数を越 えてパラメータを簡単に渡せるところが魅 なデバッガを使ってバグを追い込む方法も 力的だからです。とくに他人の重厚長大な 考えられています。 特集 1 プログラミングの禁じ手 29 凵 st void 日 ) 土 n し a; 醴辻 ch はを 3 ) ( case 0 : case 1 : case 2 : List void f() 土 n と thel char *theCp ま U し

4. 月刊 C MAGAZINE 2000年4月号

プログラミン % 禁じ手 特集 1 LiSt 36 例 し 隠 を 0 0 で ロ ク マ 常に「近似値」が出るということを覚悟すべ きです。たとえば , List 34 のようなコーデ イングは一見正しいように思えますが , 期 メモー ここでは c 十 + の例外処理機構すなわち t , cat 曲洋肚 ow を 待したとおりの挙動にならないことがあり ある程度、模倣するマクロを定義している。使い方は以下の通り 加し thevar; / / c 曲で t 0 ⅵ直を受け止める変数 ます。というのも浮動小数の演算には「丸 、ノ / t プロックの開始 ptry( め誤差」と呼ばれる誤差が付きものだから 。 w ( 値 / / t 0 曾の実行 です。人間の感覚で 10 進数で考えたときに 割り切れていると思われる式でも , コンピ pcatch(thevar)( 〃 cat 曲プロックの開始 ュータの内部の 2 進数の演算では割り切れ 0 瓧 ch で受け止める変数新 eva てはいあらかじめ土型変数として定義するこど pt 社 ow が実行されなかった場合、 theva てには 0 が無条件に入っている。 ずに誤差が発生している場合があります。 pt 社 ow で投げる値は 0 以外であるこど。 0 である場合、 pcatch プロック内は 実行されない。わざと 0 を投げるテクニックもイ吏えるかもしれないが、 そのため , ある値と等しいかどうかを判断 c 十 + 本来の t 社 0 Ⅳの仕様通りにはいかなくなる。 するには , いったん浮動小数を整数値に変 extern 加 gPTHROW—VALUE——i / * p に h て OW レベル * / 換してから判断するか ( ただし変換すると #define ptry きに桁落としをしないよう注意すること ) , gPTHROW—VALtjE——三 #define ゑセ h て 0 曾 ( V ) その値との差の絶対値が , ある程度以下な do ー gPTHROW—VALUE== VAL; 第 ら等しいとみなすロジックを採用するのが goto PCATCH—ENTRY——;= 第 ) ( 0 ト 常套手段です (List 35 ) 。 #define pcatch(VAR) PCATCH—ENTRY— VAR ま gPTHROW—VALUE——;- 第 ← gPTHROW—VALUE---e = 無節操な goto の使用 ( V ) 深刻度☆☆☆ ( 重度 ) チームプログラムの場合は , [ 症状 ] [ 原因 ] のですから , プログラマが , 「 goto 」の持つ強力な性格 なおのこと goto は禁じ手扱いです。 プログラムの解読や改造が困難になりま しかし , goto は , グローバル変数と同様 を理解していないことが原因です。 す。また , バグが発生しても退治しにくく [ 対策 / 予防 ] に強力な効能を持っています。また , 工ラ なります。 ー処理や例外処理に限定して「例外」的に いっさい , goto を使わないか , 例外や工 誤った浮動小数の比較処理 goto を使う方針もあります。ところが , 開 ラーに関する処理にならマクロや C + + の例 外処理に切り替えるとよいでしよう。 発プロジェクトにかかわっているすべての プログラマにそこいらへんがうまく伝わら [ 例外 ] 試作段階や試行錯誤している場合は許さ ないと「あ , goto 使ってら一 , バッカでえ」 と揶揄の対象になったり , あるいは「そう れるかもしれません。 か , g 。 to を使ってもいいんだ」となって軽率 [ 備考 ] どういうわけか「 goto 文はよくない」とい で怠慢なプログラマに都合のいい口実を与 うのは C 言語でプログラムをしている人は えることになりかねません。 たいてい知っています。わざわざ「禁じ手 ちなみに , List 36 のマクロは実際には パターン」としてピックアップするほどでも goto を使っているものの , それをマクロの なかに隠すことで安全に「例外処理」を実現 ありません。しかし , なぜ「よくない」かを した例です。 きちんと説明できるでしようか ? 理由が しかし , 本当に恐いのは明確に「 goto 」と わかっていないのに「よくない」といってい 表現しているのではなく「隠れた goto 文」に る人も多いような気がしてなりません。 なっている場合です。たとえば , break や 簡単にいえば , goto を乱用すると処理の con ⅱ nue というのは , goto と書かれてはい 流れが追い切れなくなり , わけがわからな ないものの , そこから一気に別の場所に飛 くなるからです。個人でプログラムする場 ぶという点で , まさしく goto 的な性格を持 合でも , わけがわからなくなる危険がある 特集 1 プログラミングの禁じ手 41 ノ * 凵 st 34 void f ( ) ödouble„ a; if(a 0 ) ( / * ←この部分がまずい * / LiSt 浮動小数の比較処理 #include <math. void f( ) double if(IsNearIySameDouble(a,0) ) { 土 n し IsNearlySameDouble(doubIe inA,double 土 ) return fabs(inA - inB) く 0.000 場

5. 月刊 C MAGAZINE 2000年4月号

第 3 章商品の購入 ソフトバンクバブリッシング株式会社 ( 以下「 SBP 」といいます ) は、 その運営する通信販売サービスであるソフトバンクバブリッシン 第 1 1 条商品の購入 1 . 会員は、本サービスを利用して SBP が出版する雑誌の定期購読サービス等のサービスを含む商品 ( 以下 グ・ダイレクト ( 以下「本サービス」といいます ) の会員規約 ( 以下「本 「商品」といいます ) を SBP から購入することができます。 規約」といいます ) を以下の通り定めます。 2. 会員は、商品の購入を希望する場合、 SBP が指定する方法に従って申込むものとします。 3. 前項の申込に対して、 SBP から電子メール、郵便等により承諾する旨の通知が会員宛に発信された時点で 会員と SBP との間に当該商品に関する ( 継続的 ) 売買契約が成立するものとします。ただし、会員指定のクレ 第 1 章総則 ジットカード会社からカード与信不履行の旨の連絡があった場合はこのかきりではありません。 4. 前項の規定に関らず、本サービス利用に関して不正行為または不適当な行為があった場合、 SBP は ( 継続 第 1 条本規約の範囲および変更 的 ) 売買契約を取消もしくは解除、その他適切な措置を取ることができるものとします。 1 . 本規約は本サービスの利用に関し、 SBP および会員 ( 第 3 条で定義します ) に適用されるものとします。 5. SBP は、商品の購入に関するサポートを、 SBP 定期購読センターを通じて行います。 2. SBP は、会員の事前の承諾を得ることなく、 SBP が適当と判断する方法で会員に通知することにより本 規約を変更できるものとします。 第 1 2 条商品の送付 1 . 本サービスを利用して購入した商品の配送先は日本国内にかぎります。 第 2 条本サービスの利用 2 . 商品は売買契約成立後、原則として 7 日以内に利用者に到着するように発送します。ただし、定期購読サ 1 . 会員は、本規約および SBP が別途定める本サービスに関するルール等に従い、本サービスを利用するもの ービスに関する商品 ( 月刊誌等 ) については、発売当日中に利用者に到着するように発送します。 とします。 3 . 郵便事情、道路事情等による商品到着の遅れについて、 SBP は責任を負わないものとします。 2. SBP は、会員の事前の承諾を得ることなく、本サービスの内容を変更することができるものとします。 4 . 商品の送付先は、会員の登録住所以外を指定することができますが、同一の注文番号で同じ商品を複数購 入した場合においても複数の送付先の指定はできないものとします。 第 2 章会員 第 1 3 条決済方法 1 . 商品の購入におけるお支払い金額は、商品の購入代金、取扱手数料および消費税の合計となります。 第 3 条会員 2. 本サービスによって購入された商品のお支払いに関しては、次の各号記載の方法、その他 SBP が別途認め 「会員」とは、本規約を承認いただいた上、 SBP 所定の手続に従い会員登録を申請し、 SBP がこれを承認し るお支払方法によるものとします。 た方をいいます。 ( 1 ) SBP 指定の会員本人名義のクレジットカードによるお支払い ( 2 ) SBP 指定の振込用紙を利用した郵便振替によるお支払い 第 4 条会員登録 ( 3 ) SBP 指定のコンビニエンスストアで、 SBP 指定の払込用紙を利用してのお支払い 1 . 入会希望者は、本サービスの提供する Web サイト ( 以下「 Web サイト」といいます ) の会員登録ページ ( 4 ) SBP 指定の銀行口座への振込によるお支払い ( 振込み手数料は会員負担とします ) または SBP 所定の会員登録申込書を利用し、 SBP の指定する方法に従い会員登録申請を行うものとします。 3. クレジットカードでの支払の場合は、会員がカード会社との間で別途契約する条件に従うものとします。 2. SBP は前項の申請に対し、会員番号および Web サイトで使用するバスワード ( 以下「バスワード」とい なお、会員と当該クレジットカード会社等の間で紛争が発生した場合は、当該当事者双方で解決するものとし、 います ) を発行することにより申請を承認するものとします。 SBP には一切責任はないものとします。 3. 入会希望者が過去に本規約違反をしたことなどにより会員登録の抹消などの処分をうけていることが判明 した場合、入会希望者の申請内容に虚偽の事項が含まれている場合、その他登録申請を承認することカ坏適当 第 14 条商品の返品および交換 であると SBP が判断する場合には、当該登録申請を承認しない場合があります。 1 . 商品の返品および交換は、配送中の破損、商品の瑕疵、商品間違い、その他 SBP が別途認める場合を除き できないものとします。 第 5 条変更の届出 2. 本条に基づく商品の返品および交換は、会員が商品を受領した後 5 日以内に SBP 定期購読センターに通知 会員は、住所、氏名、電話番号、電子メールアドレス、その他 SBP に届出ている事項に変更が生じた場合に をした場合にかきり行いうるものとします。 は、 SBP が別途指示する方法により、すみやかに SBP に届出るものとします。 3. 会員は、本条に基づく商品の返品および交換を、 SBP の定める方法および SBP 定期購読センターの指示 に従い行うものとします。 第 6 条本サービスの利用停止、会員登録の取消 SBP は、会員が以下の各号の一に該当する場合、会員に事前通知することなく本サービスの利用停止または 第 1 5 条中途解約 会員登録を抹消することができるものとします。 1 . 会員か購入した商品が SBP の出版する雑誌を継続的に購入する定期購読サービスである場合、会員は第 1 1 条に基づき成立した ( 継続的 ) 売買契約を、解約希望日の 1 ヶ月前までに SBP の指定する方式で SBP 定期 ( 1 ) 本サービスに関する料金などの支払債務の履行遅延その他の不履行があった場合 ( 2 ) 第 7 条 ( 禁止事項 ) の行為を行った場合 購読センターに通知することにより、中途解約することができます。 2. 前項により、会員が ( 継続的 ) 売買契約を中途解約した場合、 SBP は既に受領している商品購入代金およ ( 3 ) 3 年以上本サービスの利用がなかった場合 ( 4 ) その他本規約に違反した場合 び消費税のうち商品毎に定める金額を中途解約後 1 ヶ月以内に、 SBP の定める方法により返金します。 第 7 条禁止事項 第 1 6 条商品購入に関する免責 会員は以下の行為を行ってはならないものとします 1 . SBP は、会員が登録している連絡先へ連絡すること、および商品購入の際指示した送付先に商品を配送等 ( 1 ) 会員登録の際に虚偽の登録内容を申請する行為 することにより免責されるものとします。 ( 2 ) 本サービスの運営を妨げ、その他本サービスに支障をきたすおそれのある行為 2. SBP は、法律上の請求原因の如何を間わず、いなかる場合においても本サービスの利用および本サービス ( 3 ) クレジットカードを不正使用して本サービスを利用する行為 において売買される商品に関する損害、損失、不利益に関して第 1 3 条に定める以外の責任を負わないものとし ( 4 ) 会員番号およびバスワードを不正に使用する行為 ます。 ( 5 ) 他の会員、第三者もしくは SBP に迷惑、不利益もしくは損害を与える行為、またはそれらのおそれのある 行為 ( 6 ) 他の会員、第三者もしくは SBP の著作権、プライバシーその他の権利を侵害する行為、またはそれらのお それのある行為 ( 7 ) 公序良俗に反する行為その他法令に違反する行為、またはそれらのおそれのある行為 ( 8 ) その他、 SBP カ坏適当と判断する行為 第 8 条著作権 1 . 会員は、権利者の許諾を得ないで、本サービスを通じて提供されるいかなる情報も、著作権法で認められ る会員個人の私的複製等著作権の制限規定範囲外での使用をすることはできません。 2. 本条の規定に違反して問題が生じた場合、会員は自己の責任と費用においてかかる問題を解決するととも に、 SBP に何等の迷惑または損害を与えないものとします。 第 9 条会員番号およびバスワードの管理 1 . 会員は、 SBP が発行した会員番号およびバスワードの管理資任を負うものとします。 2. 会員は、会員番号を第三者に譲渡、貸与してはならないものとします。 3. 会員は、バスワードを第三者に譲渡、貸与、開示してはならないものとします。 4. 会員は、会員番号およびバスワードの管理不十分、使用上の過誤、第三者の使用などに起因する損害につ き自ら責任を負うものとします。 5. 会員は、会員番号およびバスワードが第三者によって不正に使用されていることが判明した場合には、直 ちに SBP に連絡するものとします。 6. 会員は、 Web サイトで本サービスを利用する際に行うクレジットカード番号の送信行為等の決済手段に伴 う漏洩等の危険性を認識し、自己の資任の下にこれを行うものとします。 第 10 条会員情報の利用 1 . 本サービスの利用に関連して SBP が知り得た会員の情報について、 SBP は以下の各号に該当する場合を 除き、第三者に開示または提供しないものとします。 ( 1 ) 会員が、自己の氏名、住所、性別、年齢、電子メールアドレスなどの開示に同意している場合 ( 2 ) SBP が本サービスの利用動向を把握する目的で収集した個人情報の統計を、個々の個人情報として特定で きない形式で第三者に提供する場合 ( 3 ) その他、本サービスの運営に必要な場合 2. SBP は、会員に対し SBP の商品案内等の目的で電子メールおよびダイレクトメール等を送付するため、 会員情報を利用する場合があります。 ソフトバンクバブリッシング・ダイレクト会員規約 第 4 章 Web サイトの運用 第 1 7 条 Web サイトの保守 SBP は、 Web サイトの稼動状態を良好に保っために、以下各号の場合会員に事前に通知を行うことなく Web サイトの提供の全部あるいは一部を中止することができるものとします。 ( 1 ) システムの定期保守および緊急保守の場合 ( 2 ) 火災、停電、第三者による妨害行為等により、システムの運用が困難になった場合 ( 3 ) その他、止むを得ずシステムの停止が必要と SBP が判断した場合 第 5 章一般条項 第 1 8 条権利義務譲渡の禁止 会員は、本サービスの利用に関して有する権利および義務を第三者へ譲渡し、または担保に供することはで きないものとします。 第 1 9 条その他免資事項 1 . SBP は、会員が本サービスをご利用になれなかったことにより発生した一切の損害について、いかなる責 任も負わないものとします。 2. SBP は、会員の登録内容に従い事務を処理することにより免資されるものとします。 3. SBP は、法律上の請求原因如何を問わず、いかなる場合においても本サービスの利用に関して生じた損害、 損失、不利益等に関して責任を負わないものとします。 4. 会員が、本サービスを利用することにより、他の会員または第三者に対して損害等を与えた場合には、当 該会員は自己の資任と費用において解決し、 SBP には一切迷惑を与えないものとします。 第 20 条その他 1 . SBP と会員との連絡方法は、原則として郵便によるものとします。 2. 本サービスのご利用に関して、本規約または SBP の指導により解決できない問題が生じた場合には、 SBP と会員との間で双方誠意をもって話し合い、これを解決するものとします。 3. 本サービスの利用に関して訴訟の必要が発生した場合には、日本法の適用の下、東京地方裁判所を第一審 の専属管轄裁判所といたします。 付則 : この規約は 1999 年 1 2 月 14 日からすべての会員に適用されます。

6. 月刊 C MAGAZINE 2000年4月号

五ロ 一編 ロ です。筆者が他人のプログラムを読むとき , のほうが有害な場合が多いのです。そうい などのシステム作りをするべきでしよう。 真っ先に目を付けるのがコメントの書き方 う意味で深刻そうな禁じ手パターンは , 次 とくに本人がユーモアのつもりだったり , です。そこがどうしようもないかていねい に紹介する「コメントに嘘がある」です。 単なる茶目つけのつもりでふざけたコメン に書いてあるかで , だいたいプログラムの トを付けた場合 , 真剣にコメントを読んで 品質をヒ。タリと当てることができます。 いる人たちを怒らせたり , あるいはチーム コメントに嘘がある 一般的に「プログラムにはわかりやすい の志気を落とす危険性があります。 深刻度☆☆ ( 中程度 ) コメントを書くべきだ」と強調されますし , [ 例外 ] コメントがない場合 , どういうプログラム [ 症状 ] チームで開発している場合 , 例外を認め なのかを調べるのがたいへんです。したが コメントに書かれていることと , 実際の るとたいへんなことになります。しかし個 って「コメントなしは禁じ手だろう」と誰も コードの内容が一致しないパターンです。 人が趣味でやっている場合はかまわないか が想像するでしよう。しかし , それはあっ コメントに書かれている嘘の内容を信じて もしれません。とはいっても , 昔書き込ん て当たり前の話なので , 筆者はわざわざ コードに間違った改変をほどこしたり , そ だ自分のふざけたコメントを読んで腹をた 「禁じ手パターン」という特別扱いはしませ の結果 , 別の障害が出て , 開発に遅れを生 てることもありうると思います。 ん。でも , いちおうは書いておきましよう [ 備考 ] じさせることになります。 嘘はないにしても , 何を説明したいのか これもコメントを書いた責任者の怠慢や 意味不明のコメントは , ほかの開発者を混 注意力の不足が最大の原因です。 乱させてしまいます。コメントの解釈に時 コメントがない [ 対策 / 予防 ] 間を取られるので開発に遅れを生じさせる 深刻度☆ ( 軽度 ) これに関してもコメントの品質を保証す ことになります。また , 昔気質のプログラ [ 症状 ] るためのシステム作りをするべきですし , マに多いのですがコメントを英語 ( もしく プログラムコードにコメントが書かれて 原因となった者の責任を問えるシステム作 は本人が英語と思い込んでいるだけのデタ いないものです。どういうプログラムなの りをするべきでしよう。 ラメの言葉 ) で書くというパターンもこれ かをコードを追いかけて調べるのに手間が [ 例外 ] に準ずるので , 紹介しておきましよう。 かかり , 開発に遅れを生じさせます。 このパターンに関しては例外を認めると [ 原因 ] たいへんなことになります。例外を認める コメントが英語 おそらくめんどうだったか , 開発者が「わ ということは , すなわち怠慢を積極的に認 深刻度☆ ( 軽度 ) ざわざコメントにするほどでもない」と思 めることになるわけですから , 絶対にあり ったのでしよう。怠慢というやつです。 [ 症状 ] えません。 [ 対策 / 予防 ] コメントが英語 , あるいは英語モドキに これに関してはコメント付けを習慣付け なっているパターンです。わからない単語 コメントが意味不明 を辞書で調べるのも手間だし , モドキの場 る何らかのシステム作りをするべきです。 深刻度☆ ( 軽度 ) [ 例外 ] 合は意味不明のコメントとなっていて役に 別途 , プログラムの説明やコメント代わ [ 症状 ] 立たないこともあります。場合によっては りの情報を記述した文書があるなら , プロ コメントの内容が理解できない内容にな 喧嘩やトラブルの原因にもなります。 グラムソース中にコメントがなくてもかま っている場合 , あるいは「〇〇ちゃーん , 愛 [ 原因 ] わない場合があります。また , 何でもかん してるよー」のようなプログラムの内容と 本人の勘違い ( 英語で書いたらカッコい 全然関係のない落書きが書かれているパタ い。これからは国際化時代でグローバルス でもコメントを付ければいいというわけで タンダードだもんね。みたいな ) , 外国人 ーンです。 もなく , 冗長なコメントや意味不明なコメ [ 原因 ] も開発に参加している , 英語でしかコメン ントがあると , かえってプログラムの解読 トを受け付けない開発環境などの原因が考 者をミスリードしかねません。 本人の国語力不足 , あるいはユ ーモアが [ 備考 ] あると思い込んでいるのか人格的に問題が えられます。 ある場合です。 案外 , 深刻度が「軽い」のに驚いた人もい [ 対策 / 予防 ] 本人の勘違いの場合は , それを本人にわ [ 対策 / 予防 ] るでしようが , 実はコメントがあったとし ても , その品質に問題がある場合 , そちら からせることが重要ですが , 現時点でこう これもコメントの品質の評価 , 罰則規定 特集 1 プログラミングの禁じ手 23 [ 原因 ]

7. 月刊 C MAGAZINE 2000年4月号

です。ちなみに筆者が Mac ⅲ tosh で使って 一種の妙な信念に凝り固まっているようで , いう英語コメントのスタイルを貫くという いる開発環境は , デフォルトの設定が英語 これを説得するのは難しいと感じました。 のはたいてい確信犯的というか , 一種の変 になっている場合が多いので最初にフォン 外国人がかかわったらという大義名分もあ 人でもあります。なるべくかかわらないよ りますが , 実際に日本で仕事をしているか ト指定を日本語に変更することから始めま うにするか , 黙認するしかないでしよう。 ぎりでは滅多に外国人と一緒に仕事をする 外国人が参加しているプロジェクトの場合 す。いわゆる 1 バイト = 1 文字の決めつけで 動いている開発環境でも , コメントは多バ 機会はないですし , だいいち目の前にいる や環境そのものが英語しか受け付けない場 イト文字が使用できるケースが多いのです。 日本人の同僚とうまくコミュニケートでき 合はやむをえないかもしれません。 とにかく簡単にあきらめずに調べつくしま ない人が海外の方とコミュニケートできる [ 例外 ] ものかどうか , とても疑問なんですけどね。 外国人も参加しているプロジェクトで , しよう。 [ 備考 ] ついでにいうと , 昔 , 筆者は実際に韓国の そのメンバからコメントを英語にしてほし いという強い要求があるならやむをえない 英語コメント ( あるいは英語モドキコメ 会社と仕事をしたことがありますが , その かもしれません。しかし , そういう場合で ント ) に関してはパソコン通信やインター ときのプログラムのコメントは韓国語にな ネットでバトル ( あるテーマに関する論争 ) も日本語のコメントと英語のコメントを併 っていました。しかし , そのことがとくに になるぐらい危険な話題です。ちなみに筆 仕事で支障になった記憶はありません。要 己するという工夫がほしいところです。環 するに「何語でコメントを付けるか」ではな 境が英語しか認めない場合でも , よく調べ 者もこの種のバトルに参加したことがあり く「どういう運営をするか」がだいじなわけ ると単にフォント指定を日本語にするのを ますが , いまの時点であえて英語コメント ( あるいは英語モドキコメント ) をする人は 忘れていたとかつまらない理由がありがち です。 り NULL を上手に説明しているとは思えま せん ( C 言語の仕様自体 , この引用文のよう なわけのわからない特例を認める仕様が , ところどころあって , これがさらに混乱に 拍車をかけている傾向がありますが , ここ では指摘するだけにとどめます ) 。いやら しいのは NULL は予約語ではなく単なる「記 号定数」という位置付けであるため , これ がプログラマの勘違いを補正しない要因に NULL というのはいまの C 言語では「無効 タは定数ゼロと比較することができる ポインタ」を意味するシンポルです。とこ 記号定数 NULL は , これがポインタに もなるわけです。 ちなみに C 言語以外のプログラム言語で ろが , これを数値のゼロと同一であると誤 対する特別な値であることをさらに明 解しているプログラマはさほど珍しくあり 確に示す記号として , ゼロの代わりに は , この種の無効ポインタを予約語にして いるものもあります ( たとえば Nil という名 ません。というのも , 多くの処理系で NULL よく使われる。 を定義している場所を検索してみると , 「プログラミング言語 C 第 2 版 ( 訳 称で表現するものがあります ) 。このよう な言語で , もし無効ポインタを数値のゼロ 書訂正版 ) 」 125 ページより引用 #define NULL 0 として評価しようとするとコンパイル時や みたいな記述になっているので , これだけ という文章があって , これが「そら見ろ。や 実行時にエラーになるので , この種の誤解 を見て「 NULL とは数値のゼロなり」と勘違 つばり NULL って数値のゼロだろ」という誤 いするわけです。ちなみに C 言語プログラ 解をさらに助長しかねません。この文章で が入り込む余地がありません。 マにとって必読な文献といわれている「プ は「 NULL は , ポインタに対する特別な値で ログラミング言語 C 」 ( いわゆる K & R と呼ば ある」ということをいいたいわけであり , NULL とゼロを間違える 「ポインタと整数は相互交換可能ではない れている有名な本 ) によれば , 深刻度☆☆ ( 中程度 ) が , ゼロだけは例外だ」ということを強調 ポインタと整数は相互交換可能ではな い。ゼロは唯一の例外である。定数ゼ したいわけではないのですが , 原文が悪い [ 症状 ] 具体的な被害は表面化しにくいが , プロ のか訳文が悪いのか , どっちにしてもあま はポインタに代入してよく , ポイン 24 C MAGAZINE 2000 4 NULL に関するバターン 人間は手で触れて確かめずに目で見た マキャベリ だけで判断する。

8. 月刊 C MAGAZINE 2000年4月号

Fig. 7 コンボーネントとアクションの実行処理 マウスクリックなど コンポー ネント OnClick と OnExecute がリンクされていない ショートカットの押下 アクションの更新処理 (Fig. 6 ) アクション OnClick と OnExecute がリンクされている トレベルやアプリケーションレベルで行う ときに便利です。また , アクションリスト の OnUpdate や AppIication の OnActionUpdat e イベントの Handled 引数を True にして返 すと , アクションの OnUpdate イベントの 実行を禁止できます。 アクションの OnExecute イベントの実行 次にアクションの OnExecu イベントが どのように実行されるかを説明しましょ アクションを用いない場合 , ボタンをク コンボーネントの OnClick イベント を実行 TControl.Click の違い ( Delphi 3/C + + BuiIder 3 以前 } procedure EontroI.Click; begin if Assigned(FOnClick) then FOnClick(SeIf); { Delphi 4/c + + Builder 4 以降 } procedure TControI.CIick; begin if Assigned(FOnClick) and (Action ◇ nil ) and (@FOnClick ◇ @Action.OnExecute) then FOnClick(Self) else if not (csDesigning in ComponentState) and (ActionLink ◇れ ) then ActionLink. Execute else if Assigned(FOnClick) then FOnClick(Self); Enabled=False 処理済み の . OnExecute の実行 アクションの属するアクションリスト アクションの . OnExecute の実行 処理済み Application. OnExecuteAction の実行 イベントが起こるだけです。 クションを使わない場合と同様 , OnClick ck と OnExecute が一致していない場合 , ア リンクしていない場合 , つまり , OnCIi 変わります。 「リンク」しているかどうかで処理が大きく トとアクションの OnExecute イベントが ます。この場合 , ボタンの OnClick イベン クリックした場合の動作の流れを示してい Fig. 7 はアクションを設定したボタンを 少々複雑な処理が行われます。 す。しかし , アクションを指定した場合は リックすると OnC1ick イベントが起こりま C + + BuiIderODeIphi 乢 [ 解体新書 リンクしている場合 , つまり OnClick と OnExecute が一致している場合は Fig. 7 で 示されているように いきなり OnClick が 実行されるわけではなく , ・アクションの更新処理 ・アクションが属するアクションリスト の OnExecute イベント ・ Application の OnExecuteAction イベン ト ・アクションの OnExecute イベント というように実行されます。 このように「リンクされている / いない」 で動作が変わるのは Delphi 4 , C + + Builder 4 以降では TCon け 01 の OnC ⅱ ck を起こすイベ ントディスパッチャ TControl. Click が List 5 のように変更されているからです。これは とても重要です。 アクションリストの OnExecute イベント と Application の OnActionExecute イベント は , アクションの実行処理において , アク ションリストレベルで共通処理を実行した り , アプリケーションレベルでの共通処理 を実行するのに便利です。また , アクショ ンリストの OnExecute イベントと Applicati on の OnActionExecute イベントには引数と してアクション自身と Handled が渡されま すが , HandIed 引数に True を返すと , 個々 のアクションの OnExecute イベントの実行 を禁止できます。 おわりに こまでアクションコンポーネント (T Ac ⅱ on ) の使い方を説明しましたが , 実は これはアクションの使い方の半分でしかあ りません。 アクションコンポーネントには TAction とは別に TCustomAction から派生するさま ざまなアクションコンポーネントが用意さ れており , これらは TAc ion とはまったく 異なる機能を持っています。また , このア クションコンポーネントを自作することが できます。 次回はこれらアクションコンポーネント のもうひとつの顔を解説します。 VCL 解体新書 133

9. 月刊 C MAGAZINE 2000年4月号

カリ 画像処理を極める M を大きくする , すなわちハッシュリスト を拡大することで , リストの走査をさらに 減らすことができますが , あまり大きくす ると使用メモリが多くなってしまいます し , 無意味に大きくしても使用されない部 分が増えるだけとなるので , バランスを考 えて増減する必要があると思います。 直方体 ( ボックス ) への分割 画像の RGB ヒストグラムを求めたあとは 分割処理を行っていきます。 RGB ヒストグ ラムを配列で求めた場合には , 配列を走査 していくことで画素のない部分を除去した り , 直方体を分割したりといった処理を実 現できますが , 単方向リストなどのリスト 構造などを用いた場合には別途アルゴリズ ムを工夫する必要があります。それはリス ト構造では配列の場合と違って任意の場所 のデータを即座に取り出すことができない こと , データが順序正しく並んでいる保証 がないことなどに起因します。そこで , のようなデータ構造を用いた場合の分割処 理を考えてみましよう。 まず , 前述のハッシュ法を用いて RGB ア ルゴリズムを求めましたが , このままのデ ータ構造では分割処理が不便なので , 配列 を用いたデータ構造に変換することにしま す。つまり , データ構造としては , 前述の List2 に示した画素値と画素数をセットにし たものを要素とする配列にします。変換を 行う時点では画像上の色数は求められてい るので , 必要最低限の配列だけを用意する ことができます。なお , 以降の説明ではこ のような形で表現された RGB ヒストグラ ムを「 RGB データ配列」と呼ぶことにします。 ヒストグラムを分割するには , 大きく分 けると , ・画素のない部分のカット ・もっとも長い辺を画素数が等しくなる ように分割 というふたつの処理があります。今回使用 したデータ構造に適用できるように各処理 の実現方法を考えていきましよう。 画素のない部分のカット メディアンカットアルゴリズムではまず RGB ヒストグラムから画素のない部分を除 去した直方体を求める必要があります。この 処理は RGB ヒストグラムの画素の存在する 部分の RGB の最小値最大値を求める処理と 考えることができます。この処理は RGB の 配列をすべて走査して RGB それぞれの最小 値最大値を求めることにより実現できます。 分割 RGB ヒストグラムの画素のない外側部分 を除去した直方体が求まると , 直方体のも っとも長い辺を画素数が同じになるところ で分割します。 RGB 配列に対してどのよう な処理を行えば分割処理が実現できるかを 考える前に分割の情報をどのように保持す るかを考える必要があります。本処理では , 分割の情報を List 6 に示すように RGB デー タ配列のどの要素からが直方体内の画素値 なのか , 直方体内の色数はいくつなのかを 記録することによって行うことにします。 また処理の効率化のために直方体内の画素 数の情報も持たせておくことにします。 このデータは求めたい色集合の色数の大 きさを持った配列でとります。このような 情報をポックス情報と呼ぶことにします。 ポックス情報の初期状態は全画素がひと つの直方体内に存在するというところから 始まります。分割を行うにしたがってポッ クス情報は逐次更新されていきます。 このようなデータの持ち方で本当にうま くいくのか疑問を持たれる方もいるかもし れませんが , 処理をうまくエ夫することに よってこのような情報で分割された直方体 の情報を表現できます。 さて , これらのデータ形式を用いて分割 処理を行うわけですが , 分割処理では直方 体のもっとも長い辺を分割します。もっと も長い辺は RGB のうち , 最大値最小値の差 がもっとも大きいものなので , 最大値と最 小値の差がもっとも大きい辺と定義できま す [ 注 1 ] 。もっとも長い辺が求まれば , 分割 TabIe 1 工フェクトプラグインで用いる PmacsA 曰関数 PMsGetCoIo 「 Onlmage 機 引 能画像上の任意の画素値を取得する CD 旧 * img int X. y Pix32 * col 画像データ 指定する座標 画素値が設定される 数 typedef union { unsigned long color; st 「 uct { unsigned char b; unsigned char g. unsigned char 「 : unsigned char opa; }citem : }Pix32; / * カラー値 * / / * 透明度 * / 戻り値座標が画像内なら T 日 U 巳画像外なら FALSE PMsSetColo 「 Onlmage 機 引 能 数 画像上の任意の画素値を設定する CD 旧 * img 画像データ GRAM32* out 結果をセットする領域 戻り値 int x,y Pix32 *col int reg int flag なし 指定する座標 セットする画素値 領域情報 ( 通常は与えられたものをそのまま渡せばよい ) 座標の種類を表す。工フェクタの場合は FALSE でよい 画像処理を極めるアルゴリズムラボ 121

10. 月刊 C MAGAZINE 2000年4月号

用できるような処理方法を考える必要があ ります。 以下 , 前述のふたつの処理についてそれ ぞれ考えていきましよう。 日 GB ヒストグラム メディアンカットアルゴリズムを実現す るためには , RGB ヒストグラムを求める必 要があります。この RGB ヒストグラムをど のようなデータ形式で表現するかが実装面 においては重要になってきます。もっとも 簡単な方法は RGB それぞれを添え字とする 三次元配列で表現する方法です。つまり , 画素値 (), G , B) の画素数を RGBhist[R] CG] [ B ] のような配列に格納する方法です。 このデータ構造で RGB ヒストグラムを求め るためには List 1 のようなプログラムを書 けばよいでしよう。しかし , この方法では 冒頭で述べたとおり RGB ヒストグラムのた めに大量のメモリを必要とします。配列を long 型 ( 32 ビット ) でとった場合には 64M バ イト , short 型 ( 16 ビット ) でとったとしても List List 2 を単方向リストにする 32M ノヾイトが必要になります。画素数が 256 の範囲を超えることは十分考えらるので , 8 ビット型は実用上利用できません ( 利用で きたとしても 16M バイトのメモリが必要で す ) 。より少ないメモリで RGB ヒストグラ ムを求めるにはどうすればよいでしようか。 日 GB 値と画素数をセットにする 省メモリ化を図るために利用できる事象 として , 1600 万色の色を扱うことができる フルカラーでは , 画像上にこれらすべての 色が利用されることは稀であるということ があります。たとえば , 800X600 の大きさ の画像では , 画素数は 48 万画素なので画像 内で 48 万色以上の色が使用されることは物 理的にありえません。また一般的な画像で は全画素の色が異なることは少なく , 使用 される色の分布にはかなりの偏りがある場 合がほとんどなので , 画像内で使用されて いる色数はもっと少ないはずです。そこで RGB 値と画素数をセットにして格納する方 法が考えられます。 このようなデータを格納するためには , まれ Fig. 2 リスト構造 チェーン状にデータをつないでいく 次のデータへのポインタで List 2 のようなデータ構造にします。この ようなデータを画像上に存在する色数だけ 用意して , 画素値と画素数をベアにして記 録しておきます。ある画素値の画素数を得 るには , このデータを調べて画素値が一致 するものの画素数を求めることで行います。 もし , データ内に一致する画素値が存在し なければ , その画素値は画像上に存在しな いとみなされます。 単方向リストを用いる こでこのようなデータをいくつ用意す ればよいかが新たな問題となります。色数 が事前にわかっている場合にはその色数ぶ んの配列を用意すればよいのですが , ヒス トグラムを求める , もしくはそれに近い処 理を行わないと色数は求まりません。この ようにデータ数が可変となる場合には一般 に Fig. 2 のようなデータ構造を用います。 この構造は単方向リストと呼ばれるもの で , 必要に応じて鎖状に伸ばしていくこと により , 可変長のデータ個数を持つデータ を扱うことができます。このようなデータ 終端には NULL をセット NULL typedef struct LIST { int r,%b; int num; struct LIST *next ・ } List; ハッシュ法 ハッシュ 関数 検索キー / / RGB 値 / / 画素数 / / ポインタチェー ( ハッシュ値 ) インデックス 検索キーにハッシュ関数を適用し ハッシュ値を求め . それをインデックスとして 配列内を検索する 1 18 C MAGAZINE 2 刈 4 データ値 ZZZ ァータ配列 0 インテックス シノニムに対応したデータ構造 インデックスデータ値 0 データ配列 用いる タを格納できるように単方向リストを 同じインデックスの場所に複数のテー