実行した結果が表示される理由は次のとおりです。
引数を渡すときにint
printf 指定子を使用する場合double
(この状況では a が afloat
に変換されることに注意してくださいdouble
)、ほとんどの C 実装は、引数を可変個引数関数 (多様な関数を受け入れる関数) にint
渡すための通常の規則に従って引数を渡します。int
引数の型)、しかし、ルーチンは、以下で説明するようにprintf
、引数が渡されたかのようにマシンの状態を解釈します。double
(これは常に起こるとは限りません。C 標準で定義された動作を離れると、C 実装は他のことを行う可能性があります。特に、驚くべき結果を引き起こすオプティマイザーとの複雑な相互作用が発生する可能性があります。しかし、これは起こることです。信頼することはできません。)
各コンピューティング プラットフォームには、引数の受け渡し方法に関するいくつかの規則があります。あるプラットフォームでは、すべての引数が右から左にスタックにプッシュされ、各引数が必要なバイト数だけを使用してスタックに置かれるように指定する場合があります。別のプラットフォームでは、引数を左から右にスタックにプッシュするか、次の 4 バイトの倍数まで引数をパディングして、スタックを適切に配置するように指定する場合があります。最近の多くのプラットフォームでは、特定のサイズ以下の整数引数は汎用レジスターで渡され、浮動小数点引数は浮動小数点レジスターで渡され、その他の引数はスタックで渡されるように指定されています。
が引数をprintf
見%f
て探しているときに を渡した場合、何が見つかるでしょうか? このプラットフォームが両方の引数をスタックにプッシュすると、は のビットを見つけますが、それらのビットを . であるかのように解釈します。これにより、によって決定された値が表示されますが、とのエンコーディングではビットの意味がまったく異なるため、と明確な関係はありません。double
int
printf
printf
int
double
printf
int
int
int
double
このプラットフォームがint
引数をある場所double
に配置し、別の場所に引数を配置する場合、引数printf
とはまったく関係のないビットがいくつか見つかりますint
。double
これらは、たとえば、引数があるはずの浮動小数点レジスタにたまたま残ったビットです。それらのビットは、以前の作業の残りにすぎません。int
取得する値は、渡したに対して基本的にランダムになります。渡された の 4 バイトと近くにある他の 4 バイトを取得することによりprintf
、 a の 8 バイトを探して、ミックスを取得することもできます。double
int
プログラムを複数回実行すると、同じ値が出力されることがよくあります。これには 2 つの理由があります。まず、コンピュータは機械的です。それらは主に決定論的な方法で動作するため、それらがあなたが使用している方法で使用されるように特に設計されていなくても、同じことを何度も繰り返します。第 2 に、オペレーティング システムが起動時にプログラムに渡す環境は、プログラムを起動するたびにほぼ同じです。そのメモリの大部分はクリアされるか、プログラム ファイルから初期化されます。メモリまたは他のプログラムの状態の一部が、コンピューターの他の環境から初期化されています。そのデータは、プログラムの実行ごとに異なる場合があります。たとえば、実行ごとに現在時刻が明らかに変化します。コマンド履歴も同様です。コマンド シェルが環境変数に設定したプラスの値。プログラムを複数回実行すると、結果が異なる場合があります。
仕様 (C 仕様、コンパイラ仕様、マシンおよびオペレーティング システムの仕様、またはその他のドキュメント) によって動作が定義されていないコードを使用する場合、そのコードの動作に依存することはできません。(C 標準で完全に指定されていなくても、その C コンパイラで指定されている特定の C コンパイラでコンパイルされたコードの動作に依存することができます。)