C Language
選択ステートメント
サーチ…
if()ステートメント
プログラムフローを制御する最も簡単な方法の1つは、 if
文を使用if
ことです。この文でコードのブロックを実行するかどうかを決定することができます。
Cのif
選択文の構文はif
次のようになります。
if(cond)
{
statement(s); /*to be executed, on condition being true*/
}
例えば、
if (a > 1) {
puts("a is larger than 1");
}
ここでa > 1
は、 if
ブロック内のステートメントを実行するためにtrue
と評価する必要がある条件です。この例では、 "a is greater than 1"は、 a > 1
場合にのみ出力されます。
if
選択ステートメントは包装中括弧を省略することができ{
と}
ブロック内の唯一のステートメントがある場合。上記の例は、次のように書き直すことができます。
if (a > 1)
puts("a is larger than 1");
しかし、ブロック内で複数のステートメントを実行するには、中括弧を使用する必要があります。
if
の条件には、複数の式を含めることができます。 expressionの最終結果がtrueのif
にのみアクションを実行します。
例えば
if ((a > 1) && (b > 1)) {
puts("a is larger than 1");
a++;
}
a
とb
両方が1
より大きい場合にのみ、 printf
とa++
実行します。
if()... elseステートメントと構文
一方でif
、その条件はと評価された場合にのみアクションを実行true
、 if
/ else
あなたは時に条件の異なるアクションを指定することができますtrue
と条件があるときfalse
。
例:
if (a > 1)
puts("a is larger than 1");
else
puts("a is not larger than 1");
if
文のif
と同様に、 if
またはelse
中のブロックが1つの文で構成されているif
、中括弧は省略できます(しかし、そうすることは、不注意で簡単に問題を引き起こす可能性があるため推奨しません)。 if
またはelse
ブロック内に複数のステートメントがあるif
は、その特定のブロックで中括弧を使用する必要があります。
if (a > 1)
{
puts("a is larger than 1");
a--;
}
else
{
puts("a is not larger than 1");
a++;
}
switch()ステートメント
switch
文は、プログラムが特定のテスト変数の値に応じて多くの異なることをしたいときに便利です。
switch
文の使用例は次のようになります:
int a = 1;
switch (a) {
case 1:
puts("a is 1");
break;
case 2:
puts("a is 2");
break;
default:
puts("a is neither 1 nor 2");
break;
}
この例は、
int a = 1;
if (a == 1) {
puts("a is 1");
} else if (a == 2) {
puts("a is 2");
} else {
puts("a is neither 1 nor 2");
}
switch
文が使用されているときにa
の値が1の場合、 a is 1
が出力されます。値場合、次に2であり、 a
a is 2
印刷されます。それ以外の場合a is neither 1 nor 2
も印刷されa is neither 1 nor 2
。
case n:
switch
文に渡された値がnのときに実行フローがどこにジャンプするかを記述するために使用されます。 nはコンパイル時定数でなければならず、同じnが最大でも1つのswitch
文に存在することができます。
default:
値は、値がcase n:
いずれの選択肢とも一致しなかったことを記述するために使用されdefault:
。予想外の動作を検出するには、すべてのswitch文にdefault
caseを含めることをお勧めします。
break;
switch
ブロックから飛び降りるにはステートメントが必要です。
注意: case
の終了後にbreak
を追加することを誤って忘れてしまったcase
、コンパイラは「フォールスルー」し、その後に続くすべてのcase文が実行されると想定します( break文が後続のケースステートメントが一致するかどうかにかかわらず、後続のケースのいずれか)。この特定のプロパティは、 Duffのデバイスを実装するために使用されます。この動作は、しばしばC言語仕様の欠陥と見なされます。
以下は、 break;
効果を示す例break;
:
int a = 1;
switch (a) {
case 1:
case 2:
puts("a is 1 or 2");
case 3:
puts("a is 1, 2 or 3");
break;
default:
puts("a is neither 1, 2 nor 3");
break;
}
a
の値が1または2のとき、 a is 1 or 2
、 a is 1, 2 or 3
両方を出力します。 a
が3のときはa
のみa is 1, 2 or 3
が印刷されます。それ以外の場合、 a is neither 1, 2 nor 3
印刷されa is neither 1, 2 nor 3
。
default
ケースは必要ではないことに注意してください。特に、 switch
取得した値のセットが完了し、コンパイル時に判明している場合は注意してください。
最も良い例は、 enum
switch
を使用するswitch
です。
enum msg_type { ACK, PING, ERROR };
void f(enum msg_type t)
{
switch (t) {
case ACK:
// do nothing
break;
case PING:
// do something
break;
case ERROR:
// do something else
break;
}
}
これには複数の利点があります。
- ほとんどのコンパイラは値を処理しないと警告を出力します(
default
場合は報告されません) - 同様の理由から、
enum
新しい値を追加すると、新しい値を処理するのを忘れた場所がすべて通知されます(default
場合は、そのような場合を手動で検索する必要があります) - 読者は、「
default:
隠されているものdefault:
」、他のenum
値があるかどうか、または「ちょうどの場合」の保護であるかどうかを把握する必要はありません。また、他のenum
値がある場合、コーダーは意図的にdefault
大文字小文字を使用しましたか、値を追加したときに導入されたバグがありますか? - ワイルドカードの背後に隠れることができないので、各
enum
値を処理することで、コードを自明にすることができます。それぞれを明示的に処理する必要があります。
それにもかかわらず、誰かが次のような邪悪なコードを書くのを防ぐことはできません:
enum msg_type t = (enum msg_type)666; // I'm evil
したがって、本当に必要な場合は、スイッチの前に余分なチェックを追加して検出することができます。
void f(enum msg_type t)
{
if (!is_msg_type_valid(t)) {
// Handle this unlikely error
}
switch(t) {
// Same code than before
}
}
if()... else else複数のif()... elseステートメントを連結する
if ()... else
ステートメントは、 if ()
内の条件が満たされないif ()
発生する1つの(デフォルト)動作を定義することができますが、2つ以上のif () ... else
ステートメントを連鎖させると、もしあれば、 "default"として動作する最後のelse
ブランチに行く前に、より多くの振る舞いをします。
例:
int a = ... /* initialise to some value. */
if (a >= 1)
{
printf("a is greater than or equals 1.\n");
}
else if (a == 0) //we already know that a is smaller than 1
{
printf("a equals 0.\n");
}
else /* a is smaller than 1 and not equals 0, hence: */
{
printf("a is negative.\n");
}
入れ子になったif()... else VS if().. else Ladder
ネストされたif()...else
ステートメントは、 if()...else
ステートメントのネストされたif()...else
ステートメントが内部の条件文をすべてチェックしてから、 if()...else
ラダーと比較して実行時間が長くなります条件付きif()
文が満たされますが、 if()
またはelse if()
条件文のいずれかがtrueになると、 if()..else
ラダーは条件テストを停止します。
if()...else
ラダー:
#include <stdio.h>
int main(int argc, char *argv[])
{
int a, b, c;
printf("\nEnter Three numbers = ");
scanf("%d%d%d", &a, &b, &c);
if ((a < b) && (a < c))
{
printf("\na = %d is the smallest.", a);
}
else if ((b < a) && (b < c))
{
printf("\nb = %d is the smallest.", b);
}
else if ((c < a) && (c < b))
{
printf("\nc = %d is the smallest.", c);
}
else
{
printf("\nImprove your coding logic");
}
return 0;
}
一般的なケースでは、等価な入れ子のif()...else
よりも優れていると考えられif()...else
:
#include <stdio.h>
int main(int argc, char *argv[])
{
int a, b, c;
printf("\nEnter Three numbers = ");
scanf("%d%d%d", &a, &b, &c);
if (a < b)
{
if (a < c)
{
printf("\na = %d is the smallest.", a);
}
else
{
printf("\nc = %d is the smallest.", c);
}
}
else
{
if(b < c)
{
printf("\nb = %d is the smallest.", b);
}
else
{
printf("\nc = %d is the smallest.", c);
}
}
return 0;
}