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

时间:2012-08-09 18:04:29

标签: c printf

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 个答案:

答案 0 :(得分:3)

  

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

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

您指示编译器读取y所在的整数。哪个错了。格式说明符不会告诉编译器执行强制转换,只需要预期的类型,并且信任以提供正确的类型。

行为可能是因为例如float以8个字节存储。在这种情况下,高位字节将是0。但是int存储在4个字节中。所以你告诉编译器从int那里读取y,它读取前4个字节,即0,然后打印0 ......

编辑:正如John在评论中指出的那样,这是UB,这意味着任何事情都可能发生:

<强> 7.21.6.1/9

  

如果转换规范无效,则行为未定义.282)如果任何参数不是相应转换规范的正确类型,则行为未定义。

答案 1 :(得分:2)

许多计算平台以不同的方式传递不同类型的参数。在某些平台上,浮点参数在特殊浮点寄存器中传递。在大多数平台上,整数参数在通用处理器寄存器中传递。大型参数(例如结构)存储在内存中的某处,而是传递指针(不可见地传递给C源代码)。一旦使用了少数可用于参数的寄存器,剩余的参数通常在堆栈上传递。

当您调用printf时,编译器与您传递给格式字符串中的转换说明符的参数不匹配。 (除非好的编译器会检查并在类型不匹配时发出警告。)为了操作,printf例程读取格式字符串,当它找到转换说明符时,它从相应的参数中读取数据<强>应该。如果指定“%d”但传递浮点数,则printf例程可以从通用处理器寄存器读取数据,但浮点值在浮点寄存器中。因此,打印的值将是通用处理器寄存器中发生的任何数据。

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

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

Bonus:Here are documents描述如何将参数传递给一个平台(Mac OS X)上的子程序。

答案 2 :(得分:1)

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

答案 3 :(得分:0)

格式说明符和参数类型不匹配,我认为这会导致未定义的行为。 printf不会为你做转换,所以你必须显式地转换参数。