8

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;

没关系,即使它们是相同的。我该如何摆脱它?乘法给出一个垃圾值

4

2 回答 2

10

问题是该值在 C90 中是 a 而4014109449在C99 中是 a 因为它对于 32-bit 来说太大了。虽然对于任何32 位类型来说都太大了,但. 该警告与 C90 和 C99 之间的行为不同这一事实有关。unsigned long intlong long intlong int1000000000000long long int

解决方案是通过使用适当的类型后缀来强制字面量和变量类型之间的类型一致。在这种情况下:

long long num = 4014109449LL ;

或使用类型转换:

long long num = (long long)4014109449 ;

类似地,表达式1000000 * 1000000是两种int类型的乘积并有int结果,但会导致溢出 - 表达式不会自动提升为更大的类型int。解决方案再次明确说明文字的类型:

long long num = 1000000LL * 1000000LL;

或者您也可以在一个或两个操作数上使用类型转换。

long long num = (long long)1000000 * 1000000;
于 2013-11-06T18:14:04.907 回答
4

在 C90 中,无后缀十进制整数常量(字面量)的类型是第一个

  • int
  • long int
  • unsigned long int

可以表示其值而不会溢出。

在 C99 及更高版本中,它是第一个

  • int
  • long int
  • long long int

可以代表它的价值。

该值4014109449恰好可以表示为 32 位无符号整数,但不能表示为 32 位有符号整数。假设您的系统具有 32 位longs,则该常量的类型unsigned long int在 C90、long long intC99 和 C11 中。

这就是警告告诉你的。常量的类型会根据您的编译器所遵循的 C 标准版本而有所不同。

请注意,无论其类型如何,值4014109449始终是正确的,并且在您的声明中:

long long int num = 1000000000000;

该值将始终正确转换为long long. LL但是添加一个后缀以明确表示您想要一个 type 的值肯定不会有什么坏处(并且会使警告静音)long long

long long int num = 1000000000000LL;

至于这个:

long long int num = 1000000*1000000;

假设你有 32 位ints,常量1000000是 type int,两个int值相乘的结果也是 type int。在这种情况下,乘法将溢出。同样,您可以通过确保常量为 type 来避免该问题long long int

long long int num = 1000000LL * 1000000LL;

(请注意,您可以使用小写字母ll,但这是个坏主意,因为很难区分字母l和数字1。)

于 2013-11-06T18:37:46.243 回答