如果除以1,隐式类型转换是否会发生?

时间:2015-03-24 11:50:46

标签: c++ c

#include <stdio.h>

int main()

{
    unsigned int count=1;

    signed int val = -20;

    signed int div=(val/count);

    signed int div1=(val/(signed int)count);

    printf("div %d div1 %d \n",div,div1);
    return 0;
 }

输出:

div -20 div1 -20

但如果count = 5则输出:

div 858993455 div1 -4 

在count = 5的情况下,signed int被隐式转换为unsigned int,为什么不为count = 1

3 个答案:

答案 0 :(得分:5)

signed int div=(val/count);

如果其中一个操作数为int而另一个操作数为unsigned int,则int操作数将转换为unsigned int。因此,val转换为unsigned int,然后除以count,然后将结果转换回int

也就是说,此表达式被评估为

int div = (int)((unsigned int)val / count);

因此,当count == 1时,结果保持不变,但当count == 5 (unsigned int)val / count的结果变得小于INT_MAX时,所以当转换回int时它不会改变它的(大正值)值。

请注意,严格来说,即使count == 1结果不一定是-20,因为从(unsigned int)-20int的转换结果是实现定义的

答案 1 :(得分:1)

没有“隐式类型转换”这样的东西,类型转换是指明确地改变操作数的类型。正确的术语是隐式(类型)转换

C的基本原则表明编译器可以随意订购或优化您的程序,只要它不会改变程序的结果。

因此,即使编译器发现1除法没有意义并且可以进行优化,它仍然必须考虑由隐式类型转换引起的潜在副作用:它无法优化那些,因为程序员可能故意依赖它们。

在您的特定情况下,signed int div=(val/count)会强制val隐式转换为无符号类型。但这并不重要,因为你将结果显示回一个有符号的类型,任何除以1的东西无论如何都将保持不变。因此编译器可以优化整个事物,因为无论是否使用了无符号或有符号算术,结果都是相同的。

如果除以5,则结果在-20/5 = -40xFFFFFFEC/5 = 0xFFFFFFFC之间变得非常不同。因此,编译器不允许优化隐含转换,因为它会影响结果。

因此,程序员必须知道implicit type conversion rules,以告诉他们自己的源代码行之间实际会发生什么。

答案 2 :(得分:0)

这是the usual arithmetic conversions。你可以在那里找到规则。

实际上,第一个结果是(无符号)-4。使用补充规则,它将是858993455。

您也可以参考Implicit conversions