0

ここに私のコードの一部があります。

float a = 12.5;
printf("%d\n", a);
printf("%d\n", (int)a);
printf("%d\n", *(int *)&a);

Windowsでコンパイルすると、次のようになりました。 0 12 1094713344

そして、Linuxでコンパイルすると、次のようになりました。 -1437851864 12 1094713344

-1437851864実行するたびに変更されます。私の質問は次のとおりです。「printf」機能はLinuxでどのように機能しますか

4

3 に答える 3

7

非常にうまく機能しますが、なぜ間違った種類のデータを渡すのでしょうか? %d指定子は and を期待していますが、別のintものを渡しています。悪いアイデア。

varargs バリアを越えて と のサイズが異なる場合floatintこれは未定義の動作です。そして、 通常floatはvarargs 呼び出しで昇格されるため 、あなたがあなたよりも小さい場合、これは壊れます。doubleintdouble

要するに、これは本当に悪い、壊れたコードです。これをしないでください。

于 2012-10-23T14:11:36.647 に答える
3

C で浮動小数点数を出力するには、次のようにする必要があります。

float a = 12.5;
printf("%f\n", a);
于 2012-10-23T14:12:10.127 に答える
0

前述したように、フォーマット文字列に一致しない型の引数を渡すと、未定義の動作が呼び出されるため、言語標準は何に対しても制限を設けていません。

float a = 12.5;
printf("%d\n", a);

実際にそうです。

それが何をするのかを知るには、実装を分析するか、少なくともコンパイラがそのコード用に生成したアセンブリを分析する必要があります。

そのコードを変換する一般的な方法は、プロモートされた (to double)float引数を浮動小数点レジスタに渡し、浮動小数点レジスタに渡された引数の数を伝えることprintfです。しかし、フォーマットはprintfを探すように指示しているのでint、浮動小数点レジスタではなく、別のレジスタを探します。したがって、出力される値は、呼び出されたときにたまたまそのレジスタにあったものになりprintfます。

于 2012-10-23T14:52:06.267 に答える