★分岐構造5★
では、前回の続きです。
処理を2つに分けるために「if−else」文を紹介しましたが、3つに分けるにはどうすれば良いかを考えます。
2つの整数「整数1」「整数2」を入力し、
「整数1」の方が小さければ、「整数1の方が小さいです。」
「整数1」の方が大きければ、「整数1の方が大きいです。」
2つの数が等しければ、「整数1と整数2は等しいです。」と表示するプログラムを考えてみてください。
新しい命令(制御文)を知らなければ出来ないことではありません。
まずは、皆さんで工夫してみてください。
解答例です。
<sample program 011-01>
#include <stdio.h>
int main( void )
{
int input1;
int input2;
printf( "整数1を入力してください:" );
scanf( "%d", &input1 );
printf( "整数2を入力してください:" );
scanf( "%d", &input2 );
if( input1 < input2 ) {
printf( "整数1の方が小さいです。\n" );
}
if( input1 > input2 ) {
printf( "整数1の方が大きいです。\n" );
}
if( input1 == input2 ) {
printf( "整数1と整数2は等しいです。\n" );
}
return 0;
}
|
<実行結果1 VC++ Express Edition>
整数1を入力してください:15
整数2を入力してください:23
整数1の方が小さいです。
続行するには何かキーを押してください・・・
<実行結果2 VC++ Express Edition>
整数1を入力してください:35
整数2を入力してください:23
整数1の方が大きいです。
続行するには何かキーを押してください・・・
<実行結果3 VC++ Express Edition>
整数1を入力してください:18
整数2を入力してください:18
整数1と整数2は等しいです。
続行するには何かキーを押してください・・・
if文を3つ並べれば出来ます。
では、もう1つ、同じような例ですが、
入力した整数が、
負の数であれば、「入力データは負の数です。」
正の数であれば、「入力データは正の数です。」
ゼロであれば、「入力データはゼロです。」
と表示するプログラムを作ってみましょう。
解答例です。
<sample program 011-02>
#include <stdio.h>
int main( void )
{
int input;
printf( "整数を入力してください:" );
scanf( "%d", &input );
if( input < 0 ) {
printf( "入力データは負の数です。\n" );
}
if( input > 0 ) {
printf( "入力データは正の数です。\n" );
}
if( input == 0 ) {
printf( "入力データはゼロです。\n" );
}
return 0;
}
|
<実行結果1 VC++ Express Edition>
整数を入力してください:-1
入力データは負の数です。
続行するには何かキーを押してください・・・
<実行結果2 VC++ Express Edition>
整数を入力してください:1
入力データは正の数です。
続行するには何かキーを押してください・・・
<実行結果3 VC++ Express Edition>
整数を入力してください:0
入力データはゼロです。
続行するには何かキーを押してください・・・
これも、if文3つで作れますね。
では、ここで「テスト」について読んでみてください。
では、次の段階に進みましょう。
次に作ってみるのは、「入力した整数が、0以上であり100以下の範囲内かどうか調べる」プログラムです。
結果はこんな感じで表示したいです。
<実行結果1 VC++ Express Edition>
整数を入力してください:50
入力データは0以上、100以下の範囲にあります。
続行するには何かキーを押してください・・・
<実行結果2 VC++ Express Edition>
整数を入力してください:150
続行するには何かキーを押してください・・・
まずは、皆さん考えてみてください。
間違い易い例をいくつか書いてみます。
<sample program 011-03>
#include <stdio.h>
int main( void )
{
int input;
printf( "整数を入力してください:" );
scanf( "%d", &input );
if( input >= 0 ) {
printf( "入力データは0以上、100以下の範囲にあります。\n" );
}
if( input <= 100 ) {
printf( "入力データは0以上、100以下の範囲にあります。\n" );
}
return 0;
}
|
<実行結果1 VC++ Express Edition>
整数を入力してください:-50
入力データは0以上、100以下の範囲にあります。
続行するには何かキーを押してください・・・
<実行結果2 VC++ Express Edition>
整数を入力してください:50
入力データは0以上、100以下の範囲にあります。
入力データは0以上、100以下の範囲にあります。
続行するには何かキーを押してください・・・
<実行結果3 VC++ Express Edition>
整数を入力してください:150
入力データは0以上、100以下の範囲にあります。
続行するには何かキーを押してください・・・
これだと、範囲外の数値を入力した時にも「範囲内」というメッセージが表示されていますし、
範囲内の数値を入力した時に「2回メッセージが表示」されます。
なぜ、こうなったのでしょうか。
これは、「0以上、100以下の範囲」という条件を良く考えなければなりません。
前に出てきた、「正」「負」「ゼロ」を調べるというプログラムでは、
「負の数」であれば、「正」や「ゼロ」の数では無い。
「正の数」であれば、「負」や「ゼロ」の数では無い。
「ゼロ」であれば、「負」や「正」の数では無い。
というように、どれかの条件が成立している場合、他の条件は成立できなかったのです。
数値の大小比較でも、
「整数1<整数2」であれば、「整数1>整数2」や「等しい」ということはありえません。
「整数1>整数2」であれば、「整数1<整数2」や「等しい」ということはありえません。
「等しい」のであれば、「整数1>整数2」や「整数1<整数2」ということはありえません。
同じことです。
ですが、今回の問題は違います。
「ゼロ以上の数値」でも「100より大きな数値」と「100以下の数値」があります。
「100以下の数値」にも「0以上の数値」と「0未満の数値」があります。
どちらか一方が「成立」しているだけでは、ダメなのです。
つまり、「入力した整数」が「0以上」「かつ」「100以下」でないといけません。
2つの条件が成立して初めて、やりたいことを実行出来るのです。
これを踏まえた上で、次の間違い易い例です。
#include <stdio.h>
int main( void )
{
int input;
printf( "整数を入力してください:" );
scanf( "%d", &input );
if( 0 <= input <= 100 ) {
printf( "入力データは0以上、100以下の範囲にあります。\n" );
}
return 0;
}
|
<実行結果1 VC++ Express Edition>
整数を入力してください:-50
入力データは0以上、100以下の範囲にあります。
続行するには何かキーを押してください・・・
<実行結果2 VC++ Express Edition>
整数を入力してください:50
入力データは0以上、100以下の範囲にあります。
続行するには何かキーを押してください・・・
<実行結果3 VC++ Express Edition>
整数を入力してください:150
入力データは0以上、100以下の範囲にあります。
続行するには何かキーを押してください・・・
これは、非常に多い間違いです。
考え方は分かるのですが、結果を見ると、何を入力しても範囲内となっています。
何が原因かというと、
「 0 <= input <= 100 」
この部分です。
数学等では、当たり前に使う書き方ですが、C言語では書けません。
「でも、コンパイルしてエラーにはなってないよね」
「実行も出来るし・・・・」
そうです。
だから、余計に「性質が悪い」のです。
エラーがでないから書けると思ってしまうのです。
現時点では、ただ単に書けないから間違いです!で終わってもいいのですが、
前に書いたことで、説明できますので、とりあえず説明しますね。
まず、「条件の表示」について書きました。
条件は、printf等で表示した場合、
「成立していれば、1」
「成立していなければ、0」
となります。
次に、「演算子の優先順位」について書いています。
演算子は、「左から」順に1つずつ計算するものや、「右から」順位1つずつ計算するものがあります。
例えば、「+」演算子が1行に3つ、4つあったとしても、計算は1つずつです。
では、これ「 0 <= input <= 100 」はどうでしょう?
「<=」演算子は、左から見ていきます。
ですから、まずは、( 0 <= input )が判断されます。
判断された結果、
「成立していれば、1」
「成立していなければ、0」
となります。これが「最初の結果」です。
次に、( 「最初の結果」 <= 100 )が判断されます。
「最初の結果」は「0」か「1」なので、これは必ず成立します。
つまり、どんな数値を入力しても、「成立」してしまうのです。
では、「2つ以上の条件が成立した時だけ処理を行う」プログラムはどうやって作るのでしょう。
解答例です。
<sample program 011-05>
#include <stdio.h>
int main( void )
{
int input;
printf( "整数を入力してください:" );
scanf( "%d", &input );
if( 0 <= input ) {
if( input <= 100 ) {
printf( "入力データは0以上、100以下の範囲にあります。\n" );
}
}
return 0;
}
|
<実行結果1 VC++ Express Edition>
整数を入力してください:-50
続行するには何かキーを押してください・・・
<実行結果2 VC++ Express Edition>
整数を入力してください:50
入力データは0以上、100以下の範囲にあります。
続行するには何かキーを押してください・・・
<実行結果3 VC++ Express Edition>
整数を入力してください:150
続行するには何かキーを押してください・・・
if文は「成立した時に処理を書く」欄があります。
そこに、if文を書くのです。
上のプログラムでは、「入力した整数が0以上の時」だけ「100以下かどうか」判断しています。
0未満の数値であれば「範囲外」ですから調べる必要がありません。
このように、if文の中にif文を書くことを「ネスト」とか「入れ子」と言います。
※ここでは「ネスト」と呼ぶことにします。
「ネスト」はif文だけに限ったことではありません。
ですから、今後も「この命令の中に同じ命令が書けるのではないか?」ということを
頭に置いていただければ、いろいろなことに気づくことが出来るでしょう。
次回は、今までにやった問題を「ネスト」を使った処理に変更して見ましょう。