3
//Using the if-else
#include <iostream>
using std::cin;
using std::cout;
using std::endl;

int main() {
  long number = 0;                  // Store input here
  cout << "Enter an integer less than 2 billion: ";
  cin >> number;
  cout << endl;

  if(number % 2L == 0)              // Test remainder after division by 2
    cout << "Your number is even."  // Here if remainder is 0
         << endl;
  else
    cout << "Your number is odd."   // Here if remainder is 1
         << endl;
  return 0;
}

ここで、最初の 'if' 条件で、2 の後に 'L' があるのはなぜですか? 「L」を削除すると、コードが正常に実行されるようです。

4

2 に答える 2

11

L接尾辞は、数値リテラルの型が であることを示すために使用されますlong int。通常、変数に値を割り当てるだけの場合は必要ありません。C++11 §2.14.2 ¶2 (および特に表 6) に関しては、接尾辞のない 10 進整数リテラルが最初の型になるためです。intlong intまたはの間で表すことができlong long intます。1

したがって、値自体が切り捨てられるリスクはありません。しかし:

  1. リテラルの型についてある程度の不確実性があります(プラットフォーム/コンパイラに応じて32768intまたは aの場合があります)。long
  2. 特定の式に対して間違った型のリテラルを誤って取得する可能性があります。

そのため、リテラルの型が(またはそれより大きい)Lことを確認したいコンテキストで、代わりに指定する必要があります。long次の 2 つの重要なケースが思い浮かびます。

  • オーバーロードの解決; 関数のオーバーロードが 2 つあり、1 つは forintと 1 つは forで、小さい数値を渡す場合でもlong確実に 1 つを呼び出したい場合は、リテラルを使用する必要があります。longlong

    void foo(int);
    void foo(long);
    
    foo(1);      // <-- will call the first overload
    foo(1L);     // <-- will call the second overload
    foo(32768);  // <-- may call the first or the second overload, depending
                 //     from the specific platform
    foo(32768L); // <-- will call the second overload
    
  • しかし、最も重要なことは、算術を行うときに驚きを避けることです。たとえば、次のような乗算を実行する場合:

    int a;
    ...
    long v=32767*a; // don't let the "long" fool you - 32767*a is evaluated as an int!
    

    32767intリテラル ( に収まるほど小さいためint)、aは であり、に代入している場合でもint、結果は になります。計算がオーバーフローするほど大きい場合、これは問題になる可能性があります。リテラルを指定することで、確実に乗算を実行できます。intlongalonglong

    long v=32767L*a; // now we are doing all the math with longs
    

    (この問題は実際には、意図し「実際の除算」の動作を得るためにリテラルdoubleまたはリテラルを指定する必要がある除算および FP リテラルでより頻繁に発生します)float

    @chris示唆するように、「大きな」ビットシフトを行うと、(これと同じ種類の)より頻繁な状況が発生します。

    long long mask=1<<53;
    

    上記と同じ問題を提示します: 1is an int, 53is an int, 計算はints で実行され、オーバーフローが発生します (ただし、この特定のケースでは、まともなコンパイラは警告を発行します)。ここで、正しい形式は次のようになります。

    long long mask=1LL<<53; // LL is the suffix for long long
    

あなたの特定のコードに来てください:奪うことにリスクはありませんLnumberはすでに であるため、longモジュロを実行する際に (「通常の算術変換」、§5 ¶10、および §4.5 に従って) に2昇格されるため、ここでは違いはありません。longL

それでも、多くの場合、「意図した型」のリテラルを保持することは悪い考えではありません。これにより、他のオペランドの型が何らかの理由でより狭い型に変更された場合でも、計算が引き続き行われることが保証されます。意図した方法です(モジュロの場合、違いはありません)。


  1. 整数リテラルの型は、その値を表すことができる表 6 の対応するリストの最初のものです。 整数リテラルに使用される型を説明する C++11 標準の表

于 2013-09-29T01:06:31.767 に答える
0

この場合、その必要はありません。

L長い値を示します。これは、計算が通常の整数の範囲を超えるだけで、より多くのスペースを予約することを意味します。

于 2013-09-29T00:52:40.280 に答える