header

■制御文

C#の制御文は
C,C++のそれとまったく同じ構文で、使い方も同じです。
読み飛ばしてもOKですが一応まとめておきます。

    選択文
        条件判断                    if, else, else if
        分岐                        switch

    繰り返し文
        繰り返し                    for
        前判断ループ                while
        後判断ループ                do 〜 while

    ジャンプ文
        ループ脱出                  break
        ループの先頭へジャンプ      continue
        ジャンプ                    goto
        メソッドから戻る            return


条件判断 if, else, else if
条件の真偽によって処理を行ったり、行わなかったりします。 以下に例を挙げます。 【書式例】

    1.条件式が真の場合、後ろの文1が実行されます。

        if (条件式) 文1;

    2.条件式が真の場合、文1が実行されます。(改行は無視されます)

        if (条件式)
            文1;

    3.条件式の真偽に関わらず、文2は実行されます。

        if (条件式)
            文1;
        文2;

    4.複数の条件式を指定することも可能です。(論理演算子については後述)

        if (条件式1 && 条件式2) 文1;

    5.条件式が真の場合文1が実行され、偽の場合文2が実行されます。

        if (条件式)
            文1;
        else
            文2;

    6.条件式の真偽によって実行される文を{}で囲み、複数指定します。
        if (条件式)
        {
            文1;    // 条件式が 真 の場合実行されます。
            文2;    // 同上
        }
        else
        {
            文3;    // 条件式が 偽 の場合実行されます。
            文4;    // 同上
        }

    7.{の位置はお好みで下記のように記述することも可能です。

        if (条件式){
            文1;    // 条件式が 真 の場合実行されます。
            文2;    // 同上
        }
        else{
            文3;    // 条件式が 偽 の場合実行されます。
            文4;    // 同上
        }

    8.真偽、いずれか一方のみ{}で囲んでも構いません。

        if (条件式)
        {
            文1;    // 条件式が 真 の場合実行されます。
            文2;    // 同上
        }
        else
            文3;    // 条件式が 偽 の場合実行されます。

    9.条件式によって実行される文が1つの場合であっても
      見やすいように{}で囲んで構いません。

        if (条件式)
        {
            文1;    // 条件式が 真 の場合実行されます。
        }
        else
        {
            文2;    // 条件式が 偽 の場合実行されます。
        }

    10.最初の条件式が偽の場合、続けて次の条件式を指定できます。
       if と else の間の else if は何回でも記述できます。
       また、不要であれば else if の後の再度のelse節は省略可能です。

        if (条件式1)
        {
            文1;    // 条件式1が 真 の場合実行されます。
        }
        else if (条件式2)
        {
            文2;    // 条件式1が 偽 で、条件式2が 真 の場合実行されます。
        }
        else
        {
            文3;    // 条件式1,2いずれも 偽 の場合実行されます。
        }

    11.if文の中にさらにif文をネスト記述可能です。(入れ子)
       { と } の対応、if と else の対応に注意してください。

    ┌─if (条件式1)
    │  {
    │      // 条件式1が 真 の場合実行されます。
    │      文1;
    │
    │      // 条件式1が真の場合、次のif文の条件式2が評価されます。
    │┌──if (条件式2)
    ││    {
    ││        // 条件式1が真の場合、さらに条件式2が真の場合実行されます。
    ││        文2;
    ││    }
    │└──else
    │      {
    │          // 条件式1が真の場合、さらに条件式2が偽の場合実行されます。
    │          文3;
    │      }
    │  }
    └─else
        {
            // 条件式1が偽の場合実行されます。
            文4;
        }

分岐 switch
式の値によって処理を分岐します。 例えば、ある式の値が 1の場合は処理1、 2の場合は処理2、 3の場合は処理3・・・ と、同じような評価を繰り返す場合に用います。 同様のことが if 〜 else if の連続でも記述できますが、 switchの方が効率的な場合はswitchを使います。 【書式例】 式の値が定数1と等しい場合、処理1が実行されます。 式の値が定数2と等しい場合、処理2が実行されます。 式の値が定数3と等しい場合、処理3が実行されます。 式の値が定数4または定数5と等しい場合、処理4が実行されます。 式の値が上記いずれの定数とも等しくない場合、処理5が実行されます。

        switch (式)
        {
            case 定数1:
                処理1;
                break;

            case 定数2:
                処理2;
                break;

            case 定数3:
                処理3;
                break;

            case 定数4:
            case 定数5:
                処理4;

            default:
                処理5;
                break;
        }

【補足1】 switchの式に指定できるものは intなどの整数型とstring型のみです。 (浮動小数点を扱う型は指定できません) なお、default節は省略可能ですが 各case文で処理を行った後のbreak文は省略できません。 C#ではcase文内の処理を終えた後、 次のcase文の処理を行うような流れ落ちる処理(フォールスルー) は禁止されており、コンパイルエラーとなります。 例えば、次のコードは 各case文にbreak文が無いためコンパイルできません。

        // 定数1のcase文の後、定数2のcase文へフォールするー不可
        switch (式)
        {
            case 定数1:
                処理1;

            case 定数2:
                処理2;
        }

理由としては、break文の書き忘れによる意図しない動作の防止目的と コンパイラの最適化を助けるためです。 【補足2】 C,C++では、switchの式に文字列を指定できませんが C#ではstring型を扱えるのが特徴です。 具体的には以下のよなコードが記述可能です。

        string str = "tanaka";

        switch (str)
        {
            case "yamada":
                // 山田さんの処理
                break;
            case "satoh":
                // 佐藤さんの処理
                break;
            default:
                // 上記以外の処理
                break;
        }

【補足3】 if文同様、switch文もネスト(入れ子)可能なので switch文中にさらにswitch文を記述することが可能です。 しかし、場合によっては かなり読み辛いコードになってしまうのでほどほどに。
繰り返し for
処理を繰り返し実行します。 後述するwhileやdoも同様に繰り返し処理を行いますが forは、ある回数繰り返し実行する処理を行うのに向いています。 (例えば、1〜10までの整数の和を求める、など) 【書式例】 まず最初に初期処理(多くはループカウンタの初期値設定)を行い、 式が評価され、それが真の場合、文が実行されます。 次いでループカウンタが増減(インクリメント或いはデクリメント)され 再び式が評価されます。 式が真の間、何度も文が実行され、 式が偽になるとfor文の繰り返し処理が終了します。 なお、()内の;で区切られた3つの処理 初期処理、式、ループカウンタの増減の各セクションは それぞれ省略可能です。(;は省略できません) C,C++同様、for文はかなり柔軟な記述が可能です。 以下に例を挙げます。

    1.単一文の繰り返し

        for(初期処理; 式; ループカウンタの増減) 文;

    2.{}で囲まれた複数処理の繰り返し

        for(初期処理; 式; ループカウンタの増減)
        {
            文1;
            文2;
            文3;
        }

    3.初期処理の省略

        for(; 式; ループカウンタの増減) 文;

    4.すべてを省略した無限ループ

        for(;;)
        {
            ループを抜ける場合はどこかでbreak文を記述します(後述)
        }

    5.文の無いループ
      for文単体で行いたい処理が完結してしまう場合など。
      何も繰り返す必要が無い場合に文を省略可能です。

        for(初期処理; 式; ループカウンタの増減) ;

【具体例】 1〜10の整数の和を求めるfor文の例。

        int total = 0;
        for( int i = 1; i <= 10; i ++ )
            total = total + i;

ここでは int i = 1 が初期処理 i <= 10 が式 i ++ がループカウンタの増減 です。 for文中でループカウンタのiが宣言可能であることも注目すべき点です。 (もちろん、for文の前で宣言しても構いません) 【補足】 for文中の;で区切られた3つのセクション ・初期処理 ・式 ・ループカウンタの増減 は、次のように解釈することもできます。 ・初期処理 最初のセクションは ループがはじまる前に1度だけ実行されます。 ループカウンタの初期化だけに限定されません。 この位置に関数等の処理を書いても構いません。 ・式 2番目のセクションは ループする都度、毎回評価されます。 実際にループする前に式が評価される点にも気をつけましょう。 式によっては、for文は1度もループしません。 また、この位置に関数等の処理を書いても構いません。 ・ループカウンタの増減 3番目のセクションは ループカウンタの増減だけでなく ループする都度実行されるセクションです。 この位置に関数等の処理を書いても構いません。 具体例で示したような典型的な利用例に限らず 汎用的に使いこなしてください。
前判断ループ while
条件式が真の間、ループします。 条件式はループ内の処理が実行される前に判断されます。 条件式の真偽によっては、 whileで繰り返したい処理が1度も実行されない場合があります。 処理を繰り返す回数が決まっている場合はforを。 回数が決まっていない場合はwhileが向いています。 【書式例】

    1.単一文の繰り返し

        while(条件式) 文;

    2.{}で囲まれた複数処理の繰り返し

        while(条件式)
        {
            文1;
            文2;
            文3;
        }

後判断ループ do 〜 while
条件式が真の間、ループします。 条件式はループ内の処理が実行された後に判断されます。 つまり、ループの1回目の処理は条件式が評価されません。 条件式の真偽によらず、 do 〜 while間の処理は必ず1度は実行されます。 最後のwhile(条件式)の後ろに;が必要な点に注意してください。 【書式例】

    do
    {
        文1;
        文2;
        文3;
    }while(条件式);

【具体例】 番外編的な例ですが、do 〜 while の変わった使い道として 例えば、次のように エラーが発生するとgotoでエラー処理へジャンプするロジックを

        public void Func()
        {
            bool err;

            err = 処理1();

            if (err)
                goto ERR;

            err = 処理2();

            if (err)
                goto ERR;

            return;

            ERR:
                エラー処理();
        }

次のようにgotoを使わないコードへ書き換えることができます。 注目すべきは do 〜 whileの条件がfalseなので、常に1度もループしない点です。

        public void Func()
        {
            bool err;

            do
            {
                err = 処理1();

                if (err)
                    break;

                err = 処理2();

                if (err)
                    break;

                return;
            }while(false);

            エラー処理();
        }

ループ脱出 break
ループ(for、while、do〜while)を任意の位置で脱出します。 脱出したい位置に break を記述します。 なお、switch文中のbreakは、当該switch文に対してのみ影響を与えます。 従って、ループ中のswitch文のbraekはループを脱出しません。 【forループの例】

    // 1〜100の整数の和を求めながら、和が100を超えたら脱出
    int total = 0;
    for( int i = 1; i <= 100; i ++ )
    {
        total = total + i;
        if( total > 100 )
            break;  // 脱出
    }

【whileループの例】

    // 関数の戻り値を累算し、累算結果が100を超えたら脱出
    int total = 0;
    while( total > 100 )
    {
        total = total + Get();
        if( total > 100 )
            break;  // 脱出
    }

【do〜whileループの例】

    // 処理の途中で関数がエラーを返したら脱出
    do
    {
        bool err;

        err = 処理1();
        if( !err )
            break;

        err = 処理2();
        if( !err )
            break;

        err = 処理3();
        if( !err )
            break;
    }while(false);

【switchの例】

    // switch文中のbreakはループ脱出しない
    while( true )
    {
        中略

        switch(式)
        {
            case 1:
                処理1();
                break;      // whileループを脱出しません。
            default:
                break;      // whileループを脱出しません。
        }

        中略
    }

ループの先頭へジャンプ continue
ループ処理の途中で、ループの先頭へジャンプしたい時に使います。 ループ処理中にcontinueが実行されると 以後のループ処理は行われず、ループ処理の先頭へジャンプします。 【具体例】

    // 1〜100の整数の内、偶数だけの和を求めます。
    int total = 0;
    for( int i = 1; i <= 100; i ++ )
    {
        if( i % 2 != 0 )
            continue;       // 奇数なら以後の処理を行わず次のループを行う

        total = total + i;
    }

ジャンプ goto
指定したラベルの位置へ無条件にジャンプします。 多用するとソースコードが読み辛くなるので注意が必要ですが これほどストレートで解りやすい文はありません。 注意点としては gotoでジャンプする先のラベルは gotoと同じスコープ内に記述されていなければなりません。 ですので、無論、gotoで関数やクラスを跨ぐようなジャンプはできません。 【書式例】

    goto ラベル名;

    ラベル名:

【深いネストを一気にジャンプして抜ける例】

    public void Sample()
    {
        for( int x = 0; x < 10; x ++ )
        {
            for( int y = 0; y < 10; y ++ )
            {
                for( int z = 0; z < 10; z ++ )
                {
                    bool err = Func( x, y, z );

                    // エラーが発生したら一気に全ループを脱出
                    if( err )
                        goto FINISH;
                }
            }
        }

    FINISH:
        終了処理など
    }

メソッドから戻る return
任意の位置でメソッドから抜け、呼び出し元へ戻ります。 関数の終わりを示す閉じ括弧 } でも呼び出し元へ戻りますが、 任意の位置でメソッドから戻りたい場合や 呼び出し元へ何らかの結果(戻り値)を返したい場合に用います。 【書式例】

    1.void型の関数から戻る場合(値なし)

        public void Func()
        {
            中略

            return;
        }

    2.戻り値が必要な関数から戻る場合(値あり)

        public int Func()
        {
            中略

            return 0;
        }





Copyright © 2008.07 - shougo suzaki