-1
**Allocation and Storage part of C programming **

I have come with some doubt while trying to print negative numbers through different number system. while printing negative numbers, I am getting different output values.But I am not understanding clearly. If anybody help me will be appreciative.

 #include<stdio.h>
    int main( )
    {
       char a = -5;
       unsigned char b = -5;
       int c = -5;
       unsigned int d = -5;

      //try to print as using "%d" format specifier to display decimal value
      printf("%d %d",a,b);
      printf("%d %d",c,d);

      //try to print as using "%o" format specifier to display octal value
      printf("%o %o",a,b);
      printf("%o %o",c,d);

      //try to print as using "%x" format specifier to display hexa-decimal value
      printf("%x %x",a,b);
      printf("%x %x",c,d);

      return 0;
}

Output:-

displaying decimal value 
a = -5 b = 251
c = -5 d = -5

displaying octal value
a = 37777777773 b = 373
c = 37777777773 d = 37777777773

displaying Hexa-decimal value
a = fffffffb  b = fb
c = fffffffb  d = fffffffb

Now, come to the point. I don't know why unsigned char would take only 8 bits(1 Byte) and other gets allocated to 32 bits (4 Bytes).

MK Tharma
  • 31
  • 6

1 Answers1

1

When a char value is passed to printf, it is promoted to int. printf is printing this int value.

When the char value is −5 and it is promoted to int, the int value is −5. For a 32-bit two’s complement int, −5 is represented with the bits fffffffb16. So, when you ask printf to format that with %x, you can “fffffffb”. (Technically, %x is for an unsigned int, and passing an int does not match, but most C implementations will accept it.) The eight-bit char was promoted to a 32-bit int, and that is why you see 32-bit results.

You can tell printf that the value it receives originated as a character value by using %hho or %hhx instead of %o or %x, and it may adjust accordingly. (Again, the o and x specifiers are for unsigned int values, and passing an int does not match, but it may work.) A pedantically correct solution is to use (unsigned int) (unsigned char) x when passing a signed char x for a %o or %x conversion.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • Mr.Eric if you notice the answer for unsigned char, it will give up to the range of unsigned char(0-255) for every format specifier %d - 251, %o - 373, %x - fb but others are gives 32 bits range – MK Tharma Jun 10 '20 at 01:11
  • @MKTharma: The eight-bit `char` is promoted to a 32-bit `int`. When the `char` value is positive, the high bits of the 32-bit `int` are zeros, and you do not see them. When the `char` value is negative, the high bits of the 32-bit `int` are ones, and you see them. I added a paragraph about this. – Eric Postpischil Jun 10 '20 at 01:34
  • like wise from your concerned about negative values,the highest bits of the 32-bit int are ones, But happened while unsigned char of every printf function in above my program. If you notice my program, There I initialize unsigned char b = -5; and It's negative value why it cannot bit up to 32-bit for unsigned char b; – MK Tharma Jun 10 '20 at 01:49
  • @MKTharma: `unsigned char` objects never have negative values. When you assign −5 to an eight-bit `unsigned char`, it is converted to 251 (256−5). When you print an `unsigned char` with value 251, it is promoted to an `int` with value 251, and the high bits are zeros. – Eric Postpischil Jun 10 '20 at 02:56