算術演算と整数除算の罠
計算に使う5つの記号
入力を受け取れるようになったので、いよいよ計算します。C の算術演算子は次の5つです。
+足す-引く*かける/割る%割ったあまりを出す
かけ算が x ではなく *、あまりが % である点が算数と違います。printf の書式指定子も % を使いますが、こちらは文字列の中の話なので別ものです。優先順位は算数と同じで、* / % が + - より先に計算されます。順番を変えたいときは丸かっこで囲みます。
int total = kokugo + suugaku + eigo;
int average = total / 3;int どうしの割り算は小数が消える
ここがこの回のいちばん大事なところです。3科目の合計が 221 点だったとします。本当の平均は 73.666... ですが、上のコードで出てくる値は 73 です。
C では、割られる数と割る数がどちらも int のとき、結果も int になります。int は整数しか入らない箱なので、小数部分は四捨五入されずに切り捨てられます。74 ではなく 73 になるのはこのためです。
printf("%d\n", 221 / 3); /* 73 */
printf("%d\n", 7 / 2); /* 3 */
printf("%d\n", 1 / 2); /* 0 */1 / 2 が 0 になるのは、慣れないうちは本当に気づけません。エラーも警告も出ず、静かに間違った成績表ができあがります。
消えたぶんは % で取り出せる
切り捨てられた端数は、% を使うと整数の形で拾えます。221 を 3 で割ると商が 73、あまりが 2 です。
printf("%d\n", 221 % 3); /* 2 */% は偶数か奇数かの判定や、何個ずつ配れるかの計算でよく使います。第3章の FizzBuzz でも主役になります。なお % を使えるのは int どうしのときだけです。double に使うとコンパイルエラーになります。
割る数が 0 だと落ちる
total / 0 や total % 0 はプログラムが異常終了します。コンパイルは通ってしまうので、割る数が変数のときは 0 かどうかを気にする必要があります。今回は 3 で固定なので問題になりませんが、第4章で人数を入力させるようになると、0 人と入力された場合を考えることになります。
短く書く記号
同じ変数に足し込むときは、まとめた書き方があります。
total = total + 78;
total += 78; /* 上と同じ意味 */+= -= *= /= %= があります。1つ増やす count++ もよく使い、第4章の for 文で必ず出てきます。
今回はわざと間違ったままにする
平均点を小数で正しく出す方法はあります。ただ、先に「int だと切り捨てられる」という手ざわりを持っておかないと、次回に出てくる直し方が、意味の分からない儀式になってしまいます。今回は切り捨てられた平均をそのまま出してください。直すのは次回です。
要件
- 3つの点数を scanf で読む
- 合計を int の変数に入れる
- 平均は合計を 3 で割った int の値をそのまま出す
- あまりは % を使って出す
- 「合計は221点です」「平均は73点です」「あまりは2です」の形で3行出す
入出力例
main("80 75 66") → "合計は221点です
平均は73点です
あまりは2です"
main("90", "85", "70") → "合計は245点です
平均は81点です
あまりは2です"