Reputation: 2673
The question should be basic but i am surprised that i had some trouble get it now. First one is when i glanced 'C++ primer' book chapter 5.3. The Bitwise Operators, when author use below code as an example to explain shift operation:
unsigned char bits = 1; // '10011011' is the corresponding bit pattern
bits << 1; // left shift
My head spin a little when i looked at this, where is '10011011' coming from? '1' is not '0x01'?
Another question comes from http://c-faq.com/strangeprob/ptralign.html, where author try to unpack structure:
struct mystruct {
char c;
long int i32;
int i16;
} s;
using
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++;
My question is, p is a pointer to unsigned char(which is 8 bits), right? when building higher bytes of s.i32(24~31, 16~23), *p++ is converted to 'long'(32bits) before doing left shift, so left shift would not lose bit in *p++, but in
s.i32 |= (unsigned)(*p++ << 8);
*p++ is shifted first, then convert to unsigned int, wouldn't the bits of *p++ all lost during the shift?
Again i realize i maybe missing some of the basics in C here. Hope someone can give a hand here.
Thanks,
Upvotes: 1
Views: 1228
Reputation: 6678
Yes the bit pattern of 1 is 0x01. 10011011 is the bit pattern for decimal 155.
As for the shifts, you're missing something called the "integral promotions", which are performed in arithmetic and binary operations like shifts. In this case, there's an unsigned char
operand (*p++
) and an int
operand (the constant), so the unsigned char
operand is converted to int
. The cast (whether to long
or to unsigned int
) is always performed after the promotion and the shift are performed. So no, in none of the shifts are all of the bits lost.
Upvotes: 0
Reputation: 25533
To answer your second question, performing any arithmetic operation on a char
promotes it to a (possibly unsigned) int
(including shifting and other bitwise operations), so the integer-size value is shifted, not the 8-bit char value.
Upvotes: 3