用`int`和`long long`变量理解整数溢出

时间:2014-02-08 23:41:40

标签: c integer-overflow

为什么这些程序产生不同的输出?

Program 1

#include <stdio.h>
#include <limits.h>

int main()
{
    long long bigger = 0;
    int smaller = INT_MAX;

    bigger = smaller * 2;
    printf("Smaller = %d\n", smaller);
    printf("Bigger = smaller * 2 = %lld\n\n", bigger);

    return 0;
}

输出:

  

较小= 2147483647

     

更大=更小* 2 = -2


Program 2

#include <stdio.h>
#include <limits.h>

int main()
{
    long long bigger = 0;
    int smaller = INT_MAX;

    bigger = smaller;
    bigger *= 2;
    printf("Smaller = %d\n", smaller);
    printf("Bigger = smaller * 2 = %lld\n\n", bigger);

    return 0;
}

输出:

  

较小= 2147483647

     

更大=更小* 2 = 4294967294


我的猜测是程序1尝试将乘法结果存储在与int大小相同的临时存储中。它溢出了。而程序2则将乘法结果存储在较大的存储空间中。

我说错了吗?

另外,如果我在任何一个程序中犯了任何严重的错误,请告诉我(因为根据我的说法,这些程序编译得很完美)!

1 个答案:

答案 0 :(得分:4)

smallerint,文字2也是int。所以他们的产品也是INT_MAX * 2。由于int不能由long long表示(根据定义,相当多),因此会溢出导致未定义的行为。

但是,如果将值存储在long long中,则在执行乘法时,会发生默认的整数提升(“通常的算术转换”)。现在,如果您的INT_MAX * 2可以代表bigger = bigger * (long long)2,那么您最终会得到与{{1}}在语义上等效的内容,它会按预期运行。