-6

出力は何ですか?

main()
{
    float a=4;
    int i=2;
    printf("%f %d",i/a,i/a);
    printf("%d %f",i/a,i/a);
}

私が受け取っている答えは次のとおりです。0.500000 00 0.000000

理由: 最初のprintfでは %f=i/a=2/4=int/float、暗黙のキャストが行われ、結果が a (つまり 0.500000)にiなります。floatfloat

float のデフォルトの精度は 6 であるため、10 進数の 6 桁の次%d=i/a=2 /4=0.500000に next が表示されますが、%dフォーマット文字列は整数のみを出力するため、0 が出力され、10 進数値の後に破棄されます。

Next printfwith %d=i/a=2/4print 0 のコンセプトは同じです。しかし、%f=i/a=2/4=0.000000最後の結果はわかりませんでした。

4

3 に答える 3

4

式が昇格され、それがfor 1 つの引数であることを指定している場合の両方の場合に、間違った書式指定子を指定するこの単純な未定義の動作。セクションのC99 ドラフト標準のセクションがフォーマット文字列の段落9について参照する fprintf 関数は、次のように述べています。printfi/adoubleint7.19.6.1 printf

変換指定が無効な場合、動作は未定義です。[...]

警告を有効にする必要がありますが、両方gccを有効にする必要はありません。次のメッセージが表示されます。clanggcc

warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘double’ [-Wformat]
于 2013-10-01T13:24:18.680 に答える
3

i/afloatオペランドの 1 つが であるため、式は常に に評価されますfloat。印刷中は、指定子%dとを使用しています%f。したがって、使用%fするときは常に 0.5 になり、使用するときは%dになりますundefined

Linux (ubuntu) で gcc コンパイラを使用すると、次の出力が得られます (\nわかりやすくするために、最初の印刷後に追加されます)。

0.500000 2047229448
899608576 0.500000
于 2013-10-01T13:26:23.583 に答える
2

未定義の動作: のすべてのデータ型printfは暗黙的に float です。これは、データが浮動小数点に昇格されるため、i/a型があるためです。したがって、.floatint%fprintf

于 2013-10-01T13:24:04.110 に答える