【问题标题】:long long int initialization warningslong long int 初始化警告
【发布时间】:2013-11-06 18:03:06
【问题描述】:

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;

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

【问题讨论】:

标签: c


【解决方案1】:

问题在于 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,但会导致溢出——int 表达式不会自动提升为更大的类型。解决方案是再次明确说明文字的类型:

long long num = 1000000LL * 1000000LL;

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

long long num = (long long)1000000 * 1000000;

【讨论】:

  • 但是编译器不会在乘法后自动提升数据类型吗?
  • @rohan013,不适用于 int 类型 - 这是所有操作的首选数据类型。自动类型提升规则有些晦涩难懂,最好有明确的类型协议。只有一个操作数需要是较大的类型,但可以强制结果为较大的类型。
  • 不,警告的意思是“这个十进制常量是无符号的(仅在 ISO C90 中)”。在 C99 和 C11 中,所有无后缀的十进制常量都是有符号类型。有关详细信息,请参阅my answer。在 C90 中,假设 32 位 long1000000000000 的类型为 unsigned long(警告可能更清楚;它使用“无符号”作为形容词,而不是类型名称)。
  • @KeithThompson:1000000000000 至少需要 40 位,因此不能是 unsigned long。 rohan013 说警告是针对4014109449,所以我不清楚你要解释什么。然而你的答案清楚的。
  • 我之前评论中的1000000000000 是复制粘贴错误;我的意思是说4014109449 的类型是unsigned long
【解决方案2】:

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

  • int
  • long int
  • unsigned long int

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

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

  • int
  • long int
  • long long int

可以代表它的价值。

4014109449 恰好可以表示为 32 位 无符号 整数,但不能表示为 32 位 有符号 整数。假设您的系统有 32 位 longs,则该常量的类型在 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 位 ints,常数 1000000 的类型为 int,并且两个 int 值相乘的结果也是 int 类型。在这种情况下,乘法将溢出。同样,您可以通过确保常量的类型为 long long int 来避免该问题:

long long int num = 1000000LL * 1000000LL;

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-15
    • 2011-02-05
    • 2018-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-29
    • 1970-01-01
    相关资源
    最近更新 更多