很长一段时间用C/C++

sud*_*03r 82 c++ types long-integer

我在GNU的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;
}
Run Code Online (Sandbox Code Playgroud)

当我取消注释注释行时,代码不会编译并给出错误:

错误:对于long类型,整数常量太大

但是,如果代码按原样编译并执行,则会产生远大于10000000000的值.

为什么?

unw*_*ind 143

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

long long num3 = 100000000000LL;
Run Code Online (Sandbox Code Playgroud)

后缀LL使文字成为类型long long.C不是"智能"足以从左侧的类型得出结论,类型是文字本身的属性,而不是使用它的上下文.

  • 回到这个答案的时候写的可能是正确的,但现在C++标准说没有后缀的整数文字的类型是`int`,`long int`和`long long int`中的第一个,其值为可以代表.[C++§2.14.2/ 2]因此,现在没有必要将"LL"后缀添加到对于其他类型来说太大的整数文字中. (44认同)
  • 之前出现这个问题的原因不是因为C++不够"聪明",无法根据所分配的变量类型来确定文字类型,它只是因为编译器扩展没有实现扩展整数键入以使其与标准语言一起使用.C++现在有一些规则,任何扩展的整数类型都可以更好地与标准集成:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1988.pdf (8认同)
  • @unwind我认为答案应该根据这些建议进行编辑. (4认同)

Ark*_*nez 25

尝试:

num3 = 100000000000LL;
Run Code Online (Sandbox Code Playgroud)

而BTW,在C++中这是一个编译器扩展,标准没有定义long long,那就是C99的一部分.

  • 好吧,C++ 11现在定义了long long (11认同)

sel*_*tze 5

这取决于您编译的模式。long long 不是 C++ 标准的一部分,但仅(通常)作为扩展支持。这会影响文字的类型。如果 int 大到足以表示数字,没有任何后缀的十进制整数文字总是 int 类型,否则为 long。如果数字对于 long 来说太大,则结果是实现定义的(可能只是为了向后兼容而被截断的 long int 类型的数字)。在这种情况下,您必须明确使用 LL 后缀来启用 long long 扩展(在大多数编译器上)。

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