C 理解带有'int'和'long'变量的整数溢出

C 理解带有'int'和'long'变量的整数溢出,c,integer-overflow,C,Integer Overflow,为什么这些程序产生不同的输出 : #包括 #包括 int main() { 长大于等于0; int较小=int_最大值; 较大=较小*2; printf(“更小=%d\n”,更小); printf(“较大=较小*2=%lld\n\n”,较大); 返回0; } 输出: 较小的=2147483647 较大=较小*2=-2 : #包括 #包括 int main() { 长大于等于0; int较小=int_最大值; 更大=更小; 更大*=2; printf(“更小=%d\n”,更小); printf

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

:
#包括
#包括
int main()
{
长大于等于0;
int较小=int_最大值;
较大=较小*2;
printf(“更小=%d\n”,更小);
printf(“较大=较小*2=%lld\n\n”,较大);
返回0;
}
输出:

较小的=2147483647

较大=较小*2=-2


:
#包括
#包括
int main()
{
长大于等于0;
int较小=int_最大值;
更大=更小;
更大*=2;
printf(“更小=%d\n”,更小);
printf(“较大=较小*2=%lld\n\n”,较大);
返回0;
}
输出:

较小的=2147483647

较大=较小*2=4294967294


我猜程序1试图将乘法结果存储在与
int
大小相同的临时存储器中。所以它溢出了。然而,程序2将乘法结果存储在较大的存储器中

我说得对吗


此外,如果我在任何一个程序中犯了任何严重错误,请让我知道(因为根据我的说法,这些程序编译得非常完美)

较小的
int
,文字
2
也是。所以他们的产品也是
int
。由于
INT\u MAX*2
不能用
INT
表示(根据定义,几乎可以),它会溢出,导致未定义的行为


但是,如果将值存储在
long
中,则在执行乘法时,会发生默认整数提升(“常用算术转换”)。现在,如果你的
long-long
可以表示
INT\u MAX*2
,那么你最终会得到一个语义上与
biger=biger*(long-long)2
等价的东西,正如预期的那样工作。

small
INT
,文字
2
。所以他们的产品也是
int
。由于
INT\u MAX*2
不能用
INT
表示(根据定义,几乎可以),它会溢出,导致未定义的行为


但是,如果将值存储在
long
中,则在执行乘法时,会发生默认整数提升(“常用算术转换”)。现在,如果你的
long-long
可以表示
INT\u MAX*2
,那么你最终会得到一个语义上与
biger=biger*(long-long)2
等价的东西,正如预期的那样工作。

这是为那些不理解“如果你的
long-long
可以表示
INT\u MAX*2
的人准备的附录位:
INT\u MAX==LLONG\u MAX
可能为真,在这种情况下,结果将溢出。@ChronoKitsune,有趣。你知道
INT_MAX==allong_MAX
是真的吗?@AnishRam我不知道有这样的实现,但尽可能保持可移植性并没有什么坏处。我无法想象一个嵌入式系统会使
int
64位,但是一个更现实的类似系统实际上可能有
CHAR\u bit=32
,在这种情况下,它可能与
int
相同,甚至可能是
。这一切都是理论上的,但如果你能梦想,你就可以构建它。对于那些不理解“如果你的
long
可以表示
INT\u MAX*2
”位的人来说,一个附录:
INT\u MAX==LLONG\u MAX
可能是真的,在这种情况下,结果将溢出。@ChronoKitsune,很有趣。你知道
INT_MAX==allong_MAX
是真的吗?@AnishRam我不知道有这样的实现,但尽可能保持可移植性并没有什么坏处。我无法想象一个嵌入式系统会使
int
64位,但是一个更现实的类似系统实际上可能有
CHAR\u bit=32
,在这种情况下,它可能与
int
相同,甚至可能是
。这都是理论上的,但如果你能梦想它,你就能建造它。
#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;
}
#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;
}