++C++; // 未確認飛行 C

Google
Web ufcpp.net

条件分岐

目次

キーワード

概要

プログラム中で、ある条件を満たしたときだけ処理の流れを変えたい場合があります。 このような処理を条件分岐といい、 C#では条件分岐のために ifelseswitch などのキーワードを用意しています。

if 文

if 文は以下のような書き方をします。

if(条件式)
  文1 // 条件式が真のときに実行される
else
  文2 // 条件式が偽のときに実行される

if 文は if の後の括弧内に書かれた条件式の真偽によって処理の流れを変えます。 条件式が真のときには 文1 が、偽のときには 文2 が実行されます。 また、else から後ろの部分は省略することができます。

サンプル

using System;

class IfSample
{
  public static void Main()
  {
    // 整数を入力してもらう
    int x;
    Console.Write("整数を入力してください : ");
    x = int.Parse(Console.ReadLine());

    if(x == 0)
    {
      // 0が入力された場合、エラーメッセージだけ表示
      Console.Write("0が入力されました");
    }
    else
    {
      // 0以外が入力された場合、入力された数値の逆数を求めて表示
      double x_inv = 1.0 / x;
      Console.Write("1/{0} = {1}", x, x_inv);
    }
  }
}
整数を入力してください : 4
1/4 = 0.25
整数を入力してください : 0
0が入力されました

switch 文

switch 文は以下のような書き方をします。

switch(変数)
{
  case 値1:
    いくつかの文1 // 変数の値 == 値1 のとき実行される
    break;
  case 値2:
    いくつかの文2 // 変数の値 == 値2 のとき実行される
    break;
      ・
      ・
      ・
  default:
    いくつかの文 // 変数の値がどの値とも異なるとき実行される
    break;
}

switch の後ろの括弧に書かれた変数の値によって処理の流れを変えます。 switch 中で使える変数は、整数型もしくは文字列型の変数のみです。

そして、case の後ろに条件となる値を書きます。 変数の値が case で指定されたどの値とも異なる場合、 default というラベルのついた場所に処理の流れが移ります。 break は switch 文から抜けるために使います。

フォールスルーの禁止

C# の先祖に当たる C 言語や C++ 言語では、 以下のようなコードが許されていました。

swicth(x)
{
case 1:
  printf("x == 1 のときに実行される\n"); // (1)
case 2:
  printf("x == 1 でも x == 2 でも実行される\n"); // (2)
}

変数 x が 1 のとき、(1) と (2) の両方の行が実行されます。 x が 2 のときには (2) だけが実行され、 それ以外の場合は何も実行されません。 すなわち、C/C++ では、switch 文中の case ラベルを超えてコードが実行され、 このような動作をフォールスルー(fall through)と呼びます。

ですが、実際にプログラムを作る際、多くの場合では、 x が 1 のときと 2 のときで、 全く別の処理をしたい、すなわち、 フォールスルーして欲しくない場合がほとんどで、 以下のように、braek を挿入して、 case ラベルを超えてコードが実行されないようにします。

swicth(x)
{
case 1:
  printf("x == 1 のときだけ実行される\n");
  break;
case 2:
  printf("x == 2 のときだけ実行される\n");
  break;
}

で、C/C++ では、 「フォールスルーして欲しくないのに、ついうっかり break を忘れる」 というバグが結構頻繁に起こりました。 そのため、C# ではフォールスルーを禁止しています。 すなわち、C# では、 case ラベル毎に必ず、break, goto, 戻り値 のいずれかを記述する必要があります。

毎回いちいち break を書くのが面倒ですが、必ず書く必要があります。 C/C++ 時代の名残です。

(「どうせフォールスルーできないんだから、break を明示的に書かなくてもフォールスルーしない仕様にして欲しい」という要望も多かったりします。 C# は C/C++ からの移行を意識して作られたので、 C/C++ プログラマの混乱を避けるために break を付ける構文になったんだと思います。 C# でプログラミングを始める人もちらほら出始めてきた今となっては少々気持ち悪い構文です。 )

ただし、C# でも、以下のように、case ラベルが連続している場合に限りフォールスルー可能で、 break 等が必須ではありません。

switch(x)
{
  case 1:
  case 2:
    Console.Write("x == 1 か x == 2 のときに実行される\n");
    break;
    // case ラベルが連続している場合のみ OK。
    // case 1: と case 2: の間にコードを書いては駄目。
}

サンプル

using System;

class SwitchSample
{
  public static void Main()
  {
    // 整数を2つ入力してもらう
    int x, y;
    Console.Write("1つ目の整数を入力してください : ");
    x = int.Parse(Console.ReadLine());
    Console.Write("2つ目の整数を入力してください : ");
    y = int.Parse(Console.ReadLine());

    // + - / * のいずれかを入力してもらう
    char op;
    Console.Write("行いたい操作を入力してください(+ - / *) : ");
    op = Console.ReadLine()[0];

    switch(op)
    {
      case '+':
        Console.Write("{0} + {1} = {2}", x, y, x+y);
        break;
      case '-':
        Console.Write("{0} - {1} = {2}", x, y, x-y);
        break;
      case '*':
        Console.Write("{0} × {1} = {2}", x, y, x*y);
        break;
      case '/':
        if(y != 0)
          Console.Write("{0} ÷ {1} = {2} … {3}", x, y, x/y, x%y);
        break;
      default:
        Console.Write("対応していない操作です");
        break;
    }
  }
}
1つ目の整数を入力してください : 5
2つ目の整数を入力してください : 7
行いたい操作を入力してください(+ - / *) : +
5 + 7 = 12
1つ目の整数を入力してください : 11
2つ目の整数を入力してください : 3
行いたい操作を入力してください(+ - / *) : /
11 ÷ 3 = 3 … 2
1つ目の整数を入力してください : 1
2つ目の整数を入力してください : 1
行いたい操作を入力してください(+ - / *) : 0
対応していない操作です

goto 文

goto 文は if 文や switch 文と異なり、無条件に処理の流れを変えるものです。 例えば以下のように使います。

START: // ジャンプ先を示すラベル
Console.Write("gotoの例");
goto START;// START: というラベルのある位置に処理の流れを移す

この例では、Console.Write("gotoの例");が何度も繰り返し実行されます。 (プログラムを強制終了するしか止める方法がないので注意)

goto 文を使用するとプログラムの処理の流れを追いづらくなるので、あまり使うのは好ましくないとされています。 そのため、通常は goto 文を使うのは以下のような場合に限られます。

1つは以下のように、switch 文で、x の値が1のときも2の時も同じ処理を行いたいといった場合に使います。

switch(x)
{
  case 1:
    goto case 2; // gotoを使って処理を移す
  case 2:
    // x の値が1か2だった場合の処理
    break;
  case 3:
    // x の値が3だった場合の処理
    break;
  default:
    // そのほかの場合の処理
    break;
}

もう1つ、以下のように多重ループ(ループについては 「反復処理」 で説明します)から抜け出すときにも使います。

while(x != 0)
{
  while(y != 0)
  {
    // 繰り返し行いたい処理

    if(x == y)
      goto LOOPEND; // break では while(y != 0) の方のループしか抜けられない
  }
}
LOOPEND:
;

演習問題

問題 1

ユーザから入力された整数が奇数か偶数か判定するプログラムを作成せよ。

解答

問題 2

組込み演算子問題 5のプログラムを修正し、 BMI 値から体型(やせ型、普通、やや肥満、肥満、高度肥満)を判定し、 表示するプログラムを作成せよ。

解答

問題 3

switch 文を使って150以下の平方数(4=2×2、9=3×3、16=4×4というように、ある整数の二乗になっている数)を判別するプログラムを作成せよ。 ユーザに整数値を1つ入力してもらい、 判別結果を出力するものとする。

ヒント: 要するに、ユーザからの入力が 1, 4, 9, 16, ・・・になっているかどうかを switch 文で判別します。

解答

問題 4

数値を3つ入力してもらい、 その3つの値の中の最大値、最小値を求めるプログラムを作成せよ。

解答

Transtation into English

[お問い合わせ](q)