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。如果较小的类型是有符号的,那么提升的类型是符号扩展的 - 有符号的 char 值-x被提升为具有相同值的有符号 int -x,这在 2 的补码机器中意味着在它前面加上一些0xff字节。如果操作的结果被分配回较小的类型,它会被截断。

您的三个案例适用以下规则:

  1. Unsigned char0xaa提升为 unsigned int 0x00aa, unsigned char提升0x55为 unsigned int 0x0055。取反0x00aa给出0xff55不等于0x0055

  2. 带符号的 char0xaa提升为带符号的 int 0xffaa(负符号值是符号扩展 - 带符号的 char 值-86提升为带符号的 int 值-86),带符号的 char 提升为带0x55符号的 int 0x0055(正带符号的 char 值+85提升为带符号的 int 值+85)。取反0xffaa得到0x0055等于0x0055

  3. Unsigned char0xaa提升为 unsigned int 0x00aa,反转为0xff55然后存储为 unsigned char ,导致它被截断为0x550x55稍后将 unsigned char 与 unsigned char 进行比较,0x55发现相等。

于 2013-06-28T12:26:32.040 回答