0
int main()
{
  int x;
  float y;
  char c;

  x = -4443;
  y = 24.25;
  c = 'M';

  printf("\nThe value of integer variable x is %f", (float)x);
  printf("\nThe value of float variable y is %d", y);
  printf("\nThe value of character variable c is %f\n",c);
    return 0;
}

出力:

The value of integer variable x is -4443.000000
The value of float variable y is 0
The value of character variable c is 24.250000

期待される出力が得られないのはなぜですか?

しかし、外部キャストを使用している場合、次のような期待される出力が得られます。

The value of integer variable x is -4443.000000
The value of float variable y is 24
The value of character variable c is 77.000000
4

4 に答える 4

3

期待される出力が得られないのはなぜですか?

簡単な答え: あなたの期待が間違っているからです。

どこから整数を読み取るようにコンパイラに指示していますy。これは間違っています。フォーマット指定子は、コンパイラにキャストを行うように指示するのではなく、期待する型だけを伝え、正しい型を提供することを信頼します。

この動作は、たとえば、afloatが 8 バイトで格納されていることが原因である可能性があります。この場合は上位バイトになります0。ただし、anintは 4 バイトで格納されます。つまり、コンパイラにintをどこから読み取るかを指示すると、コンパイラyは最初の 4 バイトを読み取り、これは0であり、出力し0ます ...

編集: ジョンがコメントで指摘したように、これは UB です。つまり、何でも起こり得るということです。

7.21.6.1/9

変換仕様が無効な場合、動作は未定義です.282) 引数が対応する変換仕様に対して正しい型でない場合、動作は未定義です.

于 2012-08-09T18:08:14.283 に答える
2

多くのコンピューティング プラットフォームは、さまざまな方法でさまざまな種類の引数を渡します。一部のプラットフォームでは、浮動小数点引数は特別な浮動小数点レジスタで渡されます。ほとんどのプラットフォームでは、整数引数は汎用プロセッサ レジスタで渡されます。構造体などの大きな引数はメモリのどこかに格納され、代わりにポインターが渡されます (C ソース コードには見えません)。引数に使用できるいくつかのレジスタが使用されると、通常、残りの引数はスタックに渡されます。

printf を呼び出すと、コンパイラは、書式文字列で変換指定子に渡す引数と一致しません。(優れたコンパイラがチェックして、型が一致しない場合に警告を発行することを除いて。) 動作するために、printf ルーチンはフォーマット文字列を読み取り、変換指定子を見つけると、対応する引数が必要な場所からデータを読み取ります。なれ。「%d」を指定して float を渡すと、printf ルーチンは汎用プロセッサ レジスタからデータを読み取ることができますが、float 値は浮動小数点レジスタにあります。したがって、出力される値は、たまたまジェネラル プロセッサ レジスタにあったデータです。

同様に、「%f」を指定して整数を渡すと、printf ルーチンは浮動小数点レジスタから読み取ることができますが、整数値は汎用プロセッサ レジスタにあります。

コンパイラはprintf 引数をターゲットの型に変換せず、不一致について警告しない場合があります。フォーマット文字列の変換指定子を引数の型と一致させる必要があります。

おまけ: 1 つのプラットフォーム (Mac OS X) で引数がサブルーチンに渡される方法を説明するドキュメントがあります。

于 2012-08-09T18:30:58.233 に答える
1

char を float としてフォーマットすることはできません。代わりにorを"%f"使用してください。http://www.cplusplus.com/reference/clibrary/cstdio/printf/が参考になると思います。"%c""%d"

于 2012-08-09T18:07:39.137 に答える
0

フォーマット指定子と引数の型が一致しないため、未定義の動作が発生すると思われます。printfはキャストを行わないため、引数を明示的にキャストする必要があります。

于 2012-08-09T18:07:13.180 に答える