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

为什么我没有得到预期的输出?

简短的回答:因为你的期望是错误的。

您正在指示编译器从 where yis 读取一个整数。这是错误的。格式说明符不会告诉编译器进行强制转换,只是期望什么类型,并相信提供正确的类型。

该行为可能是由于例如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”但传递一个浮点数,printf 例程可能会从通用处理器寄存器读取数据,但浮点值在浮点寄存器中。因此,打印的值将是发生在通用处理器寄存器中的任何数据。

类似地,当您指定“%f”但传递一个整数时,printf 例程可能从浮点寄存器中读取,但整数值在通用处理器寄存器中。

编译器不会将 printf 参数转换为目标类型,并且可能不会警告您不匹配。您必须将格式字符串中的转换说明符与参数类型相匹配。

奖励:这里是描述如何在一个平台(Mac OS X)上将参数传递给子例程的文档。

于 2012-08-09T18:30:58.233 回答
1

您不能将 char 格式化为 float "%f",使用"%c"or"%d"代替。我发现http://www.cplusplus.com/reference/clibrary/cstdio/printf/是一个很好的参考。

于 2012-08-09T18:07:39.137 回答
0

格式说明符和参数类型不匹配,我认为这会导致未定义的行为。printf不会为您进行强制转换,因此您必须显式转换参数。

于 2012-08-09T18:07:13.180 回答