C言語で情報オリンピック Day5
条件判断
if文
C言語では条件判断(論理計算)をif文で実装します。
if ( a > b) {
printf("%d", a);
} else {
printf("%d", b);
}
このコードは変数aとbの大きいほうの値を出力します。たとえばa=3,b=4の場合4を出力します。if 文のすぐ後ろに括弧の中には条件判断式(論理式)を記入します。C言語にはブーリアン型がないので、0出ない場合(1や5, -3など)は真、0の場合は偽になります。
elseはなくても文法としては間違っていません。たとえば
if (a > b)
printf("%d", a);
aはbより大きい時のみaの値を出力します。そしてprintf一文しかないため、{ }を省略することもできます。
論理式はさまざまな形があります。たとえば
a > b // a が b より大きい
a == b // aイコールb
a < b // a が b より小さい
a != b // a と b が等しくない
a - 10 > pow(b,2) // a - 10が bの平方より大きい
ここでよく間違えたのは == 比較符です。以下のプログラムを考えましょう。
int a=10, b = 3;
if (a=b)
printf("aとbはひとしい。\n");
else
printf("aとbは等しくありません。\n");
このコードはコンパイラーによりますが、コンパイルの時にエラーとして報告されたものもあれば、エラーなしで実行されたものもあります。もし実行されたら、「aとbはひとしい。」と出力されます。
なぜなら、a=bという式は論理式ではなく、bの値をaに与えて、式全体の値はいつも1になります。
正しいソースコードはこうなります。
int a=10, b = 3;
if (a==b)
printf("aとbはひとしい。\n");
else
printf("aとbは等しくありません。\n");
そう、=符号は2つでないとだめなんです。
例題1 入力した整数aとbに対して、最大値と最小値を出力せよ。
分析:aとbの値を比較して、大きいほうは最大値、小さい方は最小値になります。
int a, b;
scanf("%d %d", &a, &b);
if (a > b) {
printf("最大値:%d 最小値:%d\n", a, b);
} else {
printf("最大値:%d 最小値:%d\n", b, a);
}
あるいはprintfを1行にすることができます:
int a, b;
scanf("%d %d", &a, &b);
if (a<b) { a = a + b; b = a - b; a = a - b; }
printf("最大値:%d 最小値:%d", a, b);
この書き方はもしaがbより小さいの場合、aとbの値を交換します。よって、aが必ず最大値になります。しかし、この書き方がもしa+bがint型の範囲(-2^31〜2^31-1)を超えた値になったら、とんでもない結果になってしまします。もっと安全な書き方はこうなります。
int a, b, tmp;
scanf("%d %d", &a, &b);
if (a<b) { tmp = a; a = b; b = tmp; }
printf("最大値:%d 最小値:%d", a, b);
この2つの方法でaとbの値が変わってしまう恐れがあります。
三項演算子?:を使えば、もっと簡潔(かんけつ)に書けます。
int a, b;
scanf("%d %d", &a, &b);
printf("最大値:%d 最小値:%d", (a>b)?a:b, (a>b)?b:a);
例題2 入力した自然数Nに対して、1〜Nの偶数の数を出力せよ。
分析:N=1の時は0、N=2の時は1、N=3の時は1、N=4の時は2、N=5の時は2、N=6の時は3…ですので、Nが奇数のときは(N-1)/2、Nが偶数のときはN/2になります。
int N;
scanf("%d", &N);
if (N%2==0) // もしNが偶数のとき
printf("%d", N/2);
else //もしNが奇数の場合
printf("%d", (N-1)/2);
%は余りを計算する符号です。
じつは N / 2 という式ですが、Nが整数の場合、小数の部分が省略されますので、5 / 2 は 2になります。ですので、この性質(せいしつ)を利用し、if文をなくすことができます。
int N;
scanf("%d", &N);
printf("%d", N/2);
もし偶数ではなく、奇数を出力せよというふうに問題を変えたらどうなりますか。偶数以外はぜんぶ奇数だから、N - N/2 を出力すればよい。注意してほしいのは、この N - N/2は数学式ではないことです。もし数学式でれば N - N/2 = N/2 ですので、偶数の数と同じになってしまいますが、N/2はNの半分ではなく、あくまでもコンピュータの計算式なので、厳密(げんみつ)にいえば、N/2の整数部というべきでしょう。ですので、奇数の数は N - ( N/2 の整数部)というのが正しい。数学の式とコンピュータ式を区別しましょう。
Day5まとめ
if文
else文
三項式 ? :
余りの式 %
N/2はN÷2ではないこと