下面描述的行为是否可预测?
我已将数字编辑为 2147483648 的限制。它似乎仍然有效。这是可以预见的吗?
a.out 执行
e1r4p22% ./a.out
-2147483648
4
主程序
#include <stdio.h>
int main()
{
int i = 2147483648;
i = -i;
printf("%d\n", i);
printf("%lu\n", sizeof(int));
return 0;
}
下面描述的行为是否可预测?
我已将数字编辑为 2147483648 的限制。它似乎仍然有效。这是可以预见的吗?
a.out 执行
e1r4p22% ./a.out
-2147483648
4
主程序
#include <stdio.h>
int main()
{
int i = 2147483648;
i = -i;
printf("%d\n", i);
printf("%lu\n", sizeof(int));
return 0;
}
您更改了问题,这使以前的答案无效。
您的程序的行为通常是不可预测的。
C 标准仅保证int
可以表示范围-32767
为+32767
(16 位)的值。在这样的系统上,常数2147483648
的类型是long
or long long
。
即使int
是 32 位,没有填充位和二进制补码,也在2147483648
的范围之外int
,并且可能是long
或类型long long
。
这个:
int i = 2147483648;
将or值隐式转换为. 结果是实现定义的——或者它可以引发实现定义的信号。long
long long
int
在许多系统上,实现定义的结果将是-2147483648
. 如果是,那么这个:
i = -i;
尝试否定该值,产生超出范围的结果int
。与转换不同,溢出的算术运算符(例如一元)对于有符号类型-
具有未定义的行为。
程序很可能会像在您的系统上那样运行,但是不,就 C 标准而言,它是不可预测的。编译器可以自由地假设您的程序的行为是明确定义的,并基于该假设生成代码,因此它可能以某种意想不到的方式运行实际上是合理的。
还:
printf("%lu\n", sizeof(int));
如果 size_t
(sizeof
操作员的结果)unsigned long
在您的系统上,这将正常工作。如果不是,那么再次,您有未定义的行为。的正确格式size_t
是"%zu"
:
printf("%zu\n", sizeof(int));
这是在 C99 中引入的,因此某些实现(尤其是 Microsoft 的)可能不支持它。您还可以使用强制转换将参数转换为适当的类型:
printf("%lu\n", (unsigned long)sizeof(int));
无论这段代码试图完成什么,几乎可以肯定有一种更清晰的方法来完成它。如果您希望能够操作具有或值的整数2147483648
,则保证足够大。long long
int64_t
根据limits.h
和 with ,int 的限制是 2 147 483 647 sizeof(int) = 4
。所以是的,这是可以预测的,因为 2 147 483 148 < 2 147 483 647。