c

Why does printing char sometimes print 4 bytes number in C


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

Solution

  • 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 (0x9D0xFFFFFF9D). 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.