下面的代码工作:数据类型混淆用C
printf("%i\n", round(1.21*100));
输出说round(1.21*100)
是float
:
int main(void)
{
float f = get_float();
int i = round(f*100);
printf("%i\n", i);
}
然而,如果编码这种方式产生的错误。那么,为什么
int i = round(f*100);
很好?
下面的代码工作:数据类型混淆用C
printf("%i\n", round(1.21*100));
输出说round(1.21*100)
是float
:
int main(void)
{
float f = get_float();
int i = round(f*100);
printf("%i\n", i);
}
然而,如果编码这种方式产生的错误。那么,为什么
int i = round(f*100);
很好?
当你
int i = round(f*100);
你转换的double
功能round
的结果。转换后的结果存储在int
变量i
中,该变量可以与"%i"
格式一起使用,因为它预计参数为int
。
当您将double
结果round
直接作为参数传递给预期为int
的格式时,您的格式和参数类型不匹配。这导致未定义的行为。
没有转换是在调用作出printf
,并没有转换可以进行自printf
函数内部的代码不知道实际的参数类型。它只知道格式"%i"
。所有可能的类型信息都会因可变参数函数而丢失。
好吧,“没有进行转换”,默认参数促销仍然完成。 –
@AnttiHaapala由于函数返回一个'double'值,而默认参数提升将会是一个'double',在这种特殊情况下不会进行转换。 –
这是因为自动类型转换的行为。在printf中,自动类型转换不起作用。当你说%i时,它只是期望整数,它不能将double转换为整数然后打印。
在赋值操作中,double首先被转换为整数,然后被赋值给=运算符的左操作数。我希望这有帮助。
这有点重复,但也许有助于为更好地理解:
round()
原型如下:
double round(double x);
所以它返回double
。
有一个隐式转换从double
在C int
,所以写
int i = round(f*100);
会的round()
结果转换为int
。
如果您有一个函数需要int,
void printMyNumber(int number)
{
printf("%i\n", number);
}
你可以这样调用:
printMyNumber(round(f*100));
和隐式转换按预期工作,因为编译器看到两种类型(从round()
返回类型和printMyNumber()
预期的参数类型)。
这并不printf()
工作的原因是,printf()
原型是这样的:
printf(const char *format, ...);
因此,除了第一个参数,该参数类型是未知。因此,无论你通过什么都没有任何转换(除了default argument promotions)。当然,你可以使用一个投以达到显式转换代替:
printf("%i\n", (int) round(f*100)); // <- this is fine
当'float'值赋值给'int'值,内部发生转换。 'round()'给出一个double值,所以如果没有执行转换,它的值仍然是double。在这个指定的情况下'printf(“%i \ n”,round(1.21 * 100));'不执行转换,因此它需要'%f'说明符来打印float值。 – Sma