2013-06-28 62 views
0

经过一些头部划痕之后,我确定签名和未签名的字符在涉及==标志时会有惊人的差异。未签名与已签名问题的比特NOT和比较

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版本。

回答

2

在C和C++中,整数类型比int窄的运算符的操作数得到promoted to an int。如果较小类型被签名,则提升类型为符号扩展 - 将带符号的字符值-x提升为具有相同值-x的带符号整数,其在2的补码机器中意味着以一些0xff字节作为其前缀。如果操作的结果被分配回较小的类型,则会被截断。

  1. 无符号的字符0xaa被提升为unsigned int类型0x00aa和无符号字符0x55到unsigned int类型0x0055

    你三种情况如下应用这些规则。反转0x00aa给出0xff55这不等于0x0055

  2. 符号字符0xaa被提升为有符号整数0xffaa(负号的值是符号扩展 - 符号字符值-86被提升为签署int值-86)和符号字符0x55到符号int 0x0055(正符号的字符值+85被提升为以签署int值+85)。 0xffaa的倒数为0x0055,相当于0x0055

  3. 无符号字符0xaa被提升到无符号整型0x00aa,反转为0xff55然后存储为unsigned char,使其被截断为0x55。后来将无符号字符0x55与无符号字符0x55进行比较,发现它们是相等的。