多くのコード例、ソースコード、ライブラリなどで、私が見る限り、unsigned int
がより理にかなっているときに、intの使用を確認します。
私がこれをよく目にする場所の1つは、for
ループです。以下の例を参照してください:
for(int i = 0; i < length; i++)
{
// Do Stuff
}
いったいなぜunsigned int
ではなくint
を使うのですか?それはただの怠惰ですか?人々はunsigned
とタイプすることに煩わされませんか?
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
を使用すると、この種のバグが発生する可能性があり、実際に利点はありません。
それは一般的に怠惰または理解の欠如です。
値が負であってはならないときに、私はunsigned intを使用します。これは、正しい値を指定するというドキュメントの目的にも役立ちます。
私見、「unsigned int」よりも「int」を使用する方が安全であるという主張は、単に間違っており、プログラミングの習慣としては不適切です。
AdaまたはPascalを使用したことがある場合は、値に特定の範囲(たとえば、1、2、3、4、5のみを指定できる整数)を指定するというより安全な方法を使用することに慣れています。
私はプログラミング中にできるだけ明示的にすることを選びました。つまり、値が常に正の変数を使用する場合は、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
のようなことをすることができますが、これは、より明示的で使用するのではなく、符号付き整数を使用する方が得意ではないようです。そもそも符号なし。
length
もint
である場合は、同じ整数型を使用する必要があります。そうでない場合、比較ステートメントで符号付きと符号なしの型を混在させると、奇妙なことが起こります。ほとんどのコンパイラーは警告を出します。
あなたは質問を続けることができます、なぜlength
に署名する必要があるのですか?まあ、それはおそらく歴史的なことです。
また、ループを逆にする場合、つまり
for(int i=length-1;i>=0 ;i--)
{
// do stuff
}
符号なし整数を使用すると、ロジックが壊れます。
最も重要な理由は、unsigned int
を選択すると、いくつかの論理エラーが発生する可能性があることだと思います。実際、多くの場合、unsigned int
の範囲は必要ありません。int
を使用する方が安全です。
この小さなコードはユースケースに関連しており、いくつかのベクトル要素を呼び出すと、プロトタイプはintですが、c ++でそれを行うための多くの最新の方法があります。 for(const auto&v:vec){}またはイテレータ、ある計算では負の数を減算/到達できない場合、符号なしを使用する必要があり、期待される値の範囲を説明します。 intが必要ですが、真実はユースケースと状況に関するものであり、すべてのユースケースに1つの厳密なルールが適用されることはなく、強制的に使用するのはちょっとばかげています...