1

这个问题应该是基本的,但我很惊讶我现在遇到了一些麻烦。第一个是当我浏览“C++ 入门”一书第 5.3 章时。位运算符,当作者使用以下代码作为示例来解释移位操作时:

unsigned char bits = 1;     // '10011011' is the corresponding bit pattern
bits << 1;                  // left shift

当我看到这个时,我的头有点旋转,'10011011'来自哪里?“1”不是“0x01”?

另一个问题来自http://c-faq.com/strangeprob/ptralign.html,作者尝试解压结构:

struct mystruct {
    char c;
    long int i32;
    int i16;
} s;

使用

unsigned char *p = buf;

s.c = *p++;

s.i32 = (long)*p++ << 24;
s.i32 |= (long)*p++ << 16;
s.i32 |= (unsigned)(*p++ << 8);  // this line !
s.i32 |= *p++;

s.i16 = *p++ << 8;
s.i16 |= *p++;

我的问题是,p 是指向 unsigned char(8 位)的指针,对吧?在构建 s.i32(24~31, 16~23) 的更高字节时,*p++ 在左移之前会转换为 'long'(32bits),因此左移不会在 *p++ 中丢失位,但在

s.i32 |= (unsigned)(*p++ << 8);

*p++ 先移位,然后转换为 unsigned int,*p++ 的位不会在移位过程中全部丢失吗?

我再次意识到我可能在这里错过了 C 语言的一些基础知识。希望有人可以在这里伸出援手。

谢谢,

4

2 回答 2

3

要回答您的第二个问题,对 a 执行任何算术运算都会将其char提升为 a (可能是无符号的)int(包括移位和其他按位运算),因此会移位整数大小的值,而不是 8 位 char 值。

于 2012-09-24T00:58:15.867 回答
0

是的,1 的位模式是 0x01。10011011 是十进制 155 的位模式。

至于班次,你错过了一种叫做“积分提升”的东西,它是在算术和二进制运算中执行的,比如班次。在这种情况下,有一个unsigned char操作数 ( *p++) 和一个int操作数(常量),所以unsigned char操作数被转换为int. 演员表(无论是 tolong还是 to unsigned int)总是在升级和轮班执行之后执行。所以不,在所有移位中都没有丢失所有位。

于 2012-09-24T01:08:28.357 回答