ショートカット
ファシリテーター × あり方
コーディングの向こう側
Hello, ANOTHER world!
オブジェクト指向のはなし
プログラミングのはなし
C言語実力診断クイズ
eSkillBooks
プログラミングのはなし

プログラミングハ複雑サトノ戦イダ!

プログラミングは、非常に複雑な作業です。恐らく人間の活動のなかでもっとも複雑なもののひとつです。あまりに複雑なため、良いプログラミングとは何か定義することすら困難です。

困ったことに、開発作業が進むほどプログラムは複雑になっていく傾向があります。ただでさえ複雑なものが、もっと複雑になっていくなんて!

さらに困ったことに、大規模プロジェクトでは大勢のプログラマーが参加することになります。プログラムを作る、つまりアルゴリズムを考案するという作業は極めて個人的・精神的・心理的な活動であるため、他人のプログラムは理解しがたい場合がしばしばです。本当はチームプレイが求められているというのに・・・。

より良いプログラムのため、私達は複雑さと戦う必要があります。実際、実力のあるプログラマーは複雑さを回避する術を身につけているものです。

「だけど、一体どうすればいいんだい?」

ひとつ例を挙げましょう。プログラミングをするときは、ほとんどの場合、サブルーチン(または関数)を作りますね。もちろんサブルーチンの第1の目的は同じような処理を1ケ所にまとめることですが、それだけではありません。もうひとつの重要な目的は「抽象化」です。次の C++ によるコードを見て下さい(ざっと見る程度で結構です)。

SAMPLE
CODE
#include <stdio.h>

static bool IsSameString( const char *pcLHS, const char *pcRHS )
{
    ASSERT( pcLHS != 0 );
    ASSERT( pcRHS != 0 );

    bool bSame = true;
    const char *pcL = pcLHS;
    const char *pcR = pcRHS;

    while ( ( *pcL != '\0' ) && ( *pcR != '\0' ) ) {
        if ( *pcL != *pcR ) {
            bSame = false;
            break;
        }
        pcL++;
        pcR++;
    }
    if ( ( *pcL != '\0' ) || ( *pcR != '\0' ) ) {
        bSame = false;
    }

    return bSame;
}

void main()
{
    if ( IsSameString( "abc", "def" ) ) {
        puts( "SAME!" );
    }
    else {
        puts( "NOT SAME!" );
    }
}

IsSameString というのがサブルーチン(関数)になっています。2つの文字列を比較して同じかどうかを判定し、同じなら true を返すというものです。ここで注目すべき点は、サブルーチンに、その機能を的確に表すような名前をつけているということです。そのため、呼び出し側(ここでは main 関数)ではサブルーチンの実装が具体的にどうなっているのか気にすることなく、サブルーチンの名前からその機能を理解することができます。つまり、文字列が同じかどうか判定するというアルゴリズムを関数名によって抽象化したのです。

< 注意 >
実際には ANSI-C に strcmp という関数があるので、
こんなプログラムは書く必要なし!

さて、関数名による抽象化の仕組みを理解しているのと理解していないのとではどちらのほうが複雑さを軽減できる可能性があるでしょう。答えは明らかですね。

このような抽象化の仕組みを理解していないプログラマーはたいていとんちんかんなプロトタイプの関数を設計してしまい、気付かぬうちに複雑さの餌食になってしまっています(例えば関数に f とか func とか全く意味のない名前をつけた場合を想像してみてください)。

複雑さの前兆を素早くキャッチし、手後れにならないうちに何とかできる力を身につけなければなりません。しかし、プログラミングはとても奥深いものです。まずはその深みに身を投じてみるのが良いでしょう。

(「プログラミングのはなし」は1998年1月から1999年1月にかけて作成されたコンテンツです。)