Codelogy

2007年08月29日

三項演算子

C/C++ をはじめとして、多くの言語では「三項演算子」がサポートされています。

1. 三項演算子の使用例
//偶奇性の表示
void PrintParity(int n){
    puts((n % 2 == 0) ? "even" : "odd");
}

処理の内容が同じでパラメータだけが異なるような処理の場合、三項演算子を上手く使うとコードが簡潔になります。

2. if ステートメントによる分岐
//偶奇性の表示
void PrintParity(int n){
    if (n % 2 == 0)
        puts("even");
    else
        puts("odd");
}

しかし、「条件 (第 1項)」や「値 (第 2, 3項)」が長い場合は、コードが横にだらだらと伸びてしまい美しくありません。
そんなときは、値の項を1段下げて記述すると見やすくなります。
2つの「値」が同列に並ぶとともに、「条件」より1段下がることで従属関係が明確になるという利点があります。

3. 段下げした三項選択
//中央値
double median(const Array<int>& an){
    return (an.size % 2)
        ? values[an.size/2]
        : 0.5*(values[an.size/2 - 1] + values[an.size/2]);
}

ちなみに、Ruby などのステートメントの終端が明示されない言語では、この方法は使えません。 (「条件」の評価値を返して終了してしまうため。)
この問題は、津のように ? および : 演算子を行末に移動してやることで解決できます。

4. 段下げした三項選択 (Ruby の場合)
# 中央値
def median(const values)
    return (values.size % 2 != 0) ?
        an[an.size/2] :
        (an[an.size/2 - 1] + an[an.size/2])/2
end

しかしながら、この記法はいまひとつエレガントさに欠けます。
ステートメントの終端をセミコロン (;) で明示する僅かな手間を惜しみさえしなければ、こうした曖昧さはないのに……。
と、三項演算子を綴るたび、Ruby の文法に不満を覚える C++ 使いでありましたとさ。

担当: 成田 (句読点を抜かすんじゃあないッ!!)

2007年09月25日

【c++】インタプリタを初めから丁寧に 第01回

アプリケーションがスクリプトにより動作を変更できるようにするのは、応用範囲も広く(他人に仕事を任せれるため)大変重要です。 特にゲームなどでは、敵の動作などをハードコーディングしてしまった場合プログラムを製作した人しか変更することが難しく、その変更も非常に面倒になってきます。

インタプリタを製作するには yacc や lex を使うと大変便利ですが、内部動作をよく理解するために最初は手書きで作ってみることが必要でしょう。 第01回はインタプリタの内部動作についてを学習します。

>> 続きを読む...

2007年09月27日

C++例外処理のススメ

Java をはじめとするいくつかの言語は、実行時に発生したエラーを処理する仕組みとして、例外処理機構を採用しています。
例外処理を使うと、戻り値でエラーを検知・処理する手法よりも確実に行うことができる上、コードの記述も簡潔になります。
C++ もこの例外処理を採用していますが、Java のそれと比べても明らかに普及していません。
その理由としては、

  • 前身である C から、従来のエラー処理手法 (戻り値で検出) が尾を引いている。
  • Java の Exception のような、標準の例外型が存在しない。
  • 例外の補足・処理が強制されない。(Java では throws キーワードを使用してこれを強制する。)

などが考えられます。
これらのうち、1. 2. を解決すべく、Java に負けじと C++ 版 Exception を作成してみました。

これを使えば、従来よりも簡単かつ便利に例外処理を行うことができます。

>> 続きを読む...

2007年11月30日

【c++】インタプリタを初めから丁寧に第03回

前回に引き続き字句解析プログラムの内容について考えます。
成田さんに添削していただいた部分も合わせて冗長な部分を削除した・・・つもりです。

  • 演算子
  • 制御文判別子

>> 続きを読む...

2007年12月09日

XMLライブラリの紹介 (1)

某所からの「Codelogy にエントリを投稿しろ」という圧力が大きくなってきたので、自作の XML ライブラリでも紹介してお茶を濁そうかと思います。 とは言っても、業務に使用しているものなので、ちゃんと使えるレベルには仕上がっています。

>> 続きを読む...

2008年04月05日

宣言の位置

C言語では、ローカル変数の宣言を関数の始めに宣言する必要がありました。
これを習慣としているのか、C++ でもローカル変数・オブジェクトの宣言を関数の開始位置で行う人がいます。

//分散を求める関数 (C++スタイル宣言)
int variance(const Array<double>& ad){
    assert(ad);

    double dSum =0;

    int i;
    for (i=0; i<ad.size; ++i) dSum +=ad[i];

    double dAvr   =dSum/ad.size;
    double dSumSq =0;

    for (i=0; i<ad.size; ++i){

        double dTmp =ad[i] - dAvr;

        dSumSq +=dTmp*dTmp;
    }

    return dSumSq/ad.size;
}
//分散を求める関数 (Cスタイル宣言)
int variance(const Array<double>& ad){
    assert(ad);

    double dSum   =0;
    double dSumSq =0;
    double dAvr;
    double dTmp;
    int i;

    for (i=0; i<ad.size; ++i) dSum +=ad[i];

    dAvr =dSum/ad.size;

    for (i=0; i<ad.size; ++i){

        dTmp =ad[i] - dAvr;

        dSumSq +=dTmp*dTmp;
    }

    return dSumSq/ad.size;
}

それでも動作には何の支障もありませんが、変数の「宣言」と「実際に使われ始める位置」が離れてしまうため、プログラムがやや読みづらくなります。 また、上例のCスタイルの方では、2番目のループ内でのみ使われる変数 dTmp のスコープが関数全体に及んでしまうのも、あまり良い状況ではないでしょう。
しかし、C++ が変数・オブジェクトの宣言を関数の任意の位置で行えるようになっているのは、このような可読性に関する (些末な) 問題のためだけではありません。 これには、C にはなかった「クラス」「オブジェクト」が大きく関係しています。

>> 続きを読む...

2008年05月01日

XMLライブラリの紹介 (2)

前のエントリからかなり間が空いてしまいましたが、XML ライブラリの紹介の続きです。

読み込んだXML文書のツリー構造をたどって各要素に対する処理を行うのは、手間がかかります。
今回は、フレームワークを利用して XML 文書を解釈 (interpret) する方法について説明します。

>> 続きを読む...

2008年08月01日

3Dモデルファイルの独自形式制作(1回目)

3D系プログラムをしていると、どうしてもついて回るのが読み込みモデリングファイルの形式です。
私は普段DirectXを使っていますので、標準形式のXFileを使えばよいではないかということになりそうですが、XFileの方言はひどいものがある上に上位にあたるXNAではXFileをサポートしないといったことになっており散々です。
よくデザイナーさんが使うmaya, 3ds max, LightWave3Dなどのソフトがありますが、それぞれのエクスポーターで出力するXFileも方言があり、Root Frameにアニメーション情報を含んだり、含まなかったり、メッシュの名前をつけたりつけなかったりと様々です。
(他にもアニメーションの名前をつけたりつけなかったりするものまで・・・)
当然標準のビューアのみで対応できるはずもなく、マテリアル色がおかしくなったり、アニメーションが壊れたり、描画すらされなかったりといった結果になります。

それぞれのソフトに対応したエクスポーターを書いてもよいのですが、現在進行中プロジェクトではmaya, max, light waveすべてからのデータが送られてくるため、3つもエクスポータを書くのはさすがに無理です。
ですので、これらの問題を埋めるためにAutodesk社が標準とするFBXというファイル形式から必要な情報を抜き出し独自形式にコンバートしたいと思います。

今回はお仕事用としてのメモも兼ねますので、すぐに次の情報をアップしたいと思います。今回はFBXのパース、バージョンが上がったSDKの使い方がメインです。

>> 続きを読む...

About C++

ブログ「Codelogy」のカテゴリ「C++」に投稿されたすべてのエントリーのアーカイブのページです。過去のものから新しいものへ順番に並んでいます。

次のカテゴリはHaskellです。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。