printfの%dにdouble型を渡すと無関係な値が表示される
%dは整数用の書式指定子です。double型の値を%dに渡すと、コンパイルは通り実行もできますが、表示される数値はまったく無関係な値になります。
なぜエラーが出ないのか
出力: -1758341768
(エラーなし)- Cは何も報告しません。コンパイルも実行も正常に完了するためです
出力: -1758341768- 実際の挙動 — 期待した結果と食い違っている箇所
見つけ方- エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます
このエラーが出る典型パターン
パターン1
1 #include <stdio.h> 2 3 int main(void) { 4 double price = 19.99; 5 printf("%d\n", price); ^ 6 return 0; 7 }
出力: -1758341768期待: 19.990000
%dは4バイトの整数として引数を読み取りますが、double型は8バイトで浮動小数点用のレジスタに渡されるため、まったく無関係な値が表示されます。double型には%fを使います。
直し方: d を f にします。
広告
広告スロット(未設定)
パターン2
1 #include <stdio.h> 2 3 int main(void) { 4 double temp = 36.5; 5 printf("%d\n", temp); ^ 6 return 0; 7 }
出力: 1103676008期待: 36.500000
エラーも警告も出ないまま、表示される数値だけが無関係なものになります。コンパイラは書式指定子と引数の型の対応まではチェックしないことがあります。
直し方: d を f にします。
パターン3
1 #include <stdio.h> 2 3 int main(void) { 4 double pi = 3.14159; 5 printf("%d\n", pi); ^ 6 return 0; 7 }
出力: -1391517704期待: 3.141590
書式指定子は必ず渡す値の型に合わせます。整数を表示したいときは%dと int型、小数を表示したいときは%fと double型を組み合わせます。
直し方: d を f にします。
よくある誤解
エラーも警告も出ないことがあります。%dは引数を4バイトの整数として読み取りますが、double型は8バイトで浮動小数点用のレジスタに渡されるため、ビット列としてまったく噛み合いません。書式指定子は必ず渡す値の型に合わせる必要があります。
まとめ
printfの%dにdouble型を渡すと無関係な値が表示されるは初級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。