2009-09-22 11 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; 
} 

私はコメント行のコメントを解除すると、コードがコンパイルされないと与えていますエラー:コードをそのままコンパイルされ、実行された場合

はしかし、それは

なぜ10000000000.よりもはるかに大きい値を生成する

error: integer constant is too large for long type

+6

今は遅すぎるかもしれませんが、将来の読者のためには、 ''を使用し、 'uint64_t'を使うことをお勧めします。 'printf("% "PRIu64" \ n "、val);' – enthusiasticgeek

答えて

136

文字100000000000は文字定数定数を構成しますが、値がタイプintに対して大きすぎます。あなたは接尾辞LLがタイプlong longにリテラルを作る

long long num3 = 100000000000LL; 

すなわち

、リテラルの種類を変更する接尾辞を使用する必要があります。 Cは左の型からこれを結論づけるのに十分スマートではなく、型はそれが使用されているコンテキストではなく、リテラル自体のプロパティです。

+42

この返答が書かれた時、おそらく正しいはずでしたが、C++標準では、接尾辞はその値が表現できる 'int'、' long int'、 'long long int'の最初です。 [C++§2.14.2/ 2]したがって、他の型には大きすぎる整数リテラルに 'LL'接尾辞を追加する必要はありません。 – bames53

+8

これは以前の問題だった理由は、C++が割り当てられる変数の型からリテラル型を決定するのに十分なほどスマートではなかったためではなく、コンパイラ拡張が拡張型それが標準言語とうまく動作するような整数型でなければなりません。 C++には拡張された整数型が標準とよりよく統合されるような規則が追加されています:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1988pdf – bames53

+4

@unwind私はこれらの提案に従って答えを編集すべきだと思います。 – Antonio

25

試してみてください。

num3 = 100000000000LL; 

そしてところで、C++で、これはコンパイラの拡張機能である、標準は長い長い定義していない、C99の一部のthats。

+10

さて、C++ 11はlong longを定義しています –

1

あなたのコードは。でも、コメントを外し、その行と(ここでは罰金コンパイル警告を取得を開始する

num3 = 100000000000000000000; 

にそれを変更しなければならなかった。長い長いですそれはあなたがコンパイルされているどのようなモードに依存

+0

どのようなコンパイラですか? C++では、整数リテラルは、それが収まるintまたはlongのうち小さい方です.C99では、int、long、long longの中で最小です。だから、C++に非標準の拡張機能として長い間長い時間を使うと、あなたのコンパイラはおそらくリテラルに対してC99のルールを採用しているのかもしれません。 –

+0

gccバージョン4.3.2(Debian 4.3.2-1.1)を64ビットLinuxシステムにインストールします。 –

+0

ああ、とにかく64ビットはとにかく長いですよね?意味をなさない –

3

。接尾辞を持たない10進整数リテラルは常にint型ですintが大きい場合は数字を表すには、それ以外の場合は長くします。数が大きすぎて実装が定義されていない(p背部互換性のために切り捨てられているlong int型の数)この場合、(ほとんどのコンパイラで)long long拡張を有効にするには、LLサフィックスを明示的に使用する必要があります。

次のC++バージョンは、明示的にリテラルの型を少なくともlong longにする必要がある場合を除き、サフィックスは必要ありません。数を長く表現できない場合、コンパイラは自動的にLL接尾辞がなくてもlong longを使用しようとします。私はこれもC99の行動だと信じています。