/*01*/ #include <stdio.h>
/*02*/
/*03*/ main()
/*04*/ {
/*05*/ int x1;
/*06*/ int x2;
/*07*/
/*08*/ printf("2数の大小を比べます。\n");
/*09*/ printf("整数を入力してください\n");
/*10*/ printf("数1 -> "); scanf("%d", &x1);
/*11*/ printf("数2 -> "); scanf("%d", &x2);
/*12*/
/*13*/ if(x1 == x2)
/*14*/ printf("2数は同じ値で:す。\n");
/*15*/ else if(x1 > x2)
/*16*/ printf("数1 の方が大きいです。\n");
/*17*/ else
/*18*/ printf("数2 の方が大きいです。\n");
/*19*/
/*20*/ return 0;
/*21*/ }
if 文は「もし~ならば・・・せよ。」というふうに処理の流れを制御する制御文です。書式は
if(条件式) 実行文;
if(x1 == x2){
printf("2数は同じ値です。\n");
printf("2数の合計は %d です。\n", x1 + x2);
}else if(x1 > x2){
printf("数1 の方が大きいです。\n");
printf("2数の合計は %d です。\n", x1 + x2);
}else{
printf("数2 の方が大きいです。\n");
printf("2数の合計は %d です。\n", x1 + x2);
}
else 文は if 文とセットで使います。「もし~ならば・・・せよ。そうでなければXXXせよ。」という制御で、「そうでなければXXXせよ。」の部分が else 文に相当します。書式は
if(条件式) 実行文; else 実行文;
この行の「else if」は制御文と言うわけではなく、else の実行文が if 文になっているにすぎません。しかし、このようにすることで「もし~ならば・・・せよ。そうでなくてOOOならばXXXせよ」という処理を行うことができます。この例では意味的な視点から上述のように書きましたが、文法的な視点から書けば
if(x1 == x2)
printf("2数は同じ値で:す。\n");
else
if(x1 > x2)
printf("数1 の方が大きいです。\n");
else
printf("数2 の方が大きいです。\n");
if(x1 == x2){
printf("2数は同じ値です。\n");
if(x1 > 100){
printf("また、2数は100より大きいです。");
}
}
if 文の条件式には「ゼロ」または「非ゼロ」の値を記述し、「ゼロ」の状態を
if(0) 実行文; /* 実行文は常に実行されない */ if(1) 実行文; /* 実行文は常に実行される */
しかし条件式に数値を直接書いていたのでは if の意味がありません。そこで下表のような、二つの値を比較し、その結果を真偽値(ゼロ or 非ゼロ)で返す演算子があります。
| 等値演算子 | |
| x == y | x と y が等しい。「=」がひとつでないことに注意。 |
| x != y | x と y が等しくない。「=!」ではダメ。 |
| 関係演算子 | |
| x < y | x が y より小さい。 |
| x <= y | x が y 以下。「=<」ではダメ。 |
| x >= y | x が y 以上。「=>」ではダメ。 |
| x > y | x が y より大きい。 |
たとえば、「x == y」では x と y の値が等しければ true となり、非ゼロに置き換わります。なお、等値演算子と関係演算子をあわせて関係演算子ということがあります。
等値・関係演算子と一緒に良く使われるのが下表の論理演算子です。
| 論理演算子 | |
| 真偽値1 || 真偽値2 | 「真偽値1」または「真偽値2」の少なくとも一方が true のとき true |
| 真偽値1 && 真偽値2 | 「真偽値1」と「真偽値2」の両方が true のとき true |
等値・関係演算子、論理演算子の使用例を.に示すので、参考にしてください。また、これらの演算子は「 ( )」で優先順位を決めてやれば複数組み合わせることができます。
/*** パターン1 ***/
if(0){
/* 絶対に実行されない */
}
/*** パターン2 ***/
if(1){
/* 必ず実行される */
}
/*** パターン3 ***/
if(-3){
/* 必ず実行される */
}
/*** パターン4 ***/
x = 0;
if(x){ /* if(0) と同じ */
/* 実行されない
}
/*** パターン5 ***/
x = 1;
if(x){ /* if(1) と同じ */
/* 実行される */
}
/*** パターン6 ***/
x = 1; y = 2;
if(x > y){ /* 条件を満たしていないので if(0) と同じ */
/* 実行されない */
}
/*** パターン7 ***/
x = 2; y = 1;
if(x > y){ /* 条件を満たしているので if(1) と同じ */
/* 実行される */
}
/*** パターン8 ***/
if(x1 == x2){ /* x1 と x2 が等しい時に真 */
printf("2数は同じ値です。\n");
}
/*** パターン9 ***/
if(x1 == x2 || x1 < x2){ /* x1 と x2 が等しいか x1 のほうが小さいときに真 */
printf("x1 は x2 と同じか、小さいです。\n");
}
今までにいろいろな演算子が出てきましたが、ひとつの式にいくつもの演算子が使われている場合はどうなるのでしょう。これらの演算子にはどう順序でこれらのを評価していくか、演算順位が決まっています。ちょうど、数学で「+」や「-」よりも、「*(乗算)」「/(除算)」の方が優先順位が高いのと同じですね。今までに出てきていないものも含めて、これらの優先順位をまとめておくので参考にして下さい。
() [] -> . ! ~ ++ -- * & (type) sizeof (「*」は間接演算子) * / % + - << >> < <= >= > == != & (「&」はビットごとの論理演算子) ^ | && || ? : = += -= *= /= %= &= ^= |= <<= >>= ,
生まれた年(西暦)を入力すると、その年の干支が出るようにしてください。
参考1:
2000年はたつ年です。
参考2:
(十二支の順)ねずみ / うし / とら / うさぎ / たつ / へび / うま / ひつじ / さる / とり / いぬ / いのしし
二つの float 型で割る数と割られる数を入力すると、その計算結果を出す割り算プログラムを作ってください。ただし、割り算には「0 で割ることはできない」という制約があります。そこで、割る数として 0 が入力された時は「0 で割ってはいけません」というメッセージを表示するようにしてください。また、この問題では比較演算子を使ってはいけません。
キーボードから 3 つの整数を入力し、これを小さい順に並べ替えて表示させてください。
#include <stdio.h>
main()
{
int year;
printf("今年は何年ですか? -> ");
scanf("%d", &year);
/* 入力された年を12で割った余りを使い、干支を判別します。 */
year = year % 12;
/* 2000 割る 12 の余りが 8 であることから、余りが 8 の
年は たつ 年と分かります。 */
if(year == 8){
printf("あなたは たつ 年生まれです。\n");
}else if(year == 9){
printf("あなたは へび 年生まれです。\n");
}else if(year == 10){
printf("あなたは うま 年生まれです。\n");
}else if(year == 11){
printf("あなたは ひつじ 年生まれです。\n");
}else if(year == 0){
printf("あなたは さる 年生まれです。\n");
}else if(year == 1){
printf("あなたは とり 年生まれです。\n");
}else if(year == 2){
printf("あなたは いぬ 年生まれです。\n");
}else if(year == 3){
printf("あなたは いのしし 年生まれです。\n");
}else if(year == 4){
printf("あなたは ねずみ 年生まれです。\n");
}else if(year == 5){
printf("あなたは うし 年生まれです。\n");
}else if(year == 6){
printf("あなたは とら 年生まれです。\n");
}else{
printf("あなたは うさぎ 年生まれです。\n");
}
return 0;
}
if 文の条件式が非ゼロならば実行されることを利用します。
#include <stdio.h>
main()
{
float a, b, y;
printf("[割られる数] [割る数]:");
scanf("%f%f", &a, &b);
/* b が非ゼロなら計算する */
if(b){
y = a / b;
printf("答えは %.2f です。\n", y);
}else{
printf("割る数は 0 であってはいけません。\n");
}
return 0;
}
データの個数が 3 個しかないことに着目して全てのパターンを調べる強引な手法
#include <stdio.h>
main()
{
int x1, x2, x3; /* 読み込んだ値を入れる */
int y1, y2, y3; /* 小さい順に入れる */
printf("三つの整数を入力してください -> ");
scanf("%d%d%d", &x1, &x2, &x3);
/* セット1
x1 がもっとも小さいときの処理 */
if(x1 <= x2 && x1 <= x3){
y1 = x1;
if(x2 <= x3){ /* さらに x2 と x3 を比較 */
y2 = x2;
y3 = x3;
}else{
y2 = x3;
y3 = x2;
}
}
/* セット2
x2 がもっとも小さいときの処理 */
if(x2 <= x1 && x2 <= x3){
y1 = x2;
if(x1 <= x3){ /* さらに x1 と x3 を比較 */
y2 = x1;
y3 = x3;
}else{
y2 = x3;
y3 = x1;
}
}
/* セット3
x3 がもっとも小さいときの処理 */
if(x3 <= x1 && x3 <= x2){
y1 = x3;
if(x1 <= x2){ /* さらに x1 と x2 を比較 */
y2 = x1;
y3 = x2;
}else{
y2 = x2;
y3 = x1;
}
}
/* 以上の比較で「<」とせずに「<=」としたのは、値が同じ場合にその二つを
入れ替えても同じこと、という理屈のため。逆に「<」としてしまった場合、
値が同じ場合の処理も加えなければいけない。そうでないと例えば値が
「x1 = 1」「x2 = 1」「x3 = 2」の時、
(x1 < x2 && x1 < x3)
(x2 < x1 && x2 < x3)
(x3 < x1 && x3 < x2)
のいずれにも当てはまらなくなってしまう */
printf("小さい順に並べ替えました -> %d %d %d\n", y1, y2, y3);
return 0;
}
並んだデータを最初から順に見ていき、隣同士を比較して逆順なら入れ替える手法(バブルソートという)。
#include <stdio.h>
main()
{
int x1, x2, x3, tmp;
printf("三つの整数を入力してください -> ");
scanf("%d%d%d", &x1, &x2, &x3);
/* 1 サイクル目 */
if(x1 > x2){ /* 最初の二つを比較 */
tmp = x1; /* 二つの値を入れ替えるとき、片方の値を */
x1 = x2; /* tmp に退避させておかねばならない */
x2 = tmp;
}
if(x2 > x3){
tmp = x2;
x2 = x3;
x3 = tmp;
}
/* ここまでが 1 サイクル目。この時点で並びの最後には
もっとも大きな値が入っているはず */
/* 2 サイクル目 */
if(x1 > x2){
tmp = x1;
x1 = x2;
x2 = tmp;
}
/* ここまでが 2 サイクル目 */
printf("小さい順に並べ替えました -> %d %d %d\n", x1, x2, x3);
return 0;
}
補足:バブルソートの例
3 5 1 2 4 という並びがあったとする。[]で示された二つの値を比較 1 サイクル目 [3] [5] 1 2 4 → 3 5 1 2 4 3 [5] [1] 2 4 → 3 1 5 2 4 3 1 [5] [2] 4 → 3 1 2 5 4 3 1 2 [5] [4] → 3 1 2 4 5 この時点で並びの最後は最も大きな値になっている 2 サイクル目 [3] [1] 2 4 5 → 1 3 2 4 5 1 [3] [2] 4 5 → 1 2 3 4 5 この例では 2 サイクル目で並び終わったが、あとは これの繰り返しである