web-dev-qa-db-ja.com

%dと%fを使用するC printf

私はこのプログラムに取り組んでいましたが、doubleに%fを使用し、floatに%dを使用すると、まったく異なるものになることに気付きました。なぜこれが起こるのか誰かが知っていますか?

int main ()
{
 float a = 1F;
 double b = 1;

 printf("float =%d\ndouble= %f", a, b);
}

これは出力です

float = -1610612736
double = 190359837192766135921612671364749893774625551025007120912096639276776057269784974988808792093423962875123204096.0000
10
user69514

変数パラメーターの動作方法により、Cは、%d%f以外に、実際に渡す値のタイプを認識していません。変数パラメーターを渡すときは、基本的に(void*)&myvalueを実行します。これは、コンパイラーも実行時の関数も、フォーマット文字列で指定されているものを除いて、変数のタイプを判別できないためです。したがって、使用可能な暗黙の変換がある場合でも、コンパイラーはそれが必要であることを認識しません。

まあ、ほとんどのシステムではdoubleは8バイトですが、floatは4バイトです。したがって、2つのタイプはそのままではバイナリ互換ではありません。そしてそれは、文字列をdoubleまたは他の互換性のない型として解釈しようとするようなものです。

5
Earlz

%dは10進数を表し、タイプint(またはプロモートされる小さな符号付き整数タイプ)の引数を想定しています。浮動小数点型floatdoubleはどちらも同じ方法で渡され(doubleにプロモートされます)、どちらも%fを使用します。 C99では、%lfを使用してdoubleのサイズが大きいことを示すこともできますが、これは純粋に表面的なものです(scanfではプロモーションは発生せず、実際に違いが生じることに注意してください)。

4
Tronic

データの内部表現と関係があります。 floatをintであるかのように出力しようとしていますが、これは完全に異なる内部(バイナリ)表現を持っています。

doubleの場合も同様です。 float変数の後にガベージ(任意のデータ)がある可能性があります。そのゴミはdouble値の一部として解釈されます。

3

%dは整数を出力するため、printfは変数aをintとして解釈します。

Gcc 3.4.6では、コードで両方の値が0になります(初期化からFを削除した後、コンパイラエラーが発生しました)。これは、intが0として解釈されているa変数の部分に関係していると思われ、コンパイラーは混乱します...

両方の変数に%fを使用すると、両方の変数に1.000000が出力されます。

このページの下部近くに変換文字のリストがあります。

http://www.exforsys.com/tutorials/c-language/managing-input-and-output-operations-in-c.html

0
GreenMatt