[comp.lang.c] A Simple question

yhe@zip.eecs.umich.edu (Youda He) (04/09/90)

Here is the sample program:
main()
{
  char a=255;
  unsigned char b = 255;
  printf("a=%X\n",a);
  printf("b=%X\n",b);
}

The result is 
a=FFFF
b=FF
on dos, by using zortech and mcs, char is 8 bit long, why a looks like 16bit?
what is the difference of char and unsigned char on printf? 

-- Youda

dkeisen@Gang-of-Four.Stanford.EDU (Dave Eisen) (04/09/90)

In article <1881@zipeecs.umich.edu> yhe@eecs.umich.edu (Youda He) writes:
>Here is the sample program:
>main()
>{
>  char a=255;
>  unsigned char b = 255;
>  printf("a=%X\n",a);
>  printf("b=%X\n",b);
>}
>
>The result is 
>a=FFFF
>b=FF
>on dos, by using zortech and mcs, char is 8 bit long, why a looks like 16bit?

In a sense, it *is* 16 bits. C converts all chars to ints before passing them
to a function. 

a = 255 puts 11111111 into a, b = 255 also puts 11111111 into b. The difference
appears when the two variables are extended to being 2 bytes long.

As an unsigned value, b is extended by tacking 0's to the front to become
000000011111111, still FF as it should be.

But a is signed and extending it by tacking 0's to the front doesn't work if
you are extending negative numbers. In a two's complement system, unsigned 
chars are extended by tacking on whatever appears in the most significant bit 
in the original character so a becomes 1111111111111111, or FFFF.



--
Dave Eisen                      	    Home:(415) 324-9366 / (415) 323-9757
814 University Avenue                       Office: (415) 967-5644
Palo Alto, CA 94301 		            dkeisen@Gang-of-Four.Stanford.EDU 

grogers@convex.com (Geoffrey Rogers) (04/10/90)

In article <1881@zipeecs.umich.edu> yhe@eecs.umich.edu (Youda He) writes:
+main()
+{
+  char a=255;
+  unsigned char b = 255;
+  printf("a=%X\n",a);
+  printf("b=%X\n",b);
+}
+
+The result is 
+a=FFFF
+b=FF
+on dos, by using zortech and mcs, char is 8 bit long, why a looks like 16bit?
+what is the difference of char and unsigned char on printf? 
+

Sign extension. Since 'a' is a char, when it value gets converted to a
int (when you call printf), it sign gets extended. With 'b' this does
not happen, because it is a unsigned char, so when it gets converted to
an int, you just do a bit-wise copy.

+------------------------------------+---------------------------------+
| Geoffrey C. Rogers   		     | "Whose brain did you get?"      |
| grogers@convex.com                 | "Abbie Normal!"                 |
| {sun,uunet,uiucdcs}!convex!grogers |                                 |
+------------------------------------+---------------------------------+

wallis@labc.dec.com (Barry L. Wallis) (04/11/90)

In article <1881@zipeecs.umich.edu>, yhe@zip.eecs.umich.edu (Youda He) writes...
!>Here is the sample program:
!>main()
!>{
!>  char a=255;
!>  unsigned char b = 255;
!>  printf("a=%X\n",a);
!>  printf("b=%X\n",b);
!>}
!> 
!>The result is 
!>a=FFFF
!>b=FF
!>on dos, by using zortech and mcs, char is 8 bit long, why a looks like 16bit?
!>what is the difference of char and unsigned char on printf? 
!> 
!>-- Youda

The %X specifier in printf() tells the function to interpret the argument as an
int. Since the actual value is a char it is pushed on the stack as an int. If
the value pushed is defined as a signed char (as 'a' is), the high order bit is
sign extended; otherwise the high order byte is 00.
---
Barry L. Wallis			USENET: wallis@labc.dec.com
Database Consultant		Prodigy (don't laugh): DNMX41A
U.S. DECtp Resource Center	DECUServe: EISNER::WALLIS (not on the net yet)
Los Angeles, CA			"No one voted for me, I represent myself"
---

mcdaniel@amara.uucp (Tim McDaniel) (04/13/90)

yhe@zip.eecs.umich.edu (Youda He) asked about "printf("a=%X\n",a);",
where "a" is a signed char.

wallis@labc.dec.com (Barry L. Wallis) replies:

   The %X specifier in printf() tells the function to interpret the
   argument as an int.  Since the actual value is a char it is pushed
   on the stack as an int.

Those statements, in that order, may be ambiguous.  (As I first read
them, they seemed to say that printf does the type conversion after
seeing %X!)  To amplify:

Generally, an actual argument to a function undergoes "argument
promotion".  For example, integral type arguments smaller than an
"int" are automatically and silently converted to "int".  (The
compiler emits code to do this---the smaller-type values never reach
the function.)  The variable "a", with value -1, is converted to an
"int" with value -1.  printf (on the machine in question) prints an
int -1 as "FFFF".

ANSI C provides function prototypes, which allows you to avoid
argument promotion in most cases.  However, printf has a variable
number of arguments, and prototypes can't help here.

--
Tim McDaniel
Applied Dynamics International, Ann Arbor, MI
Internet: mcdaniel%amara.uucp@mailgw.cc.umich.edu
UUCP: {uunet,sharkey}!amara!mcdaniel