2009-07-08 367 views
11

在(char)0xff左移8并将其转换为int时,我们得到-256或0xffffff00。 有人可以解释为什么会发生这种情况吗?在C中向左移(char)0xFF 8并将其转换为int

#include <stdio.h> 
int main (void) 
{ 
    char c = 0xff; 
    printf("%d %x\n", (int)(c<<8),(int)(c<<8)); 
    return 0; 
} 

输出是

-256 ffffff00 

回答

14

char可以是有符号或无符号的 - 它是实现定义的。您会看到这些结果,因为char在您的编译器上被默认签名。

对于已签名的字符0xFF对应-1(这就是两个补码的工作方式)。当您尝试移动它,它首先提升为int,然后转向 - 你有效地256

得到乘法因此,它是这样的代码:

char c = 0xFF; // -1 
int shifted = c << 8; //-256 (-1 * 256) 
printf("%d, %x", shifted, shifted); 
1

char是什么,但有符号的字符。所以char c = 0xFF将是-1。当你左移8位时,你会得到-256。

+11

字符的签名是实现定义的。 – 2009-07-08 10:02:50

3

c为被晋升为int前换班操作完成。假设你的实现使得字符被默认签名,这意味着你将得到0xffffffff,然后向左移动以得到你的结果。

如果你把c变成一个无符号的字符,你应该得到你所期望的。

7

当我第一次看到这个问题时,我最初的观点是char'c'应该左移8位 - 所有8位被丢弃,然后空char被转换为值为0的int。

一点研究显示通常的一元转换 - 这是减少大量算术类型的地方,转换自动应用于一元'!',' - ','〜'和'*'的操作数运算符分配给二进制'< <'和'>>'运算符的每个操作数。

因此char'c'被转换为int 第一个,然后向左移动,给出您看到的答案。

你每天都会学到新的东西!