2009-09-22 49 views
75

我在GNU公司的C尝试这种代码++编译器,但无法了解其行为:长长的C/C++

#include <stdio.h>; 

int main() 
{ 
    int num1 = 1000000000; 
    long num2 = 1000000000; 
    long long num3; 
    //num3 = 100000000000; 
    long long num4 = ~0; 

    printf("%u %u %u", sizeof(num1), sizeof(num2), sizeof(num3)); 
    printf("%d %ld %lld %llu", num1, num2, num3, num4); 
    return 0; 
} 

当我去掉了注释行,代码不编译,并给人一种错误:

error: integer constant is too large for long type

但是,如果代码被编译,因为它是和被执行,它会产生比10000000000.

为什么更大的价值?

+6

现在可能已经太晚了,但对于未来的读者,我建议你使用''并使用'uint64_t'。要显示一个64位的值,'printf(“%PRIu64”\ n“,val);' – enthusiasticgeek 2012-08-13 15:36:17

回答

136

字母100000000000组成一个文字整数常量,但对于类型int,该值太大。您需要使用后缀来改变文字的类型,即

long long num3 = 100000000000LL; 

后缀LL,使文字变成long long类型。 C不足以从左边的类型得出结论,类型是文本本身的一个属性,而不是它被使用的上下文。

+42

回答这个问题的答案可能是正确的,但是现在C++标准说明了一个整型后缀是“int”,“long int”和“long long int”中的第一个,其值可以表示。 [C++§2.14.2/ 2]因此,现在不需要将'LL'后缀添加到对其他类型太大的整数文字中。 – bames53 2012-01-04 21:48:42

+8

之前出现这个问题的原因并不是因为C++不够聪明,无法从被分配的变量类型中确定文字类型,而只是因为编译器扩展没有实现扩展整数类型,使其能够与标准语言一起使用。 C++现在的规则是任何扩展整数类型都可以更好地与标准集成:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1988。pdf – bames53 2012-01-04 21:49:07

+4

@unwind我认为应该根据这些建议来编辑答案。 – Antonio 2013-06-22 20:12:00

25

尝试:

num3 = 100000000000LL; 

而且顺便说一句,在C++中,这是一个编译器扩展,该标准没有定义长长,这就是C99的一部分。

+10

那么,C++ 11现在定义了long long – 2014-08-02 01:30:31

1

您的代码编译在这里罚款(即使该行注释。不得不将其更改为

num3 = 100000000000000000000; 

开始得到警告。

+0

什么编译器?在C++中,整数文字是它适合的int或long中较小的一个。在C99中,它是int中最小的一个,long和long中的最小者。所以,当把C++作为一个非标准的扩展插入很长时间时,也许你的编译器也采用了C99的文字规则。 – 2009-09-22 09:42:29

+0

gcc版本4.3.2(Debian 4.3.2-1.1)在64位Linux系统上。 – 2009-09-22 09:56:41

+0

哦,无论如何,这么长时间是64位,对吧?说得通。 – 2009-09-22 10:56:55

3

这取决于你正在编译什么模式。长长的IS而不是C++标准的一部分,但只支持(通常)作为扩展名,这会影响文字的类型,如果int足够大,则不带任何后缀的十进制整数文字总是为int 表示数字,否则为long。数字甚至太长,结果是实现定义(第24页) robably只是一些类型的long int,为了向后兼容而被截断)。在这种情况下,您必须明确使用LL后缀来启用长时间的扩展(在大多数编译器上)。

下一个C++版本将正式支持很长一段时间,除非您明确希望强制文字类型至少长很长,否则不需要任何后缀。如果编号不能长时间表示,编译器会自动尝试使用很长时间,即使没有LL后缀。我相信这也是C99的行为。