符号付きの値よりも符号なしの値を使用するのはいつですか?


82

符号付き変数よりも符号なし変数を使用するのが適切なのはいつですか?何約forループ?

これについてはたくさんの意見を聞いており、コンセンサスに似たものがあるかどうかを知りたいと思いました。

for (unsigned int i = 0; i < someThing.length(); i++) {  
    SomeThing var = someThing.at(i);  
    // You get the idea.  
}

私はJavaは符号なしの値を持っていない知っている、それが上の意識の決断だったに違いないSun Microsystemsの'の部分。


1
私はこれが役に立ったと評価してい:codemines.blogspot.ca/2007/10/...
MK12

この質問はかなり意見に基づいていると思います。提示されたコードはどちらの場合も問題なく実行されるため、両方を使用できます。パフォーマンス上の理由を除いて(これまでのところ、実際にパフォーマンスを扱っている答えはありません)、それは個人的な好みです。
トリラリオン2014年

回答:


69

以前はあまり考えていなかったので、このテーマについて良い会話を見つけうれしかったです。

要約すると、変数に対して算術演算を実行する場合(通常のforループの場合のように)、署名は一般的な選択として適しています。

マスクのようなビット単位のことをするつもりなら、unsignedがより意味をなし始めます。または、符号ビットを利用してその余分な正の範囲を取得したい場合。

個人的には、一貫性を保ち、2つのタイプを混在させないようにすることを自分自身に信頼していないため、署名が好きです(記事が警告しているように)。


3
そのスレッドの後半でunsigned、信頼できない入力のオーバーフローを検出するのに非常に優れていることが示されています。残念ながら、パズルに対して提案された「答え」はそれほど素晴らしいものではありません。私のは、template<size_t limit> bool range_check_sum( unsigned a, unsigned b ) { return (a < limit) && (b < limit - a); } 誰かが署名されたタイプを使用して同様に単純で直接的な答えを持っているなら、私はそれを見たいです。
Ben Voigt 2012

10

上記の例では、「i」が常に正であり、より高い範囲が有益である場合、符号なしが役立ちます。次のような「declare」ステートメントを使用している場合と同様です。

#declare BIT1 (unsigned int 1)
#declare BIT32 (unsigned int reallybignumber)

特にこれらの値が決して変わらない場合。

しかし、人々が彼らのお金に無責任であり、常に赤字である会計プログラムをしているなら、あなたは間違いなく「署名された」を使いたいでしょう。

私は聖人に同意しますが、経験則としては、Cが実際にデフォルトで使用する署名付きを使用することであるため、カバーされます。


9

あなたのビジネスケースで負の数が無効であると指示されている場合は、エラーを表示またはスローする必要があると思います。

そのことを念頭に置いて、バイナリファイルのデータを処理し、データをデータベースに保存するプロジェクトで作業しているときに、符号なし整数について最近知りました。私は意図的にバイナリデータを「破損」させていたため、予期したエラーではなく負の値を取得することになりました。値が変換されたとしても、その値は私のビジネスケースには有効ではないことがわかりました。
私のプログラムはエラーにならず、データベースに間違ったデータを取得することになりました。私が使っuintていて、プログラムが失敗したならもっと良かったでしょう。


8

CおよびC ++コンパイラは、符号付き型と符号なし型を比較す​​ると警告を生成します。サンプルコードでは、ループ変数をunsignedにして、コンパイラに警告なしでコードを生成させることはできませんでした(警告がオンになっていると仮定します)。

当然、警告を完全に上げてコンパイルしていますよね?

そして、それをさらに一歩進めるために、「警告をエラーとして扱う」でコンパイルすることを検討しましたか?

符号付き数値を使用することの欠点は、たとえば、値0-> nがメニュー選択であり、-1は何も選択されていないことを意味するように、それらをオーバーロードしたいという誘惑があることです-2つの変数を持つクラスを作成するのではなく、何かが選択されているかどうかを示し、その選択が何であるかを保存するために別のものを示します。あなたがそれを知る前に、あなたはいたるところにネガティブなものをテストしていて、コンパイラはあなたがメニュー選択をあなたが持っているメニュー選択の数とどのように比較したいかについて不平を言っています-しかしそれらは異なるタイプなので危険です。だからそうしないでください。


6

size_t多くの場合、これには、またはsize_typeSTLクラスを使用している場合に適しています。


バイト単位で何かのサイズを扱っている場合のみ。
mk12 2012

@ mk12標準ライブラリコンテナsize_typeは、バイトだけでなく要素数のメンバーを公開します。std::size_t利用可能な場合は代わりに使用する必要がありますが、で始まるsize_tものがバイトを意味するだけであることを意味するのは不正確です。
underscore_d
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.