本課題は渡辺先生の作成した「応用理工情報処理」(金曜クラス)のテキストをもとに改訂したものです。
渡辺先生に感謝!
今回(第3回)から第5回まででC言語のプログラムの流れを変更するフロー制御を扱います。C言語のフロー制御には
条件が成立するかどうかによってプログラムの流れを変える「条件分岐」
特定の処理を繰り返す「繰り返し処理」
強制的にプログラムの流れを変える「goto」
があります。今回は、この中の「条件分岐」を勉強します。条件分岐には 2 種類あります。一つが if、もう一つが switch です。それでは、勉強していきましょう。
条件分岐を理解するためには、条件を記述する方法を知らなければいけません。それが「条件式」です。条件式は等号 (==) や不等号(<, >) などを組み合わせた「式」であり、式自体が値を持ちます。
式で示された 条件が成立する場合、その式の値は0以外の値となり、条件が成立しない場合は0になります。(ここで、0 はC言語で「偽」という論理値を表すための数字です。C言語の使用では「論理値「真」は0以外の数字とする」と定められており、実際にどの数字が用いられるかはC言語の処理系によって異なります。
たとえば、式 (5 == 5) の値は0以外(真)になります。また、(3 < 1) の値は0 (偽)になります。この様に、2つの値の関係を表現する演算子には以下があります。
== 等号。C言語では "=" は等号ではなく代入演算子なので注意。
>, < 不等号。
>= 数学の ≧ と同じです。
<= 数学の ≦ と同じです。
!= not equal。数学の≠と同じです。
また、幾つかの条件式を組み合わせるための演算子も存在します。
&& AND 演算子。(条件式 1) && (条件式2) は、条件式1, 2 が両方成り立つ場合のみ真となります。
|| OR 演算子。(条件式 1) || (条件式2) は、条件式1, 2 のどちらかが成り立てば真となります。
例えば、(1 == 3) || (5 != 3) は真 (0以外)になります。
実は、条件式は上記以外のどんな式でもかまいません。例えば、(8-3-5) の値は0ですから、これは「偽」を表す条件式。(5+3) の値は8ですから、これは「真」を表す条件式、ということになります。
代入演算子 = を用いた式も通常の数式と同じように値を持ちます。例えば int 型変数を x として、x = 5 という式は x に5を代入すると同時に、式としても5という値を持ちます。このため、y = x = 5 という式を書くことができます。(まず、x に 5が代入され、その後、y に (x = 5) の値、つまり、5が代入されます。
もし何々ならば何々するという構文です。以下のように使います。
if (条件式)
{
コードブロック1
}else{
コードブロック2
}
この場合、条件式が真であればコードブロック1 を実行し、偽であればコードブロック2 を実行します。
ここで、コードブロックというのは { } で囲まれたC言語の式や命令のかたまりです。
単一の式の値によって幾つかの候補のうち一つのフローに分岐させたいときに使います。
switch (式) {
case 定数1:
文1; /* 式の値が定数1と一致すれば文1が実行される。*/
break; /* break がると、そこで switch 文から外に出る。 */
case 定数2:/* break;が無ければ次のcaseの文も実行される。*/
文2;
break; /* break;に出会うとswitch文を終了する{ }の外まで飛ぶ。*/
default :/* どのcaseの定数とも一致しないときはここに飛ぶ。省略可。*\
文3;
break;
}
テキスト p. 42, List 3-1 のプログラムを実行してみて下さい。
/* 読み込んだ整数値は5で割り切れないか */
#include <stdio.h>
int main (void) {
int vx;
printf("整数を入力してください:");
scanf("%d", &vx);
if (vx % 5)
{
puts("その数は5で割り切れません。");
}
return (0);
}
if の条件式の中に出てくる演算子 % は余りを求める演算子です。例えば、7 % 3 であれば、7÷3 のあまり、つまり、1が式の値になります。ここで、if の条件式が vx % 5 であることに注目して下さい。vx % 5 が 0 以外つまり「真」であるときだけ、{ } の中のコードが実行されます。
条件式では、上記の関係演算子や論理演算子を用いて様々な条件判断を行います。以下のようなプログラムでいろいろ試してみてこれらの使い方をマスターしましょう。
#include <stdio.h>
int main (void)
{
int vx = 5;
if (vx < 5)
puts("条件式は真(True)です");
return (0);
}
※ ここでは、if の後のコードブロックを囲む { } が省略されています。この例のように、コードブロックの中の命令や式(この場合は puts(...); )が一つだけの場合は { } を省略することができます。
#include <stdio.h>
int main (void)
{
int vx = 5;
if (vx < 5 || vx > 5) /* ||は"または"という意味で、&&は"かつ"という意味の論理演算子です。*/
puts("条件式は真(True)です");
return (0);
}
if文で、Falseのときも何か実行したいときにはelseを使います。テキストp. 44, List 3-3のプログラムで確認しましょう。
/* 読み込んだ整数値は5で割り切れないか割り切れるか */
#include <stdio.h>
int main (void)
{
int vx;
printf("整数を入力してください:");
scanf("%d", &vx);
if (vx % 5)
puts("その数は5で割り切れません。");
else
puts("その数は5で割り切れます。");
return (0);
}
if 文で多数に分岐する場合は、下のプログラム(テキスト p. 44, List 3-9)のように else if を用いて行います。
/* 読み込んだ整数値の符号を判定 */
#include <stdio.h>
int main (void)
{
int no;
printf("整数を入力してください:");
scanf("%d", &no);
if (no == 0)
puts("その数は0です。");
else if (no > 0)
puts("その数は正です。");
else
puts("その数は負です。");
return (0);
}
このように続けていけばいくらでも条件分岐できますが、それではプログラムが読みにくくなるので、一定の条件での多重分岐には次のswitch文を使用します。
練習4: switch
テキスト p. 65, List 3-19 のプログラムを実行してみよう。
/* 読み込んだ整数値を3で割った剰余を表示(switch文) */
#include <stdio.h>
int main (void)
{
int num;
printf("整数を入力してください:");
scanf("%d", &num);
switch (num % 3)
{
case 0 :
puts("その数は3で割り切れます。");
break;
case 1 :
puts("その数を3で割った余りは1です。");
break;
case 2 :
puts("その数を3で割った余りは2です。");
break;
}
return (0);
}
switch文で注意する点は以下の二点です。
条件判断の制御式の型は整数でなければならないこと、
break;文が無いと次の文が実行されること、です。
if (a)
b;
else
c;
というコードは、a ? b : c; という形で簡潔に表現することが可能です。次のプログラム (p. 56, List 3-14) で確認してみましょう
/* 読み込んだ二つの整数値の大きい方の値を求めて表示(条件演算子) */
#include <stdio.h>
int main (void)
{
int n1, n2, max;
puts("二つの整数を入力してください。");
printf("整数1:");
scanf("%d", &n1);
printf("整数2:");
scanf("%d", &n2);
max = (n1 > n2) ? n1 : n2; /* 大きい方の値をmaxに代入 */
printf("大きい方の値は%dです。\n", max);
return (0);
}
3つの整数値をキーボードから読み込んで、その最大値を表示するプログラムを作成せよ。(数値を比較する場合は2つの数値の間の比較となるため、最大値を明らかにするには2回比較する必要があります。)
(実行例)
整数1:3
整数2:5
整数3:9
最大値は9です。
何月かを整数値として読み込んで、その季節を表示するプログラムをswitch文を用いて作成せよ。(List 3-17とList 3-20参照。)
(実行例)
今は何月ですか?:10
季節は秋ですね。