编辑(更正)(我错过了重点。我的答案对常量是正确的,但问题包含函数的参数,那么这里发生的是有符号整数对象的溢出,正如@Cornstalks 在他的评论中正确指出的那样,这是未定义的行为)。
/编辑
在fun1()
您printf()
以错误的方式使用。
你写信"%d"
接受一个int
,但如果你的数字大于那个,那就不是真的MAX_INT
。
您必须检查MAX_INT
系统中的值。
如果您以十六进制格式编写整数常量,则标准 C(ISO C99 或 C11)会尝试按照以下顺序将该值放入常量可以容纳的第一种类型:
整数,无符号整数,长整数,无符号长整数,长整数,无符号长整数。
因此,如果您有一个大于MAX_INT
(范围内的最大值int
)的常数,则您的常数(如果为正)具有类型unsigned int
,但指令%d
需要一个signed int
值。因此,它将显示一些负数。
最糟糕的是,如果您的常量的值大于UMAX_INT
(范围内的最大值unsigned int
),那么常量的类型将是 的第一个long int, unsigned long int, long long int
,精度严格大于 的unsigned int
。
这意味着%d
成为错误的指令。
如果您不能完全确定您的值有多大,您可以强制转换为最大的整数类型:
printf("%lld", (long long int) 0x33333333333);
该指令%lld
代表long long int
.
如果您始终对正值感兴趣,则必须使用%llu
并转换为unsigned long long int
:
printf("%llu", (unsigned long long int) 0x33333333333);
通过这种方式,您可以避免任何“有趣”的数字,就像在不损失任何精度的情况下显示大数字一样。
备注:常量INT_MAX
、UINT_MAX
等在limits.h中。
重要提示:自动转换序列仅对八进制和十六进制常量有效。对于十进制常量,还有另一条规则:
整数,长整数,长整数。