2

このトピックは、多くのコンテキストで頻繁に議論されてきました。いくつかの投稿を検索して読んだとき。次の投稿で混乱しました。

Cでの符号付きから符号なしへの変換 - 常に安全ですか?

以下は元の質問です。

unsigned int u = 1234;
int i = -5678;
unsigned int result = u + i;

答えは単に「6.3.1.8 通常の算術変換」のポイント 3、つまり、

それ以外の場合、符号なし整数型のオペランドのランクが他のオペランドの型のランク以上である場合、符号付き整数型のオペランドは符号なし整数型のオペランドの型に変換されます。

ただし、私の理解が正しければ、「通常の算術変換」を検討する前に整数昇格を行う必要があります。

そしてそのためのルールは

int が元の型のすべての値を表すことができる場合、値は int に変換されます。それ以外の場合は、 unsigned int に変換されます。これらの変換規則は積分昇格と呼ばれます

つまり、加算はunsigned intよりもsigned intの型で完了することを意味します。また、 unsigned intの結果に負を代入すると、大きな値への変換が発生します。

私は自分の理解に少し自信がありません。誰かがその投稿について同様の混乱を抱えていますか?

返信やコメントは大歓迎です。よろしくお願いします!

ジェフ

4

3 に答える 3

3
unsigned int result = u + i;

加算演算子があります。算術型のオペランドを持つ加算演算子は、最初に通常の算術変換を実行します。

通常の算術変換は、次の 2 つのステップで行われます。

最初の整数整数昇格が各オペランドに適用されます。

  • uintそのまま昇進しないunsigned int
  • iはすでにintです。昇格させる必要はありませんint

オペランドの実際の型ランクは に等しいintため、整数昇格は実行されません。

次に、オペランドを共通の型にします。一般的なタイプはunsigned int.

  • uもうunsigned int
  • iintであり、に変換されますunsigned int

通常の算術変換の後、 type の 2 つの値unsigned intが加算され、結果が に割り当てられresultます。

于 2014-02-12T10:41:54.217 に答える
2

ただし、私の理解が正しければ、「通常の算術変換」を検討する前に整数昇格を行う必要があります。

正しいが、整数昇格規則で定義されている整数昇格は、char や short などの小さい整数型にのみ適用されます。あなたは段落の半分しか引用していないので、混乱したかもしれません。その段落全体を引用しましょう。

C11 6.3.1.1/2

以下は、int または unsigned int を使用できる式で使用できます。

  • 整数変換ランクが int および unsigned int のランク以下である整数型 (int または unsigned int 以外) のオブジェクトまたは式。

  • _Bool、int、signed int、または unsigned int 型のビット フィールド。

int が元の型のすべての値を表すことができる場合 (ビットフィールドの幅によって制限されるため)、値は int に変換されます。それ以外の場合は、unsigned int に変換されます。これらは 整数プロモーションと呼ばれます。他のすべての型は、整数の昇格によって変更されません。

したがって、変換ランクが低くないため、整数昇格はintまたはには適用されません。unsigned int

つまり、unsigned int よりも signed int の型で加算が完了するということです。また、unsigned int の結果に負を代入すると、大きな値への変換が発生します。

通常の算術変換が原因で、加算は ussigned int で行われます。

于 2014-02-12T11:18:30.343 に答える
0

問題を説明するために16進数表現を使用します...

int変数のサイズが 32 ビットであると仮定すると、次のようになります。

  • +1234 = 0x000004D2
  • -5678 = 0xFFFFE9D2

を行うとき、それらのそれぞれがどのように表されているか (または) は問題a+bはありません。上記の 2 つの値を加算し、結果を変数に格納すると、各オペランドの符号に関係なく、0xFFFFEEA4 の値が保持されます。signedunsignedint

  • 出力変数が の場合、signed(他の操作では) -4444 として扱われます。
  • 出力変数が の場合、unsigned(他の操作では) 4294962852 として扱われます。
于 2014-02-12T10:59:19.877 に答える