0

少し頭を悩ませた後、== 記号に関しては、符号付き文字と符号なし文字には驚くべき違いがあることがわかりました。

void loop()
{
}

void setup()
{
  unsigned char ucA = 0x55;
  unsigned char ucB = 0xAA;
  unsigned char ucB_not;

  char cA = 0x55;
  char cB = 0xAA;

  Serial.begin( 115200);

  if ( ucA == ~ucB)
    Serial.println( "unsigned -- match");
  else
    Serial.println( "unsigned -- no match");


  if ( cA == ~cB)
    Serial.println( "signed -- match");
  else
    Serial.println( "signed -- no match");

  ucB_not = ~ucB;
  if ( ucA == ucB_not)
    Serial.println( "unsigned, seperate variable -- match");
  else
    Serial.println( "unsigned, seperate variable -- no match");

}

私が得る出力は次のとおりです。

unsigned -- no match
signed -- match
unsigned, seperate variable -- match

比較の前に値が拡大されるという規則はありますか? そうだとしても、署名のないケースは問題にならないはずですよね?

最後のケースを追加しました - 別の変数を作成しても問題はないようです。

私はArduinoリリース1.0.5を使用しています。

4

1 に答える 1

2

C と C++ の両方で、 int より狭い整数型である演算子のオペランドは int に昇格されます。小さい方の型が signed の場合、プロモートされた型は符号拡張されます。signed char 値-xは、同じ値の signed int にプロモートされます-x。これは、2 の補数のマシンでは、それにいくつかの0xffバイトをプレフィックスとして付けることを意味します。演算の結果が小さい方の型に代入されると、切り捨てられます。

あなたの 3 つのケースは、これらのルールを次のように適用します。

  1. unsigned char0xaaは unsigned int に昇格し、 unsigned 0x00aacharは0x55unsigned int に昇格し0x0055ます。を反転すると、 に等しくない が0x00aa得られます。0xff550x0055

  2. signed char0xaaは signed int に昇格され0xffaa(負の signed 値は符号拡張されます - signed char 値-86は signed int 値に昇格されます-86)、signed char0x55は signed intに昇格され0x0055ます (正の signed char 値+85は signed int 値に昇格されます+85)。を反転すると に等しい が0xffaa得られます。0x00550x0055

  3. unsigned char0xaaは unsigned int に昇格され0x00aa、反転0xff55されてから unsigned char として格納されるため、切り捨てられて0x55. unsigned char0x55は後で unsigned char と比較0x55され、等しいことがわかります。

于 2013-06-28T12:26:32.040 に答える