435,594 Members | 3,680 Online + Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,594 IT Pros & Developers. It's quick & easy.

unsigned char and char print

 P: n/a Hello, Here is my simple program int main() { unsigned char a =0x81; char b = 0x81; printf("unsigned char = 0x%x(%d), char = 0x%x(%d)\n",a,a,b,b); printf("cast char to unsigned 0x%x\n",(unsigned char)b); } ~ And here is the print out: unsigned char = 0x81(129), char = 0xffffff81(-127) cast char to unsigned 0x81 The result is what I expected, but I couldn't explain it well. Could someone give me a help and explain to me what 0xfffff81. (a char is one byte right?) And is cast here good? if not, is there any other way I can print out a char 0x81 as 0x81 printf("cast char to unsigned 0x%x\n",(unsigned char)b); Thanks a lot! Apr 6 '06 #1
3 Replies

 P: n/a QQ wrote: Hello, Here is my simple program int main() { unsigned char a =0x81; char b = 0x81; b could be either unsigned or signed. Which is up to the implemntation. If you want 'b' to be signed, say so. Since UCHAR_MAX may be as low as 127, and b is signed, you may be assigning an unsigned value to b out of range. The result of such an assignment is implementation defined. printf("unsigned char = 0x%x(%d), char = 0x%x(%d)\n",a,a,b,b); No matter what type b is (unsigned char oe signed char), the above is wrong. %x is a specifier for unsigned values, %d is a specifier for signed values. Since a is unsigned, the first %d is wrong. If b is unsigned, the second %d is wrong. If b is signed, the second %x is wrong. printf("cast char to unsigned 0x%x\n",(unsigned char)b); } ~ And here is the print out: unsigned char = 0x81(129), char = 0xffffff81(-127) cast char to unsigned 0x81 The result is what I expected, but I couldn't explain it well. You have no reasonable expectation as to the output. Your program is ill-formed. Could someone give me a help and explain to me what 0xfffff81. (a char is one byte right?) It is the int representation of -127. If you use a signed char as an argument to printf, the usual integer promotions are applied and the value is passed as a signed int. Apr 6 '06 #2

 P: n/a QQ schrieb: Here is my simple program Unfortunately, it also does not compile. #include int main() int main (void) { unsigned char a =0x81; char b = 0x81; Note: "char" is a special integer type; usually, the integer type name alone gives you the same type as if preceded by "signed". For char, this is not true; char is a type of its own and can be either signed or unsigned. Your compiler may even offer you to choose what kind of char you want to have. If you mean "signed char", write "signed char". Otherwise, you may run into surprises for another platform, operating system, compiler or even other compiler settings. printf("unsigned char = 0x%x(%d), char = 0x%x(%d)\n",a,a,b,b); Notes: Because printf() is a variadic function, both a and b are promoted to signed int and passed in this form. This means that "x" is the wrong conversion specifier. Cast a and b to unsigned int if you want %u, %x, %o. If you do not mind that 0 will be output as "0" instead of "0x0", you also could use the # flag (i.e. %#x instead of 0x%x). printf("cast char to unsigned 0x%x\n",(unsigned char)b); } ~ And here is the print out: unsigned char = 0x81(129), char = 0xffffff81(-127) cast char to unsigned 0x81 The result is what I expected, but I couldn't explain it well. Could someone give me a help and explain to me what 0xfffff81. (a char is one byte right?) Yes. And you are outputting an int (as explained above). If you want to print out the _representation_ (the actual bits) of b, then pass (unsigned int)(*((unsigned char *)&b)) instead of (unsigned char)b or (the correct version) (unsigned int)((unsigned char)b) What is the difference? (unsigned char) b takes the value of b and if it does not fit into unsigned char, then (UCHAR_MAX + 1) is added or subtracted as often as necessary to have b + N*(UCHAR_MAX+1) or b-N*(UCHAR_MAX+1) in the range that can be represented by unsigned char. The other one looks at the address where b is stored, pretends that this is the address of an unsigned char variable and then interprets the bit pattern found there as unsigned char value. And is cast here good? Casts are only necessary in very few places in C. The arguments of functions with variable argument list (such as printf()) are one of these places. Whether the cast really gives you what you want is another question. Cheers Michael -- E-Mail: Mine is an /at/ gmx /dot/ de address. Apr 6 '06 #3

 P: n/a Martin Ambuhl schrieb: QQ wrote: Hello, Here is my simple program int main() { unsigned char a =0x81; char b = 0x81; b could be either unsigned or signed. Which is up to the implemntation. If you want 'b' to be signed, say so. Since UCHAR_MAX may be as low as 127, and b is signed, ITYM: CHAR_MAX you may be assigning an unsigned value to b out of range. The result of such an assignment is implementation defined. printf("unsigned char = 0x%x(%d), char = 0x%x(%d)\n",a,a,b,b); No matter what type b is (unsigned char oe signed char), the above is wrong. %x is a specifier for unsigned values, %d is a specifier for signed values. Since a is unsigned, the first %d is wrong. If b is unsigned, the second %d is wrong. If b is signed, the second %x is wrong. I am not sure about this. If INT_MAX >= UCHAR_MAX, then I'd expect that effectively (signed int)a and (signed int)b, respectively, is passed. Could you please clarify how the signedness is transported via variable argument lists? Cheers Michael -- E-Mail: Mine is an /at/ gmx /dot/ de address. Apr 6 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion. 