2

これが発生する理由を理解するのに苦労しています:次のコードで。

    #include <stdio.h>

    int main() 
    {
        double x=123;

        printf("x is %f. Enter a new value for x.\n", x);
        scanf("%f", &x);
        printf("x is %f\n", x);

        return 0;
    }

x の新しい値として 45678 を入力すると、「x is 123.000017」が出力されます。スキャン時に %lf を使用するとこれが修正されることはわかっていますが、%f を使用するとこの問題が発生するのはなぜですか?

4

2 に答える 2

3

スキャン時に %lf を使用するとこれが修正されることはわかっていますが、%f を使用するとこの問題が発生するのはなぜですか?

printfscanf関数の引数の違いは、 には値を渡しますがprintf、 にscanfはポインター (つまり、値のアドレス) を渡すことです。C の規則によると、関数が可変数の引数を取る場合、すべてのパラメーターはデフォルトの昇格を受けます。

プロモーションの 1 つは、 がfloatに変換されるdoubleのと同じ方法で、shortが に変換されることintです。%for%lfを使用できるのはそのためですprintf。どちらのタイプの値もコンパイラによって に変換されるためdouble、安全にアクセスできます。

ただし、ポインターにはそのような規則はありません (そして、正当な理由で:doubleのスペースに aを書き込もうとするfloatと、未定義の動作になります)。そのため、関数ファミリにパラメータを渡すとき%fとを区別する必要があります。%lfscanf

于 2013-11-10T14:25:43.520 に答える
1
 scanf("%f", &x);

する必要があります

 scanf("%lf", &x);

と の間の浮動小数点変換指定子には、誤った対称性がありprintfますscanf

また、変換指定子は変換lf指定子と同等であることに注意してください(c99 以降、以前は定義されていませんでした)。fprintf

スキャン時に %lf を使用するとこれが修正されることはわかっていますが、%f を使用するとこの問題が発生するのはなぜですか?

fの変換指定子にscanfは、 へのポインタ型の引数が必要floatです。ポインター型の引数を渡すと、double未定義の動作が呼び出されます。

于 2013-11-10T14:18:56.997 に答える