l
を読み取るときにscanf()
が "%lf
"でdouble
を必要とするのは、なぜprintf()
がその引数がdouble
であるかfloat
であるかに関係なく "%f
"を使用できるからですか?
サンプルコード:
double d;
scanf("%lf", &d);
printf("%f", d);
Cは、可変引数を取る関数のfloatをdoubleにプロモートするためです。ポインターは何にも昇格されないので、%lf
、%lg
、または%le
(またはC99では%la
)を使用してダブルで読み取る必要があります。
С99以降、Cの書式指定子と浮動小数点引数型の一致は、printf
とscanf
の間で一貫しています。それは
float
の%f
double
の%lf
%Lf
for long double
タイプfloat
の引数が可変引数として渡されると、そのような引数は暗黙的にタイプdouble
に変換されます。これが、printf
形式指定子%f
と%lf
が同等で互換性がある理由です。 printf
では、float
と%lf
またはdouble
と%f
を「相互使用」できます。
しかし、実際に実際に行う理由はありません。タイプprintf
のdouble
引数に%f
を使用しないでください。それは、C89/90時代に生まれた広範な習慣ですが、悪い習慣です。 printf
にはdouble
の%lf
を使用し、float
引数には%f
を予約しておいてください。
scanf
は、&d
が指すデータのサイズを認識して適切に入力する必要がありますが、可変長関数はfloatをdoubleに昇格します(理由は完全にはわかりません)。したがって、printf
は常にdouble
を取得します。
そうしないと、scanfは、doubleよりも小さいサイズのfloatにポインターを渡していると見なし、誤った値を返します。
C式でfloat値またはdouble値を使用すると、とにかくdoubleの値になるため、printfは違いを判別できません。一方、doubleへのポインターは、floatへのポインターとは異なるものとしてscanfに明示的に通知する必要があります。これは、ポインターが指すものが重要なためです。