0

下手な英語でごめんなさい。

uint16_t a, c;
uint8_t b = 0xff;

a = b<<8;
c = b*10;

の値とは何aですかc? 任意の整数型の状況とは?

4

1 に答える 1

0
uint16_t a, c;
uint8_t b = 0xff;

a = b<<8;

まず、の引数に対して整数昇格が実行されます<<。定数8はanintであるため、変換されません。の変換ランクは、の変換ランクuint8_tよりも小さく、のintすべての値はsuint8_tとして表現できるため、の値を保持して、に変換されます。結果の値は、8ビット左にシフトされます。intbintint

intが16ビット幅しかない場合、値0xff * 2^8はとして表現できません。その場合int、シフトは未定義動作を呼び出します。n1570およびC99では6.5.7(4)です。

E1に符号付きタイプと非負の値があり、E1×2 E2が結果タイプで表現可能である場合、それが結果の値です。それ以外の場合、動作は定義されていません。

それ以外の場合、結果は255*256 = 65280 = 0xFF00です。その値はのタイプで表現できるため、シフトaの結果を変換して値を保持します。結果が範囲外の場合(たとえば、シフト距離が9 [および十分に広い]の場合)、からの範囲の値を取得するためにモジュロで削減されます。intuint16_tint2^1602^16 - 1uint16_t

c = b*10;

通常の算術変換は、のオペランドに対して実行されます*。両方のオペランドは整数型であるため、最初に整数拡張が実行されます。10はであり、の型のintすべての値はbとして表現できるため、int整数拡張は両方のオペランドに同じ型を与えint、通常の算術変換ではそれ以上の変換は必要ありません。乗算はタイプで行われint、その結果は2550、タイプで再び表現できるため、値をに格納する前にc変換が行われ、値が保持されます。uint16_tc

任意の整数型の状況はどうですか?

の場合<<

  1. 整数プロモーション; int変換ランクが(および)の整数型以下の整数型の値/式unsigned int[幅<=が]の整数型、および(unsigned) int型のビットフィールドは、またはに変換されます(それがのすべての値を表すことができる場合)元のタイプ、それ以外の場合)。_Boolintsigned intunsigned intintunsigned intintunsigned int

  2. (プロモートされた)右オペランド(シフト距離)が負であるか、(プロモートされた)左オペランドの幅(値ビットと符号ビットの数。符号ビットが1つあるか、まったくない)以上の場合、動作は次のようになります。未定義。(プロモートされた)左オペランドの値が負の場合、動作は未定義です。(プロモートされた)左オペランドのタイプが符号なしの場合、結果はvalue * 2^distanceモジュロを法として減少し2^widthます。(プロモートされた)左オペランドのタイプが符号付きで、値が非負の場合、結果はvalue * 2^distance、それがタイプで表現可能である場合、それ以外の場合の動作は未定義です。

  3. 2.で未定義の動作が発生しなかった場合、結果は格納されている変数のタイプに変換されます。

    • ターゲットタイプが_Bool(またはそのエイリアス)の場合、ゼロ以外の結果は1に変換され、ゼロ以外の結果は0に変換されます。
    • 結果をターゲットタイプで表すことができる場合は、その値が保持されます。それ以外の場合は、その値が保持されます。
    • ターゲットタイプが符号なしの場合、結果はモジュロで減少し2^widthます。それ以外の場合、結果はモジュロで減少します。
    • 結果は実装定義の方法で変換されるか、実装定義のシグナルが発生します。

の場合*

  1. 通常の算術変換が実行されるため、両方の(変換された)オペランドは同じタイプになります。
  2. 乗算は、結果の型で実行されます。それが符号付き整数型であり、乗算がオーバーフローした場合、動作は未定義です。
  3. 結果は、上記と同じ方法でターゲットタイプに変換されます。

これが抽象マシンの定義方法です。実装が別の方法で同じ結果(動作が定義されている場合)を達成できる場合は、as-ifルールの下で好きなように実行できます。

于 2012-12-09T13:36:11.893 に答える