问题
I was studying how C stores data in memory by bit patterns.
However I have confronted some issues when it comes to printf
formatting.
I have saved a variable as -10
(I do understand two's complement)
and another variable as 246
. Those two variables have bit patterns of 11110110
(which is 0xF6
).
I was trying to print out a value using the unsigned int
hexadecimal format in printf
.
char a = -10;
unsigned char b = 246;
printf("a : %x , b : %x\n" , (unsigned int) a, (unsigned int) b);
//a : fffffff6 , b : f6
Both integers have the same bit pattern of 0xF6
. However, if I do perform type casting into unsigned int
, the result varies. The result is 0xFFFFFFF6
for a
, while b
remains the same.
For a signed character, it seems to me that type casting process made the unsigned char
into an integer and filled all the empty bits with 1.
Is this due to their signedness? Or is this just Undefined Behavior?
回答1:
In this expression
(unsigned int) a
the integer promotions are applied to the object a
.
From the C Standard (6.3.1.1 Boolean, characters, and integers)
2 The following may be used in an expression wherever an int or unsigned int may be used:
— An object or expression with an integer type (other than int or unsigned int) whose integer conversion rank is less than or equal to the rank of int and unsigned int.
— A bit-field of type _Bool, int, signed int, or unsigned int.
If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. 58) All other types are unchanged by the integer promotions.
and
3 The integer promotions preserve value including sign. As discussed earlier, whether a ‘‘plain’’ char is treated as signed is implementation-defined.
If you want that in the result object after casting the character object woulf be represented as having the type unsigned char
then you have to write
(unsigned char) a
As the value of the promoted expression (unsigned char) a
can be represented in the type unsigned int then the second cast (to unsigned int) is not required. The C Standard allows to use arguments pf the type int instead of the type unsigned int if the value is represented in the both types. You could just write
printf("a : %x , b : %x\n" , (unsigned char) a, (unsigned int) b);
来源:https://stackoverflow.com/questions/58503202/why-is-a-number-sign-extended-when-it-is-cast-to-an-unsigned-type