確認問題 (これまでの内容がきちんと理解できていればすぐにできる問題です)
ガソリンを満タン給油する際、トリップメーター(距離計)をゼロにリセットし、次回ガソリン給油時に走行距離を給油量で割ることにより、その車の大体の燃費(ガソリン1リットルで何キロメートルはしることができるか)を計算することができる.走行距離と給油量を入力すると、燃費を計算し、結果を画面に表示するプログラムを作成せよ.
今日でてくる if 文や for, while 文ではブロック文と呼ばれるものが使われます.ブロック文とは、文を一まとめにしたもので、{ と } で囲まれています.
プログラムを作成していると、条件によって処理を分岐させたい場合がよく出てきます.例えば、先週の演習で出てきたサンプルプログラム(足し算を行うもの)を scanf をつかって、 a,b に入力を行うようにし、 a/b を求め表示するプログラムに変更することを考えます.プログラムは次のようになります.ファイル名を Part4-1.c としてエディターで打ち込んでください.(コメントは打ち込まなくても結構です.)
#include <stdio.h>
main()
{
/* 整数型の変数 a, b, c を用意する */
int a, b, c;
/* 整数型変数 a に入力 */
printf("整数 a を入力してください:");
scanf("%d", &a);
/* 整数型変数 b に入力 */
printf("整数 b を入力してください:");
scanf("%d", &b);
/* 整数型変数 c に a/b の結果を代入 */
c = a/b;
/* 変数 c の内容を画面に表示 */
printf("a/b=%d\n", c);
}
このプログラムを実行し、整数 a,b をそれぞれ入力すると、a/b の結果を画面に出力します.この場合 a,b 共に整数型なので、計算は整数の範囲で行われます(1/2 は 0 となります).ところで、 b として 0 を入力するとどうなるでしょうか?やってみると分かりますが、なにかエラーが出ます.このように、整数型に限らず 0 で割ろうとすると実行時にエラーになる(コンパイルは成功する)ので、それを回避することを考えねばなりません.そこで、条件文が登場します.まずは、サンプルプログラムでみてみましょう.先の Part4-1.c を次のように変更してください(説明の為に色をつけていますが、色は無視してください).
#include <stdio.h>
main()
{
/* 整数型の変数 a, b, c を用意する */
int a, b, c;
/* 整数型変数 a に入力 */
printf("整数 a を入力してください:");
scanf("%d", &a);
/* 整数型変数 b に入力 */
printf("整数 b を入力してください:");
scanf("%d", &b);
/* b が 0 であるかによって分岐 */
if (b == 0)
{
printf("0 での割り算はできません.\n");
}
else
{
/* 整数型変数 c に
a/b の結果を代入 */
c = a/b;
/* 変数 c
の内容を画面に表示 */
printf("a/b=%d\n", c);
}
}
if (b == 0) からが条件文です.このプログラムでは、入力された b の値が 0 に等しければ青色の部分が実行され、それ以外の場合は赤色の部分が実行されます.
if-else 文には重要なものとして次のような2つのパターンがあります.
パターン1
文0
if (条件)
{
条件が真であれば実行するブロック文・・・・ブロック文1
}
else
{
条件が偽であれば実行するブロック文・・・・ブロック文2
}
文3
パターン2
文0
if (条件)
{
条件が真であれば実行するブロック文・・・・ブロック文1
}
文2
パターン1とパターン2の違いは else 文が有るか無いかの違いです.
より複雑なものとして、次のパターン3がありますが、今回はあまり詳しく扱いません.
パターン3
文0
if (条件1)
{
条件が真であれば実行するブロック文・・・・ブロック文1
}
else if (条件2)
{
条件1が偽かつ条件2が真であれば実行するブロック文・・・・ブロック文2
}
・・・・・・
else if (条件N)
{
条件1〜条件N-1が全て偽かつ条件Nが真であれば実行するブロック文・・・・ブロック文N
}
else
{
条件1〜条件Nが全て偽であれば実行するブロック文・・・・ブロック文N+1
}
文N+2
上記パターン1とパターン2をフローチャートで示すと次のようになります.
if 文の条件の部分には条件式が入ります.条件式は関係演算子という演算子を使って記述します.関係演算子は2つの値の大小関係や等値関係を判定するものです.関係演算子には次のものがあります.
演算子 | 説明 | 記述例 | 記述の意味 |
> | 大きい | if (a > 100) | a が 100より大なら |
>= | 大きいか等しい | if (a >= 100) | a が 100以上なら |
< | 小さい | if (a < 100) | a が 100より小なら |
<= | 小さいか等しい | if (a <= 100) | a が 100以下なら |
== | 等しい | if (a == 100) | a が 100なら |
!= | 等しくない | if (a != 100) | a が 100でないなら |
等しいをあらわす条件式は == とイコール2つであることに注意してください.= とイコール1つの場合は変数への代入をあらわしていました(先週の内容).if 文の条件を書く部分に誤って代入式を書いたとしても、文法的には間違っていないので、コンパイルが成功してしまいます(期待した動作はしませんが).気をつけてください.
先ほどのサンプルプログラム Part4-1.c の if (b == 0) の部分を if (b != 0) と書き換えた場合、書き換える前のプログラムと同様の振る舞いをするプログラムとなるよう、他の部分を変更せよ.
ときには、
「a>10」 かつ 「a<100」 なら
「a==100」 または 「a==200」 なら
といった、場合を扱いたいときがあります.このような「かつ」や「または」に相当する論理演算子を使うことで、より複雑な条件をあらわすことができます.
例えば、うるう年は
「4で割り切れ かつ 100で割り切れない年」
「400で割り切れる年」
のどちらかに当てはまる年のことです.入力された年(西暦)を上の条件に照らし合わせ、うるう年かどうかを判定するプログラムは次のようになります.途中でてくる % は剰余を与えるものでした.
#include <stdio.h>
main()
{
int n;
printf("年=");
scanf("%d", &n);
if ((n%4 == 0) && (n%100 != 0))
{
printf("うるう年です\n");
}
if (n%400 == 0)
{
printf("うるう年です\n");
}
}
途中でてくる && が関係演算子で、「かつ」をあらわします.関係演算子には && のほかに次のようなものがあります.
演算子 | 説明 | 記述例 | 記述の意味 |
&& | 論理積(かつ/and) | if (a == 3 && b == 4) | a が 3 かつ b が 4 なら |
|| | 論理和(または/or) | if (a == 3 || b == 4) | a が 3 または b が 4 なら |
! | 否定(でない/not) | if (!(a == 3 && b == 4)) | a が 3 かつ b が 4 、でないなら |
関係演算子 && は & が2つであることに注意してください(|| も同様). & 1つでも他の意味がありますので、コンパイルエラーにはなりません.しかし、期待した動作とはならないので注意が必要です.
先の日本語でのうるう年の定義は
「4で割り切れ かつ 100で割り切れない年」 または 「400で割り切れる年」
と書き直すことができます.つまり、先の2つの if 文を一つにまとめて次のように書くこともできます.
if (((n%4 == 0) && (n%100 != 0)) || (n%400 ==
0))
{
printf("うるう年です\n");
}
入力された整数が、奇数か偶数かを判定するプログラムを作成せよ.
(注:演算子 % は整数型変数、整数に対してのみ利用可能.)
入力された実数の絶対値を表示するプログラムを作成せよ.