2个问题
首先,而
long long int num = 1000000000000;
工作正常
long long int num = 4014109449;
给出
warning: this decimal constant is unsigned only in ISO C90 [enabled by default]
这是什么意思?
其次
long long int num = 1000000*1000000;
发出溢出警告 而
long long int num = 1000000000000;
没关系,即使它们是相同的。我如何摆脱它?乘法给出了垃圾值
答案 0 :(得分:10)
问题是值4014109449
在C90中是unsigned long int
但在C99中是long long int
,因为它对于32位long int
来说太大了。虽然1000000000000
对于任何 32位类型而言太大,但自动为long long int
。该警告涉及C90和C99之间的行为不同这一事实。
解决方案是通过使用适当的类型后缀强制文字和变量类型之间的类型协议。在这种情况下:
long long num = 4014109449LL ;
或使用类型转换:
long long num = (long long)4014109449 ;
类似地,表达式1000000 * 1000000
是两个int
类型的乘法并且具有int
结果,但会导致溢出 - 没有自动提升为{{1的更大类型表达式。解决方案再次明确关于文字的类型:
int
或者您也可以在一个或两个操作数上使用类型转换。
long long num = 1000000LL * 1000000LL;
答案 1 :(得分:4)
在C90中,未填充的十进制整数常量(字面值)的类型是
的第一个int
long int
unsigned long int
可以代表其值而不会溢出。
在C99及更高版本中,它是第一个
int
long int
long long int
可以代表它的价值。
值4014109449
恰好可以表示为32位 unsigned 整数,但不能表示为32位 signed 整数。假设您的系统具有32位long
s,则该常量的类型在C90中为unsigned long int
,在C99和C11中为long long int
。
这就是警告告诉你的。常量的类型根据编译器符合的C标准版本而变化。
请注意,无论其类型如何,4014109449
的值始终都是正确的,并且在您的声明中:
long long int num = 1000000000000;
该值始终会正确转换为long long
。但它肯定不会伤害(并且会使警告静音)添加LL
后缀以明确表示您想要类型为long long
的值:
long long int num = 1000000000000LL;
至于此:
long long int num = 1000000*1000000;
假设您有32位int
s,则常量1000000
的类型为int
,并且将两个int
值相乘的结果也是int
类型的结果1}}。在这种情况下,乘法将溢出。同样,您可以通过确保常量类型为long long int
来避免此问题:
long long int num = 1000000LL * 1000000LL;
(请注意,您可以使用小写ll
,但这是一个坏主意,因为很难区分字母l
和数字{{1} }。)