4.
分岐処理
分岐処理
・*:..☆ プロローグ ☆..:*・
「まったく、カメさんもどういうつもりなんだか。別に歩くのが遅いのを批判したわけじゃないんだよ。そんなの個性だからね。ちょっと歩く速さを話題にしただけなんだから、そんなに向きにならなくてもいいと思うんだけどな。ついつい受けてしまったけど、こんなレースは僕にとって何の意味もないんだ。カメさんに勝ったって自慢にはならないからね。あ~あ、やっぱり断るんだったかな。」
ぶつぶつ言いながらも、山のふもとを目指して快走するウサギさんです。だが、突然、立ち止まりました。そこは分岐点でした。目の前の道は右と左に分かれており、その間には標識が立っていました。
------------------------
お急ぎの方は左へ → ちょっとだけ近道です
そうでない方は右へ → 休憩所がございます
どちらの道も山のふもとに続いています
------------------------
「まいったな。これ絶対、カメさんのトラップだぜ。休憩所っていうのが怪しそうだ。う~ん、どうしようかな~、えーとー、まあ、カメさん相手に急いでいるわけでもないし、ここは標識に従って右の道を選ぶとするか。どんなトラップか見てみたいし、それにトラップを避けてカメさんに勝ったところで面白くもなんともない。」
ウサギさんは右の道を駆けていきました。今までは少し退屈そうに走っていたウサギさんでしたが、標識を見てからは楽しそうな表情になりました。
それからしばらくして、カメさんが分岐点にやってきました。
「どれどれ、足跡を見る限りでは、ウサギさん右の道を選んでくれたみたいだな。長い付き合いだから性格は知ってるさ。ちょうど今頃はウサギさんのお昼寝タイムだからね。ふかふかの穴型ベッドを見たら入らずにはいられないだろう。その間に近道で追い越せるはずさ。これでタヌキさんとの賭けは僕が有利になったと思っていいかな。タヌキさん、1対100でウサギさんに賭けるなんて言うんだもの。一儲けできると思ったら、多少、無理しても勝ちたいさ。」
C言語のプログラムは記述した順に処理が実行されます。
- 起きる
- 朝食を食べる
- 学校に行く
- 家に帰る
と記述すれば、『まず、起きて、次に朝食を食べ、それから学校に行き、家に帰る』のように行われます。決して、起きる前に朝食を食べるようなことはありません。学校に行かないこともありませんし、家に帰らないこともありません。
しかし、多くの場合、それだけでは目的の機能を実現できません。『場合によっては、学校ではなく、遊びに行く』、『場合によっては、ジョギングをする』といったことも必要になるのです。
この、『場合によっては、』をプログラムで実現する事を、分岐処理と言います。
分岐と言うと、例えば、道が分岐していて、片方の道を行けば海へ、もう片方の道を行けば山へ、と、行き先が全く違っているような状況が想像できますが、C言語の場合はそうではなく、それほど遠くない地点で1本の道に合流します。つまり、行き先は決まっていて、寄り道をする、あるいは、通る道を選択するといった感じです。
4.1. if 文
if 文
それでは、分岐処理を加えてみましょう。
- 起きる
- 朝食を食べる
- 休日であれば、遊びに行く、そうでなければ、学校に行く
- 家に帰る
ここで 3 行目、『休日であれば…』が分岐処理です。前述の通り、分岐があっても元の道に戻りますから、4 行目の『家に帰る』は必ず実行されます。
では、これに C言語の書式を加えてみましょう。次のようになります。
- 起きる
- 朝食を食べる
-
if ( 休日であれば )
遊びに行く
else
学校に行く
- 家に帰る
3 行目の“if”と“else”が if 文という分岐処理のキーワードです。
if に続く小カッコ ( ) 内に記述された分岐条件を満たす場合、if ( ) の次に記述された文が実行されます。分岐条件を満たさない場合には else の次に記述した文が実行されます。
この場合、休日には遊びに行き、他の日には学校に行きます。
else の省略
else の省略
次のようなことを実現するには、どうすればよいでしょうか。
- 起きる
- 朝食を食べる
- 8時前であれば、ジョギングをする
- 学校に行く
前の例と違うのは、“そうでなければ”が、無いところです。
これに、C言語の書式を加えると次のようになります。
- 起きる
- 朝食を食べる
- if ( 8時前であれば )
ジョギングをする
- 学校に行く
この例では、“そうでなければ”に相当する“else”がありません。elseは 省略できるのです。
朝食後、8時前であればジョギングをするのですが、8時を過ぎていればジョギングをしないで学校に行くことになります。
ブロック
ブロック
分岐条件を満たした場合に、複数の文を実行するには、どうしたら良いでしょうか。
- 起きる
- 朝食を食べる
- 休日であれば、テレビを見る、そして、遊びに行く
このような場合には、波カッコ { } を使用して複数の文をまとめたブロックとします。ブロックは1つの文とみなされます。
- 起きる
- 朝食を食べる
-
if ( 休日であれば )
{
テレビを見る
遊びに行く
}
ブロック化は、if 文だけではなく、他の制御構文でも使用されます。また、関数の定義で使用する波カッコ { } もブロックと考えられます。
条件式
条件式
それでは、C言語の実際のコードを見てみましょう。
if( x > y )
printf( "xはyより大きい。\n" );
x と y は int 型の変数で、何らかの値が代入されているものとします。
ここで、if に続く小カッコ( )の中、“x > y”の部分を条件式と言います。
“>”演算子は関係演算子と呼ばれ、数学の記号と同様、“左辺は右辺より大きい”と言う意味ですので、『 x は y より大きい』ということを表しています。数学と違うのは、x は y より大きい、ということを述べているのではなく、x は y より大きいかどうか、であることです。
この部分のコードが実行されると、実際に x が y よりも大きいかどうかが確かめられます。これを、評価する、と言います。
条件式を評価した結果は 0 か 1(非0)で得られます。x が y よりも大きい場合には 1、そうでなければ 0 が得られます。
if 文は、小カッコ ( ) 内の式が0でなければ、続く文を実行します。
0 と 0 以外
0 と 0 以外
多くのプログラム言語にはブール型(Boolean)があります。C言語でも C99 規格では _Bool 型が導入されています。
ブール型は真(True)と偽(False)のどちらかの値を持ちます。
“x > y”のような条件式を評価した結果は、x が y より大きい(真)、または、そうではない(偽)の、どちらかとなるので、ブール型として得られる事が合理的です。
しかし、C99 以前の C言語ではブール型がありません。そこで、0 と 0 以外が、偽と真を表すことになっています。0 であれば偽、0 以外であれば真に対応します。
これは、次のプログラムで確認できます。
int x = 13;
int y = 3;
printf( "%d\n", x > y );
次のプログラムでは、if 文の式に、0 か 0 以外の定数を書き込んでいます。
if( 0 )
printf( "条件を満たしている\n" );
else
printf( "条件を満たしていない\n" );
if ( 0 ) の場合には“条件を満たしていない”と出力されます。
if ( 123 ) と記述した場合には、123 は 0 以外なので“条件を満たしている”と出力されます。
if 文のまとめ
if 文のまとめ
if 文は次のような書式です。
if( 式 )
文
else
文
- 式が 0 でなければ、if ( ) に続く文を実行します。
- 式が 0 であれば、else に続く文を実行します。
- else 以降は省略できます。
式には“x > y”のような条件式が用いられることが多いのですが、0 か 0 以外が得られる式であれば、どのような式でもかまいません。定数を書くことも出来ます。
else if
else if
if 文によって制御される文は、代入、演算、関数呼び出しのような処理だけではなく、制御文とすることも出来ます。もちろん、別の if 文であってもかまいません。
これは、他の制御文でも同様です。
以下は、if 文を組み合わせた例です。
if( 式 A )
文 A
else
if( 式 B )
文 B
else
if( 式 C )
文 C
else
文 D
このプログラムは、次のような処理をします。
- 式 A を評価し、真であれば 文 A を実行する。
- そうでなければ、式 B を評価し、真であれば 文 B を実行する。
- そうでなければ、式 C を評価し、真であれば 文 C を実行する。
- そうでなければ、式 D を実行する。
全く同じプログラムで、改行と字下げを以下のように変えます。
if( 式 A )
文 A
else if( 式 B )
文 B
else if( 式 C )
文 C
else
文 D
“else if”が1組になっているように見えないでしょうか。処理の意味は“そうでなければ、式を評価し、真であれば文を実行する”です。
改行、字下げは、コードを見やすくする為に重要であり、共通のルールに従って行うべきものですが、if 文の組み合わせに限っては、このように変形させる書き方が多く用いられます。
4.2. 関係演算子と論理演算子
関係演算子と論理演算子
関係演算子と論理演算子は、条件式に使用されることが多い演算子です。
関係演算子
関係演算子
関係演算子は、2つの項の関係を表すものです。評価した結果は、関係が正しければ 1、正しくなければ 0 になります。
==
|
左辺と右辺が等しい |
!=
|
左辺と右辺が等しくない |
<、>、<=、>=
|
左辺と右辺の大小比較 <=、>= は ≦、≧ と同様に、= を含む
|
論理演算子
論理演算子
論理演算、“かつ(AND)”、“または(OR)”、“否定(NOT)”を実行します。“かつ”、と、“または”は二項演算子で、“否定”は単項演算子です。
&&
|
かつ(AND) 左辺、右辺とも真の場合に真、それ以外は偽
|
||
|
または(OR) 左辺、右辺のどちらかが真の場合は真、それ以外は偽
|
!
|
項が真の場合は偽、偽の場合は真 |
使用例
使用例
以下に、関係演算子と論理演算子の使用例を示します。
優先して評価したい演算には小カッコ ( ) を使用します。
x > 10 && x < 100
|
x は 10 より大きく、かつ、100 より小さい |
x == 3 || x == 4
|
x は 3 または 4 である |
x == 0 || ( y > 0 && y < 10 )
|
x が 0 である、または、y は 0 より大きく10 より小さい |
!( x == 3 )
|
x は 3 である、の否定( x は 3 ではない)
|
次のような記述には注意してください。
0 < x < 10
x は 0 より大きく 10 より小さい、という条件式のつもりであるとすれば、正しい結果は得られません。まず、0 < x が評価され、0 か 1 が得られます。次に、その 0 か 1 が 10 より小さいかどうかが調べられるので、常に真となってしまいます。
正しい結果を得たいのであれば、次のように記述しなければなりません。
0 < x && x < 10
4.3. switch 文
switch 文
分岐処理を実現するための、もう1つの構文です。
季節が、春、夏、秋、冬の何れかによって処理が分岐するものとしましょう。
switch 文を使用して書くと、次のようになります。
switch( 季節 ){
case 春:
入学式
case 夏:
林間学校
case 秋:
文化祭
case 冬:
クリスマス
}
switch に続く小カッコ ( ) 内に、整数が得られるテスト式を記述します。この式は、以降の行の case と比較する元となるものです。
“case”キーワードの右側には、テスト式と照合する定数値を記述します。case 以降に実行する文を記述します。
テスト式に一致する case の定数値が存在すると、それ以降に記述されている文が実行されます。
各季節で実行される文は、次のとおりです。
- 春:入学式、林間学校、文化祭、クリスマス
- 夏:林間学校、文化祭、クリスマス
- 秋:文化祭、クリスマス
- 冬:クリスマス
case の直後の文だけが実行される、ということではありませんから注意してください。
それではこれを実際のコードにしてみましょう。
変数 season は int 型で、1 から 4 までの数値が代入されていて、1 は春、2 は夏、3 は秋、4 は冬に対応しているものとします。
switch( season ){
case 1:
printf( "入学式\n" );
case 2:
printf( "林間学校\n" );
case 3:
printf( "文化祭\n" );
case 4:
printf( "クリスマス\n" );
}
case の定数値のいずれにも一致しない場合、実行される文はありません。
case の直後に文を置かず、続けて case を書くことも出来ます。
switch( season ){
case 1:
case 2:
printf( "前期\n" );
case 3:
case 4:
printf( "後期\n" );
}
break
break
break 文は、switch 文から抜け出すための手段です。break 文が実行されると、それ以降の文を実行せずに switch 文を抜けます。
switch( season ){
case 1:
printf( "三、四、五月です\n" );
break;
case 2:
printf( "六、七、八月です\n" );
break;
case 3:
printf( "九、十、十一月です\n" );
break;
case 4:
printf( "十二、一、二月です\n" );
break;
}
default
default default は、テスト式が、どの case にも一致しなかった場合の受け入れ先です。
switch( season ){
case 2:
printf( "冷房が必要です\n" );
break;
case 4:
printf( "暖房が必要です\n" );
break;
default:
printf( "過ごしやすい季節です\n" );
break;
}
switch文のまとめ
switch文のまとめ switch 文は次のような書式です。
switch( 式 ){
case 定数値:
文
break;
case 定数値:
文
break;
case 定数値:
文
break;
case 定数値:
文
break;
default:
文
break;
}
- switch の式に一致する case の定数値がある場合、それ以降の文を実行します。
- case の定数値に重複があってはいけません。
- case 以降に文が無くてもかまいません。
- 一致する case の定数値が無い場合には、default 以降の文が実行されます。
- default は無くてもかまいません。
- break が実行されると、switch 文を抜けます。