C

时间:2017-07-19 08:50:29

标签: c type-conversion

以下代码有效:

int main(void)
{  
   float f = get_float();
   int i = round(f*100);
   printf("%i\n", i); 
}

然而,如果以这种方式编码会产生错误:

printf("%i\n", round(1.21*100));

输出结果显示round(1.21*100)float。那么,为什么

int i = round(f*100); 

很好吗?

3 个答案:

答案 0 :(得分:15)

当你这样做时

int i = round(f*100); 

转换 double函数round的结果。转换后的结果存储在int变量i中,该变量可以与格式"%i"一起使用,因为它需要int参数。

当您将double round结果直接作为参数传递给期望int的格式时,您的格式和参数类型不匹配。这会导致未定义的行为

printf的调用未进行转换,因为printf函数中的代码不知道实际的类型,因此无法进行转换 论点。它只知道格式"%i"。变量参数函数会丢失所有可能的类型信息。

答案 1 :(得分:5)

这是因为自动类型转换的行为。在printf中,自动类型转换不起作用。当你说%i时,它只是期望整数,它不能将double转换为整数然后打印。

在赋值操作中,double首先转换为整数,然后将其赋值给=运算符的左操作数。我希望这会有所帮助。

答案 2 :(得分:4)

这有点重复,但可能有助于更好地理解:

  1. round()有以下原型:

    double round(double x);
    

    所以它返回double

  2. C中有{em>隐式转换从doubleint,所以写

    int i = round(f*100);
    

    会将round()的结果转换为int

  3. 如果你有一个需要int的函数,例如

    void printMyNumber(int number)
    {
        printf("%i\n", number);
    }
    
    你可以这样称呼它:

    printMyNumber(round(f*100));
    

    并且隐式转换按预期工作,因为编译器会看到两种类型(round()的返回类型和printMyNumber()的预期参数类型。)

  4. 这与printf()无法合作的原因是printf()的原型如下所示:

    printf(const char *format, ...);
    

    所以,除第一个参数外,参数的类型是 unknown 。因此,无论您传递的是什么都没有任何转换(default argument promotions除外)。当然,您可以使用强制转换来实现显式转换

    printf("%i\n", (int) round(f*100)); // <- this is fine