キャスト

切り捨てられた平均を直す

前回、合計 221 点の平均が 73 点になりました。本当は 73.666... です。今回はこれを正しく出します。

原因は割り算そのものにある

まず、次のコードでは直りません。

double average = total / 3; printf("%.1f\n", average); /* 73.0 */

受け取る側を double にしても、73.0 と出るだけです。total / 3 を計算する時点で、両方とも int なので結果は int になり、そこで 73 に切り捨てられています。あとから double の箱に移しても、消えた 0.666 は戻ってきません。

直すべきなのは、割り算をする前です。

キャストで型を一時的に変える

値の前に (型名) を書くと、その値をその型として扱えます。これをキャストと呼びます。

double average = (double)total / 3; printf("%.1f\n", average); /* 73.7 */

(double)total で、割られる数だけを double にしています。C では、割り算の左右で型が違うと、小さいほうが大きいほうに合わせられます。ここでは int の 3 が double の 3.0 として扱われ、割り算全体が小数の割り算になります。結果は 73.666... となり、切り捨ては起きません。

(double)(total / 3) と書くと丸かっこの中が先に計算されてしまい、73.0 に戻ります。キャストはかっこの位置で意味が変わります。

3つの書き方はどれも通る

次の3つはどれも小数の平均になります。片方が double なら十分だからです。

(double)total / 3 total / (double)3 total / 3.0

いちばん短いのは total / 3.0 です。ただ、割る数が変数のときは 3.0 と書けないので、(double) を付ける形を覚えておくと応用が利きます。

表示の桁を決める

%f のままだと 73.666667 と6桁出ます。前回の書式指定を使って %.1f と桁を決めてください。この講座の採点は出力を1文字ずつ比べるので、桁を指定しないと不合格になります。

キャストは切り捨てにも使える

逆向きのキャストもできます。(int)73.9 は 73 です。四捨五入ではなく小数を捨てるだけ、という点は int の代入と同じです。四捨五入したいときは 0.5 を足してから int にする、という手が使えます。

printf("%d\n", (int)73.9); /* 73 */ printf("%d\n", (int)(73.4 + 0.5)); /* 73 */ printf("%d\n", (int)(73.6 + 0.5)); /* 74 */

事故に気づくための目印

平均を小数で出したはずなのに、.0 ばかりが並ぶときは、ほぼ確実にどこかで int どうしの割り算をしています。逆に、小数で出したいのに %d で出そうとすると、値がまったく別の数になります。

この2つは C の初学者がいちばん長く悩む場所です。「割る前にキャストできているか」「出す印は値の型と合っているか」の2点を、その場で確かめる癖を付けてください。次回の比較演算子と合わせて、この章の残りはあと2回です。

要件

  1. 3つの点数を scanf で読む
  2. 合計は int で出す
  3. 平均はキャストを使って小数のまま計算する
  4. 平均は小数点以下1桁で出す
  5. 「合計は221点です」「平均は73.7点です」の形で2行出す

入出力例

main("80 75 66") → "合計は221点です 平均は73.7点です" main("90", "85", "70") → "合計は245点です 平均は81.7点です"

ヒント

生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部
main.c
学習モード

メモ

キャスト

⌘S で保存