A little confusion between `char' and `unsigned char'

I'm currently working on something that need bit operations and I decided to use unsigned char to manipulate. However, I've got some strange results.
Let's have a look at the code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>

int main()
{
	char a;
	unsigned char b;
	printf("%d %d\n", (int) sizeof(a), (int) sizeof(b));
	a = b = '\x7f';
	printf("%.2X %.2X\n", a, b);
	printf("%d %d\n", a, b);
	a = b = '\x80';
	printf("%.2X %.2X\n", a, b); //be cautious!
	printf("%d %d\n", a, b);
}


The result is this(under GCC 4.3):
1
2
3
4
5
1 1
7F 7F
127 127
FFFFFF80 80
-128 128


Why is the char of '\x80' shown as a 4-bit type while the result of sizeof function is still 1? And yet why will values from \x80 through \xff behave like this while values from \x00 through \x7f behave `normal'?
Great thanks if anyone could explain this to me.
As you know, the difference between a signed and unsigned type is how it's interpretted. But you should also appreciate that in C, chars are passed as int, when passed by value to a function.

So, printf("%.2X %.2X\n", a, b); and printf("%d %d\n", a, b); sees two ints. Both chars are extended to ints with the sign preserved.
And, as it can be seen, if the signed variable's assigned value steps over the half of max value, it is treated as negative.
Yes, the key is that %x requires an unsigned int, not a char, and thus the char is being sign extended to an int then output as unsigned. So 0x80 signed is -128, sign extended
to 32-bits is 0xFFFFFF80 (sign bit is propagated).
Thanks a lot!
Topic archived. No new replies allowed.