符号付き値ではなく符号なし値を使用するのはどのような場合ですか?
-
08-06-2019 - |
質問
符号付き変数ではなく符号なし変数を使用するのが適切なのはどのような場合ですか?ではどうでしょうか for
ループ?
これについては多くの意見を聞いていますが、何かコンセンサスに近いものがあるかどうかを確認したいと思いました。
for (unsigned int i = 0; i < someThing.length(); i++) {
SomeThing var = someThing.at(i);
// You get the idea.
}
Java には符号なしの値がないことは知っていますが、それはおそらく意識的な決定だったに違いありません。 サン・マイクロシステムズ' 一部。
解決
見つけてよかったです 良い会話 この件については、これまであまり考えたことがなかったので。
要約すると、(典型的な for ループの場合のように) 変数に対して算術演算を行う場合は、すべての数値が正であることが確実な場合でも、signed は一般的な選択肢として適切です。
マスクなどのビット単位の処理を行う場合は、unsigned の方が理にかなっています。または、符号ビットを利用して追加のプラスの範囲を取得したい場合。
個人的には、一貫性を保ち、2 つのタイプの混合を避けることができるとは信じていないので、署名付きが好きです (記事で警告されているように)。
他のヒント
上記の例では、「i」が常に正であり、より高い範囲が有利である場合、unsigned が役立ちます。次のような「declare」ステートメントを使用している場合と同様です。
#declare BIT1 (unsigned int 1)
#declare BIT32 (unsigned int reallybignumber)
特にこれらの値が決して変更されない場合はそうです。
ただし、人々がお金の使い方に無責任で常に赤字を出している会計プログラムを実行している場合は、間違いなく「signed」を使用したくなるでしょう。
ただし、経験則としては signed を使用するのが良いという saint の意見に同意します。C では実際にこれがデフォルトなので、問題はありません。
C および C++ コンパイラは、符号付き型と符号なし型を比較するときに警告を生成します。サンプルコードでは、ループ変数を符号なしにして、コンパイラに警告なしでコードを生成させることはできませんでした(警告がオンになっていると仮定して)。
当然、警告を最大限に上げてコンパイルしていますよね?
そして、さらに一歩進めるために、「警告をエラーとして扱う」でコンパイルすることを検討しましたか?
符号付き数値を使用する場合の欠点は、2 つの変数を持つクラスを作成するのではなく、値 0->n がメニュー選択であり、-1 は何も選択されていないことを意味するように、それらをオーバーロードする誘惑があることです。何かが選択されているかどうかを示し、もう 1 つはその選択内容を保存します。気づけば、あちこちで負の値をテストしていて、コンパイラは、メニュー選択とメニュー選択の数をどのように比較したいかについて文句を言っていますが、それは危険です。なぜなら、それらはタイプが異なるからです。 。だからそんなことはしないでください。
ビジネスケースで負の数値が無効であると規定されている場合は、次のようにするだろうと思います。 欲しい エラーが表示またはスローされるようにします。
それを念頭に置いて、私はつい最近、バイナリ ファイル内のデータを処理し、そのデータをデータベースに保存するプロジェクトに取り組んでいるときに、符号なし整数について知りました。バイナリデータを意図的に「破損」させたため、予想されるエラーではなく負の値が返されてしまいました。値が変換されたとしても、その値は私のビジネス ケースでは有効ではないことがわかりました。
私のプログラムではエラーは発生しませんでしたが、最終的にはデータベースに間違ったデータを取り込んでしまいました。使えば良かったのに uint
そしてプログラムが失敗してしまいました。
size_t
多くの場合、これには良い選択です。または、 size_type
STL クラスを使用している場合。