printf と co は float と double をどのように区別しますか



強く型付けされていないため、適切なメモリサイズを選択し、引数の型に基づいて解釈しただけだと思いました。ただし、float と double はどちらも %f を使用し、サイズが異なります。


P.S.
値を temp にコピーしてキャストすることによる昇格 (これは正しいですか?) がどのように機能するかを確認できます
しかし、scanfs/sscanf ではどのように機能しますか?


答え:


それは区別しません。 float を受け取ることはできません vararg として:any float あなたが提供する引数は、最初に double に昇格されます .


6.5.2.2/6 は「デフォルトの引数の昇格」を定義し、/7 はデフォルトの引数の昇格が「末尾の引数」、つまり ... で示される可変引数に適用されると述べています。 .



%f scanf のフォーマット float へのポインタが必要です . %lf double へのポインタが必要です 、 %Lf long double へのポインタが必要です .



float 引数を指定すると、実装は double 型のテンポラリを作成し、float 値で初期化し、これを vararg として渡します。定義によるキャストは明示的です キャスト演算子を使用した変換 -- 必要に応じてキャストして、何が起こっているかを正確に読者に明確にすることができますが、 float f = 3; printf("%f", f); float f = 3; printf("%f", (double)f); とまったく同じです .デフォルトの引数昇格は、キャストと同じ意味を持ちます。