web-dev-qa-db-ja.com

C / C ++でのintまたはunsigned intの使用

多くのコード例、ソースコード、ライブラリなどで、私が見る限り、unsigned intがより理にかなっているときに、intの使用を確認します。

私がこれをよく目にする場所の1つは、forループです。以下の例を参照してください:

for(int i = 0; i < length; i++)
{
    // Do Stuff
}

いったいなぜunsigned intではなくintを使うのですか?それはただの怠惰ですか?人々はunsignedとタイプすることに煩わされませんか?

30
developerbmw

unsignedを使用すると、特定が難しいプログラミングエラーが発生する可能性があります。通常は、エラーを回避するためだけに署名付きintを使用することをお勧めします。 1つの例は、前方ではなく後方に反復してこれを書く場合です。

for (unsigned i = 5; i >= 0; i--) {
    printf("%d\n", i);
}

もう1つは、ループ内でいくつかの計算を行う場合です。

for (unsigned i = 0; i < 10; i++) {
    for (unsigned j = 0; j < 10; j++) {
        if (i - j >= 4) printf("%d %d\n", i, j);
    }
}

unsignedを使用すると、この種のバグが発生する可能性があり、実際に利点はありません。

22
Paul Hankin

それは一般的に怠惰または理解の欠如です。

値が負であってはならないときに、私はunsigned intを使用します。これは、正しい値を指定するというドキュメントの目的にも役立ちます。

私見、「unsigned int」よりも「int」を使用する方が安全であるという主張は、単に間違っており、プログラミングの習慣としては不適切です。

AdaまたはPascalを使用したことがある場合は、値に特定の範囲(たとえば、1、2、3、4、5のみを指定できる整数)を指定するというより安全な方法を使用することに慣れています。

10
user3344003

私はプログラミング中にできるだけ明示的にすることを選びました。つまり、値が常に正の変数を使用する場合は、unsignedが使用されます。ここでは多くの人が「バグを見つけるのが難しい」と述べていますが、例を挙げている人はほとんどいません。ここでのほとんどの投稿とは異なり、unsignedを使用するための次の支持者の例を検討してください。

enum num_things {
    THINGA = 0,
    THINGB,
    THINGC,
    NUM_THINGS
};

int unsafe_function(int thing_ID){
    if(thing_ID >= NUM_THINGS)
        return -1;

    ...
}

int safe_function(unsigned int thing_ID){
    if(thing_ID >= NUM_THINGS)
        return -1;

    ...
}

int other_safe_function(int thing_ID){
    if((thing_ID >=0 ) && (thing_ID >= NUM_THINGS))
        return -1;

    ...
}

/* Error not caught */
unsafe_function(-1);

/* Error is caught */
safe_function((unsigned int)-1);

上記の例で、負の値がthing_IDとして渡されるとどうなりますか?最初のケースでは、負の値が以上でないNUM_THINGSので、関数は続行します実行。

2番目のケースでは、thing_IDの符号により、条件付きで符号なし比較が実行されるため、実際に実行時にこれをキャッチします。

もちろん、あなたother_safe_functionのようなことをすることができますが、これは、より明示的で使用するのではなく、符号付き整数を使用する方が得意ではないようです。そもそも符号なし。

5
sherrellbc

lengthintである場合は、同じ整数型を使用する必要があります。そうでない場合、比較ステートメントで符号付きと符号なしの型を混在させると、奇妙なことが起こります。ほとんどのコンパイラーは警告を出します。

あなたは質問を続けることができます、なぜlengthに署名する必要があるのですか?まあ、それはおそらく歴史的なことです。

また、ループを逆にする場合、つまり

for(int i=length-1;i>=0 ;i--)
{
   // do stuff
}

符号なし整数を使用すると、ロジックが壊れます。

3
Mark Lakata

最も重要な理由は、unsigned intを選択すると、いくつかの論理エラーが発生する可能性があることだと思います。実際、多くの場合、unsigned intの範囲は必要ありません。intを使用する方が安全です。

1
Khoi Pham

この小さなコードはユースケースに関連しており、いくつかのベクトル要素を呼び出すと、プロトタイプはintですが、c ++でそれを行うための多くの最新の方法があります。 for(const auto&v:vec){}またはイテレータ、ある計算では負の数を減算/到達できない場合、符号なしを使用する必要があり、期待される値の範囲を説明します。 intが必要ですが、真実はユースケースと状況に関するものであり、すべてのユースケースに1つの厳密なルールが適用されることはなく、強制的に使用するのはちょっとばかげています...

0
LiorA