• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:doubleは常に%lfとするべきなのか)

doubleは常に%lfとするべきなのか

このQ&Aのポイント
  • c言語におけるdoubleのフォーマットについて質問しました。
  • プログラム中で%fと%lfを使用した際の動作の違いについて疑問があります。
  • 変数ならfloat-double間の拡張をコンパイラが行ってくれるが、ポインタの拡張は行えないため、%lfを常に使用すべきではないかと考えています。

質問者が選んだベストアンサー

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

まず、引数の数が変えられる「可変長引数」というのがあります。 scanfもprintfも可変長引数の関数です。 C言語の場合、この可変長引数は次の特徴があります (1)引数として指定すると、int以下の整数はintに、double以下の実数はdoubleに型変換されます (2)関数側では、どんな引数が指定されたか、知ることができません。 (1) はprintfの%f に関係があります。 float f; double d; printf("%f %f",f,d) ; とあった場合、(1)のルールによって printf("%f %f",(double)f,d) ; と等価になります。 %fの対象をfloatとdoubleとで区別する必要がありません。 どちらもdoubeになるのですから (2)はscanfの%fと関係します。 引数の型や数を知ることができないので、別な方法で知ります。 その方法の一つが、「別の引数で、数や型を指定する」というものです。 scanf,printfの場合、書式文字列中の %* の数と型で判断します。 scanf("%f", &d) ; だと、 %f なので、1つのfloat * が指定されている、と判断します。つまり scanf("%f", (float *)&d) ; です。そして、読み込んだ値をsizeof(float)分、ポインタが示すアドレスに書き込みます。 一般にsizeof(float)<sizeof(double)なので、変数dの領域の一部が書き変わるだけです。 読み出した値は正しく変数dには納まりません。 scanf("%lf", &d) ; だと、 %lf なので、1つのdouble * が指定されている、と判断します。つまり scanf("%lf", (double *)&d) ; です。そして、読み込んだ値をsizeof(double)分、ポインタが示すアドレスに書き込みます。 こちらは、型と内容が一致するので、正しく変数dに納まります。 一部コンパイラは、書式文字列と引数との対応を調べて警告を出しますが、書式文字列が変数で指定されている場合等では、警告も出ません。 char scanFormat[STRMAX] ; /* scanFormatに書式文字列を設定 */ scanf( scanFormat, &a); >double変数の表示には%fでもいいが,%lfを常に使う方が正統な書き方だという理解でよろしいのでしょうか > 常に%lfを使うと何か問題なのでしょうか. むしろ、%fの方が正統です。 もともとprintfに%lfは不要ですし、存在していませんでした。 ところが、scanfと混同して「%lfが正しい」と考える人があまりに多かったので、後から規格に追加されました。 C99以降の規格に準じたコンパイラなら、どちらを使っても同じです。 それ以前のコンパイラでも、独自に%lf=%fとして処理しているものもありますが、%fとして動作しない場合もあります。 http://www.kijineko.co.jp/tech/superstitions/printf-format-for-double.html

nasanaut
質問者

お礼

ありがとうございます.説明していた内容をもとにprintf, scanfを読んだらとてもよく分かりました.今後もよろしくお願いします.

関連するQ&A