What is the difference between signed and unsigned char?

Discussion in 'C Programming' started by tinesan, Jan 27, 2005.

  1. tinesan

    tinesan Guest

    Hello fellow C programmers,

    I'm just learning to program with C, and I'm wondering what the
    difference between signed and unsigned char is. To me there seems to
    be no difference, and the standard doesn't even care what a normal char
    is (because signed and unsigned have equal behavior).

    For example if someone does this:

    unsigned char a = -2; /* or = 254 */
    signed char b = -2; /* or = 254 */

    putchar(b); /* both print the same character (ex ascii 254)*/

    It seems to me that it doesn't matter whether char is signed or
    unsigned, because the output functions just look at the bit pattern and
    deal with it as a positive number.
    Also, I assigned a negative number to unsigned char, it wraps around
    and creates the same bit pattern as assigning the same negative number
    to signed char.

    So my question is, what really is the difference between unsigned and
    signed char?

    Also, for other integral types, are the normal types always equal to
    the signed types (int = signed int, long = signed long,etc. etc.)... or
    is that implementation defined just like for chars?
    Any help will be appreciated.
    tinesan, Jan 27, 2005
    1. Advertisements

  2. tinesan

    Kobu Guest

    I don't think you can assign a negative initializer to a signed
    Am I right people?
    Kobu, Jan 27, 2005
    1. Advertisements

  3. tinesan

    Gregory Dean Guest

    The other way around...
    unsigned char does not have a sign extension.
    Gregory Dean, Jan 27, 2005
  4. tinesan

    Alex Fraser Guest

    In this, the value -2, of type int, is converted to unsigned char. This
    conversion is specified as being equivalent to repeatedly adding or
    subtracting UCHAR_MAX + 1 (where UCHAR_MAX is the maximum value an unsigned
    char can have; apparently 255 for your compiler) until the result is between
    0 and UCHAR_MAX inclusive. So a is assigned the value 254.
    Here, -2, again of type int, is converted to signed char. Note however that
    the effect of assigning 254 to b (which can hold values between SCHAR_MIN
    and SCHAR_MAX inclusive, probably -128 and 127 respectively in your case) is
    undefined by the standards.
    The putchar function takes an int, so for both these calls, the argument is
    converted to type int; the calls are equivalent to putchar(254) and
    putchar(-2) respectively. The putchar function is specified as converting
    its parameter to unsigned char, which uses the rule above. Therefore, with
    UCHAR_MAX being 255, the second call is equivalent to the first in terms of
    the result.
    See above.
    See the rule above. The wrapping around is what the standards specify. The
    fact it is the same bit pattern is common, because two's complement
    representation for signed numbers is common, but two's complement is not
    required by the standards.
    One can represent unsigned values, and the other signed values (obviously).
    As indicated above, conversion of out-of-range values to signed types (such
    as signed char) is undefined by the standard. Similarly, the result of
    arithmetic that produces out-of-range values for the type is undefined. But
    the behaviour in both these cases for unsigned types (such as unsigned char)
    *is* defined.
    char can represent the same range of values as either signed char or
    unsigned char, but all three are distinct types. (Similarly, int and long
    may be able to represent the same range of values on a given implementation,
    but they too are distinct types.)

    int, short, long (and long long in C99) are always capable of representing
    negative numbers. I think that int and signed int are the same type, and
    similarly for short, long and long long. Hopefully someone else can clarify
    this point.

    Alex Fraser, Jan 27, 2005
  5. Abstractly, putchar() is a wrapper for fputc(), and...

    "The fputc function writes the character specified by c
    (converted to an unsigned char)..."

    So, the calls will both send the same byte value to stdout.

    No, the conversion is _NOT_ specified in terms of bit pattern.

    On a signed magnitude machine, the 8-bit representation of -2 is...


    Irrespective of the signed char representation, the conversion
    will always yield UCHAR_MAX + 1 - 2.
    It will do so on two's complement machines. However, the standard
    doesn't _require_ two's complement integer representation for
    negative signed integers.
    Peter Nilsson, Jan 27, 2005
  6. Please don't top post in clc.

    Apart from the obvious!?

    You haven't read the standard, have you?

    The value of an unsigned integer cannot be negative.

    /* or UCHAR_MAX + 1 - 2 */

    Since -2 is in the range -127..127, the minimum range for
    signed char, b will always be assigned the value -2 here
    on any conforming implementation.

    Peter Nilsson, Jan 27, 2005
  7. No. Both declarations above are legal.
    Keith Thompson, Jan 27, 2005
  8. On your machine. They won't on a 1-s complement machine. Incidentally,
    value 254 (0xFE) is not an ASCII character, ASCII only defines 7 bit
    characters in the range 0x00 to 0x7FF (0 to 127).

    Usually, yes. Not guaranteed, though (some output libraries will fail
    if the parameter is negative).
    Again, on your machine.
    int main(void)
    unsigned char a = -2;
    signed char b = -2;

    if (a == b)

    if (a > 0)
    printf("a > 0\n");

    if (b > 0)
    printf("b > 0\n");
    return 0;

    What, if anything, will be output?
    They are defined to take the same amount of storage. It is also defined
    that a signed value which is positive can be converted to an unsigned
    value of the same type and back again with no change in value. However,
    an unsigned value which is greater than the maximum positive value which
    a signed version can hold cannot be reliably converted into a signed
    value, nor is it defined what value an unsigned version of a negative
    value has.

    Chris C
    Chris Croughton, Jan 28, 2005
  9. tinesan

    CBFalconer Guest

    .... snip on signed/unsigned char ...
    That last provision is wrong. There is a specific process for
    converting any out-of-range value to an unsigned value. It just
    isn't necessarily reversible.
    CBFalconer, Jan 28, 2005
  10. tinesan

    Gregory Dean Guest

    Silly preferences setting in Entourage 2004. Sorry.
    Gregory Dean, Jan 28, 2005
  11. tinesan

    pete Guest

    They won't do what exactly, on a 1-s complement machine?

    ((unsigned char)-2) may or may not be 254,
    but putchar(-2) does the same thing
    as putchar((unsigned char)-2), always.

    See Alex Fraser's post in this thread for a good explanation.
    pete, Feb 4, 2005
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.