user1559625
user1559625

Reputation: 2673

Mini questions on 'unsigned char' and 'shift' operation?

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

Answers (2)

user1610015
user1610015

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

James
James

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

Related Questions