関数分けの効用
通常、プログラムを書くときは、処理をただ順番に書き下すのではなく、いくつかの「関数」に分割します。 これによって各ステップの処理が部品化され、再利用が可能になるわけですが、関数分けの効用はそれだけに留まりません。 例え、たった一度しか実行されない処理でも、これらを上手く関数化し、本体から分離することで、プログラムの可読性・保守性を向上させることができます。
例えば、以下のようなフォームからデータを受け取るプログラムを考えてみましょう。
![]() |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Codelogy | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
関数分けの効用通常、プログラムを書くときは、処理をただ順番に書き下すのではなく、いくつかの「関数」に分割します。 これによって各ステップの処理が部品化され、再利用が可能になるわけですが、関数分けの効用はそれだけに留まりません。 例え、たった一度しか実行されない処理でも、これらを上手く関数化し、本体から分離することで、プログラムの可読性・保守性を向上させることができます。 例えば、以下のようなフォームからデータを受け取るプログラムを考えてみましょう。 構造体によるデータ集約個人的な観測範囲内での話ですが、「プログラマ」と呼ばれる人の中には、自分で構造体 (あるいはクラス) を定義することを面倒臭がり、これをしないで済ませようとする人が少なくありません。 彼らは、本来構造体として集約されるべきデータをプリミティブ (組み込み型) と標準ライブラリなどで与えられたコンテナ型を組み合わせることで表現しようとします。
例えば、地図上の登録地点の情報を CSV (各列にID, 名前, 緯度, 経度, 解説, ... が格納されている) から読み取るコードは以下のようになるわけです。
(
だからそうじゃねぇだろうが!! C++の std::unique と、Ruby の Array#uniq の本質的な違い配列から重複した要素を取り除きたいとき、C++ では STL の std::unique を、Rubyでは Array#uniq を使うことが出来ます。
これらの関数 (メソッド) は全く同じ働きをするように見えますが、よく調べてみると、実は微妙に異なる動作をすることが分かります。 異なる動作をするのは、具体的には次のようなケースです。
std::unique では望んだとおりの出力が得られません。 これは何故でしょうか。 Array クラスを作る (size フィールド編)
Java では、配列の要素数をフィールド
この 一方、C++ ならば、値の変更が可能かつ、外部からの変更が不能なメンバ変数 (を模したインターフェイス) を定義することが可能です。 このエントリでは、このテクニックを使い、これまでのエントリで作成してきた Array クラステンプレート (参照) に要素数読み取り専用のメンバ変数 size を定義します。 ビット演算の基礎ビット演算を使用すると、1つの整数型データをビット単位で区切って、複数の用途に割り当てることができます。 例えば、符号なし整数 (unsigned int) のデータ長が32ビットの環境であれば、一つの変数で32個の真理値 (bool: true/false に相当) を格納することができます。 また、これらの真理値を複数個まとめて参照・操作することも可能です。 しかし最近のプログラミング環境では、潤沢なメモリやライブラリの普及などにより、ビット演算を利用するような場面は、以前と比べて少なくなっています。 そのため、ある程度長くプログラミングを学んでいるにも関わらず、ビット演算が使えない、あるいはその概念自体を知らないという人も見かけるようになりました。 というわけで、今回はビット演算の基本中の基本である、ビット値の参照・操作の方法とその手順について解説します。 ちなみに、当エントリの説明では図のスペース節約のため、8ビット符号なし整数 (BYTE: unsigned char) を操作の対象としていますので、実際に使用する場合は適当なデータ長に置き換えて考えてください。 32ビット環境で64ビット整数を扱う (加法編)
通常用いられる整数型 (32ビット符号付き) は -2,147,483,648 ~ 2,147,483,647 の範囲の値を表現することができます。 参照の配列は何故作れないか参照の配列は作れないさて問題です。次のコードの実行結果はどうなるでしょうか?
見出しを見た皆様のお察しの通り、正解は、「そもそもコンパイルされない」です。
このように、C++では参照の配列を作成することは出来ません。
タグ:
C++
32ビット環境で64ビット整数を扱う (減法編)
32ビット環境で64ビット整数を扱う (加法編) の続き。 念のため、前回のエントリで使用した64ビット整数を表現するための構造体 QWORD の定義を再掲します。
カウンタ付き参照C++ では、new を用いてオブジェクト (メモリ領域) を確保したならば、これを delete でを明示的に解放してやらなければなりません。 この「借りたもの (メモリ) は自分で返す」という硬派なスタイルは非常に C++ らしく、またパフォーマンスの面でも優れるため、個人的にはとても気に入っています。 その一方で、このスタイルにはメモリリークや二重解放によるアクセス違反, ダングリング・ポインタの発生といった問題があり、致命的なバグの原因となりがちであることも事実です。 また、プログラムの性質上、オブジェクトが利用されなくなるタイミングが予測しづらく、明示的な解放を記述することが原理的に困難であるような状況というものも存在します。 C/C++ 以外の殆どの言語はガーベジ・コレクションを言語仕様として採用することでこうした問題を回避しています。 特に、ガーベジ・コレクション手法の一つである参照カウントは、その動作原理が非常に単純であり、またそれ故に (一般的な状況下における) パフォーマンスにおいて他の手法よりも優れています。 そこで、この参照カウントの仕組みを C++ でも利用できないかと考え、Reference というクラステンプレートを作ってみました: ソースコードは上記リンク先のページからダウンロードすることができます。 今回はこの Reference クラステンプレートの使い方について簡単に説明します。
タグ:
C++
C++ スタイルのキャストC言語では、キャスト (型変換) を以下のような形式で行います。
この記法では、どのような種類のキャストが行われるのかを明示したり、不正・危険なキャストに対してチェックを行うことができないという問題があります。 オブジェクト指向のメリット (カプセル化編)Eyes, JAPAN では、ソフトウェア開発には専ら C++, Java, Ruby などの オブジェクト指向プログラミング言語を用いています。(一部例外もありますが。)
ところで、「"オブジェクト指向" とは何か?」と問われたとき、「○○○○のことだ」とはっきり答えることのできる方はいないのではないでしょうか?
といった概念・機能 (の一部または全部) を取り込んだプログラミング手法の総称であり、厳密な定義は存在しないのです。 今回は、その中でももっとも分かりやすい (目立つ) 機能である「カプセル化」について、その概要とメリットを説明してみたいと思います。
タグ:
C++
Array クラスを作る (演算子編)
"Array クラスを作る" シリーズの 4回目です。 過去の内容については、以下の記事を参照してください: XFile方言アレコレイントロダクション
最近 3ds max から独自形式を吐き出すエクスポーターを作成しているのですが、その際 3d, xfile, maxsdk の仕様など学ぶことがいろいろありました。
まずは独自形式の前に一般的に知られているファイル形式を出力したいと思いました。
タグ:
XFile
モーションキャプチャデータの使い方 (計画編)
前回予定していましたFBX形式からメッシュやマテリアル情報を抜き出す方法ですが、FBXSDK のドキュメントがあまりにも (以下略) であるため、断念しました。
ですので今回はFBXはおいておき、モーションキャプチャデータであるBVHファイルの利用方法を考えてみたいと思います。
タグ:
BVH
Ruby でも型チェック
動的型付け (スクリプト) 言語では、データ型のチェックが実行時にしか行われないため、プログラムの妥当性検証・デバッグといった作業が困難になります。
この手のバグは、問題の発生 (不正な型の代入) と発覚 (エラーの発生) の位置が離れてしまうので、非常に厄介。 発生箇所を絞り込むのが難しいため、プログラムを広範囲に渡って見直すハメになります。 GPUでレイトレーシング (補足)前回のGPUでレイトレーシングを並列処理についてもう少し補足したほうがよさそうでしたので、補足します。 今回はGPUのジョブの単位、メモリの扱い、画面分割の割り当てを図を用いて説明します。 GPUでレイトレーシングを並列処理
以前やったGPUでレイトレーシングを並列処理の続きとして、今回はGPUでレイトレーシングを行いたいと思います。 Haskell でバグの出にくいプログラミング (4) ローカルスコープによる変数代入の模倣前回は、副作用である変数代入という概念が純粋関数型言語である Haskell には存在しないということを書きました。 今回と次回は、そのような変数という概念を純粋関数的に模倣した Haskell の State モナドについて書こうと思います。 今回は、State モナドの説明の前段階として、ローカルスコープを用いた変数代入の模倣についてです。
タグ:
Haskell
変数宣言の位置C言語では、ローカル変数の宣言を関数の始めに宣言する必要がありました。 これを習慣としているのか、C++ でもローカル変数・オブジェクトの宣言を関数の開始位置で行う人がいます。
それでも動作には何の支障もありませんが、変数の「宣言」と「実際に使われ始める位置」が離れてしまうため、プログラムがやや読みづらくなります。
また、上例のCスタイルの方では、2番目のループ内でのみ使われる変数
タグ:
C++
0からはじめる計算幾何学 第04回 過去のプログラムの有効活用
昔書いたプログラムをもう一度使えないかと考えることは、多くのプログラマにとって (そしてエントリのネタを探す私にとっても) 重要なことです。
タグ:
ICPC
コメントつけろよプログラマは自分でコードを書くことができるだけでなく、他人が書いたコードを (ある程度は) 読むことができなければなりません。 その際に最もゲンナリさせられるのが、コメントが全くないソースコードです。
腕の立つプログラマのコードというのはきちんと構造化されいるため、コメントに頼らずとも作者の意図をきちんと読み取ることができます。
しかし、そのようなコードを書くプログラマは、コメントもきちんと付けるもの。
むしろ、初心者や読みづらいコードを書くプログラマほど、コメントも疎かになる傾向があるようです。
などなど……。(いずれも、実際に言われたことがある。) |
2012年 2月
最近のエントリ最近のコメント
ビット演算の基礎
参照の配列は何故作れないか
【Ruby】 Office2007 ファイルの書き換え
検索言語
その他 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Copyright 2007 - 2010 Eyes, JAPAN | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||