Why does printing a hex representation of char to the screen using printf sometimes prints a 4 byte number?
This is the code I have written
#include <stdio.h>
#include <stdint.h>
int main(void) {
char testStream[8] = {'a', 'b', 'c', 'd', 0x3f, 0x9d, 0xf3, 0xb6};
int i;
for(i=0;i<8;i++){
printf("%c = 0x%X, ", testStream[i], testStream[i]);
}
return 0;
}
And following is the output:
a = 0x61, b = 0x62, c = 0x63, d = 0x64, ? = 0x3F, � = 0xFFFFFF9D, � = 0xFFFFFFF3, � = 0xFFFFFFB6
char
appears to be signed on your system. With the standard "two's complement" representation of integers, having the most significant bit set means it is a negative number.
In order to pass a char
to a vararg function like printf
it has to be expanded to an int
. To preserve its value the sign bit is copied to all the new bits (0x9D
→ 0xFFFFFF9D
). Now the %X
conversion expects and prints an unsigned int
and you get to see all the set bits in the negative number rather than a minus sign.
If you don't want this, you have to either use unsigned char
or cast it to unsigned char
when passing it to printf
. An unsigned char
has no extra bits compared to a signed char
and therefore the same bit pattern. When the unsigned value gets extended, the new bits will be zeros and you get what you expected in the first place.