这个问题应该是基本的,但我很惊讶我现在遇到了一些麻烦。第一个是当我浏览'C ++ primer'一书的第5.3章。 Bitwise Operators,当作者使用下面的代码作为例子来解释移位操作时:
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'(32位),因此左移不会在* p ++中丢失位,而是在
s.i32 |= (unsigned)(*p++ << 8);
* p ++首先被移位,然后转换为unsigned int,在移位期间* p ++的所有位都不会丢失吗?
我再次意识到我可能会错过C中的一些基础知识。希望有人能在这里伸出援助之手。
谢谢,
答案 0 :(得分:3)
要回答第二个问题,对char
执行任何算术运算会将其提升为(可能是无符号的)int
(包括移位和其他按位运算),所以移位整数大小的值,而不是8位字符值。
答案 1 :(得分:0)
是1的位模式是0x01。 10011011是十进制155的位模式。
至于转变,你会遗漏一些叫做“整体促销”的东西,这些东西在算术和二元运算中进行,如轮班。在这种情况下,有一个unsigned char
操作数(*p++
)和一个int
操作数(常量),因此unsigned char
操作数转换为int
。演员(无论是long
还是unsigned int
)总是在>>促销和转换后执行。所以不,没有任何一个班次都丢失了。