int main(void)
{
int a = 65;
char c = (char)a;
int m = 3.0/2;
printf("%c\n", c); // output: A
//printf("this %f\n", 5 / 2); //0.000000
printf("%f\n", (float)a); // output: 65.000000
printf("this %f\n", 5 / 2); //65.0000
printf("%f\n", 5.0 / 2); // output: 2.5000000
//printf("this %f\n", 5 / 2); 2.500
printf("%f\n", 5 / 2.0); // output: 2.5000000
//printf("this %f\n", 5 / 2); 2.5000
printf("%f\n", (float)5 / 2); // output: 2.5000000
//printf("this %f\n", 5 / 2); 2.500
printf("%f\n", 5 / (float)2); // output: 2.5000000
//printf("this %f\n", 5 / 2); 2.5000
printf("%f\n", (float)(5 / 2)); // output: 2.0000000 - we cast only after division and result was 2
//printf("this %f\n", 5 / 2); 2.0000000
printf("%f\n", 5.0 / 2); // output: 2.5000000
//printf("this %f\n", 5 / 2); 2.500
printf("%d\n", m); // output: 1
//printf("this %f\n", 5 / 2); 2.500
system("PAUSE");
return 0;
}
为什么每个注释中编写的所有内容都会更改,为什么每个注释中都会发生此更改? 例如,在第一条评论中,为什么会发生这种情况以及如何解决它的原因是0.00
答案 0 :(得分:1)
问题是您通过使用错误的格式说明符来调用未定义的行为。 5/2
的类型为2
的值为int
,但是您使用%f
进行打印。您应该将5/2
更改为5.0/2
,使其类型为double
或使用%d
打印。
printf("this %f\n", 5.0/ 2);
或
printf("this %d\n", 5 / 2);
答案 1 :(得分:1)
要扩大对Osiris的回答...
printf
是所谓的 variadic 函数-它具有可变数量的参数。函数原型如下:
int printf( const char * restrict format, ... );
这意味着该函数接受一个固定参数(format
),然后接受一些未知数(零个或多个)的附加参数。现在,这就是问题所在– printf
知道还有其他参数的唯一方法是它们的类型取决于您在format
字符串中指定的内容。 printf
不知道-它不知道-您在参数列表中实际传递了什么。它仅根据您在格式字符串中使用的转换说明符知道您的 claim 在参数列表中。
如果你写
printf( "%f\n", 1.0, 2, "3", '4', 5.0 );
那么就printf
而言,您仅传递了一个附加的double
自变量1.0
。即使您在格式字符串后传递了5个参数,printf
仍会查看单个%f
并得出结论,只有一个附加参数。请注意,这种特殊情况是定义明确的-将评估其他参数,但否则将忽略。从这里的代码行为是可预测的意义上来说,这是“安全的”。
如果你写
printf( "%f\n" );
然后您就遇到了问题,因为printf
假设还有一个额外的double
参数,它将继续寻找它(在寄存器中或堆栈中,取决于调用约定)。在这种情况下,行为是 undefined -最终结果可以是任何东西,从垃圾输出到彻底崩溃。
如果你写
printf( "%f\n", 5 / 2 ); // int / int == int
您有两个问题之一。如果函数参数是通过寄存器传递的,则您会遇到与上述相同的问题(整数参数通常在与浮点参数不同的一组寄存器中传递,因此printf
将在错误的寄存器中查找)。如果函数参数是通过堆栈传递的,则printf
将抢占堆栈中的下一个sizeof (double)
字节,并将其解释为double
。在这种情况下,问题在于int
和double
的表示可能根本不同。在32位int
中,2
通常表示为0x00000002
。在64位double
(假设使用IEEE-754表示)中,2.0
表示为0x4000000000000000
。同样,此行为是 undefined -您不能相信得到的任何结果。