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ではないこと



この記事が気に入ったらサポートをしてみませんか?