176

So I know that the difference between a signed int and unsigned int is that a bit is used to signify if the number if positive or negative, but how does this apply to a char? How can a character be positive or negative?

NAND
  • 663
  • 8
  • 22
Chiggins
  • 8,197
  • 22
  • 56
  • 81
  • 2
    [A previous answer](http://stackoverflow.com/questions/75191/unsigned-char) on this topic will help. – jarmod Dec 02 '10 at 16:24
  • 3
    *"So I know that the difference between a signed and unsigned int is that a bit is used to signify if the number if positive or negative"* - Note that this is just one of the ways to to it and not the most usual and practical one. – Christian Rau Jun 05 '13 at 16:50

8 Answers8

169

There's no dedicated "character type" in C language. char is an integer type, same (in that regard) as int, short and other integer types. char just happens to be the smallest integer type. So, just like any other integer type, it can be signed or unsigned.

It is true that (as the name suggests) char is mostly intended to be used to represent characters. But characters in C are represented by their integer "codes", so there's nothing unusual in the fact that an integer type char is used to serve that purpose.

The only general difference between char and other integer types is that plain char is not synonymous with signed char, while with other integer types the signed modifier is optional/implied.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • Alright, hopefully you'll be able to stay with me here, I'm not that great with bits / C and stuff. So with a signed char, something like "01011011" could represent one character? – Chiggins Dec 02 '10 at 16:34
  • 3
    @Chiggins: Is it binary? If so, then yes. Your `01011011` is a binary representation of 91. So, it represents whatever character has code 91 on your platform (`[` on PC, for example). – AnT stands with Russia Dec 02 '10 at 17:40
  • 1
    For a simple proof of the nature of chars being ints try applying `swtich...case`, which can be applied only to integral numeric values. – rbaleksandar Sep 10 '15 at 10:39
  • 4
    C89 6.1.2.5 "There are three character types, designated as char , signed char, and unsigned char." C11 6.2.5p15 "The three types `char`, `signed char`, and `unsigned char` are collectively called the *character types*." 6.2.5fn45 "`char` is a separate type from the other two and is not compatible with either" – Cubbi May 07 '16 at 04:17
67

I slightly disagree with the above. The unsigned char simply means: Use the most significant bit instead of treating it as a bit flag for +/- sign when performing arithmetic operations.

It makes significance if you use char as a number for instance:

typedef char BYTE1;
typedef unsigned char BYTE2;

BYTE1 a;
BYTE2 b;

For variable a, only 7 bits are available and its range is (-127 to 127) = (+/-)2^7 -1. For variable b all 8 bits are available and the range is 0 to 255 (2^8 -1).

If you use char as character, "unsigned" is completely ignored by the compiler just as comments are removed from your program.

NAND
  • 663
  • 8
  • 22
Simple Fellow
  • 4,315
  • 2
  • 31
  • 44
  • 10
    I think you did a mistake (correct me if I'm wrong): "a" is signed char so the range is -128 to 127 and "b" is unsigned char so the range is 0 to 255. [similar question](http://stackoverflow.com/questions/75191/what-is-an-unsigned-char) – dalf Feb 06 '14 at 02:22
  • 7
    You need to change this answer to reflect that signed integers use twos complement and not a sign bit like you say, because as it stands this answer is incorrect. – Matthew Mitchell Nov 14 '14 at 15:47
  • @Matthew Mitchell read the question again. He didn't want a thesis on that. simple questions deserve simple answers.. I don't over complicating things to impress others! – Simple Fellow Nov 14 '14 at 18:50
  • 1
    as written above, this is not what the standard says. Being unsigned could in principal only mean "ignore the sign bit". Nothing guarantees that an unsigned type will be able to hold larger positive value than its signed counterpart. – user1251840 Oct 21 '15 at 10:55
  • @user1251840 : http://stackoverflow.com/questions/3724242/what-is-the-difference-between-int-and-uint-long-and-ulong – Simple Fellow Oct 21 '15 at 11:18
  • 16
    **This is incorrect**. In C, signed integer types use two's complement, with range `-(2^n-1)` to `(2^n-1)-1`, where `n` is the number of bits and `0` is counted once, not twice. By default, a `char` is unsigned, not signed. Please correct this; it is a simple **but incorrect** explanation. – wizzwizz4 Feb 15 '16 at 11:52
  • 1
    The signed bit also **does not change the way arithmetic works**, adding the two unsigned numbers 4294967295 and 4294967295 will still give you a signed -2. Type is **only** for humans and has no meaning at a binary level. – Qwerty01 Oct 05 '16 at 15:37
  • Quick correction to the above: comparisons are changed depending on whether it is signed or unsigned. – Qwerty01 Oct 05 '16 at 15:47
  • 7
    wizzwizz4: AFAIK **if char is unsigned or signed by default is defined by the implementation** not by the standard (e.g. see http://stackoverflow.com/a/2054941/138526) – Felix Schwarz Feb 14 '17 at 15:04
  • 4
    @wizzwizz4 The C standard does not define the encoding format for signed integers. It is up to the compiler designer to choose between 2s complement, 1s complement and sign & magnitude. – Fernando Mar 23 '17 at 14:22
  • 2
    @wizzwizz4 As far as my understanding of the C11 standard goes, the actual smallest value *is* -127. So you can end up with no -128. See Section 5.2.4.2.1. – Garogolun May 22 '19 at 13:38
  • @Garogolun You are right, I think. I've deleted one of my comments, but I'm not sure enough to delete the other. – wizzwizz4 May 22 '19 at 15:44
  • I'm here a bit late, but if I remember my undergrad course 2s complement makes the math a bit easier, but doesn't affect the storage capacity of the int. Saying the answer is incorrect only because of that seems a bit pedantic, as the veracity of the answer does not depend on the way you encode your int. – bendl May 03 '21 at 01:27
29

There are three char types: (plain) char, signed char and unsigned char. Any char is usually an 8-bit integer* and in that sense, a signed and unsigned char have a useful meaning (generally equivalent to uint8_t and int8_t). When used as a character in the sense of text, use a char (also referred to as a plain char). This is typically a signed char but can be implemented either way by the compiler.

* Technically, a char can be any size as long as sizeof(char) is 1, but it is usually an 8-bit integer.

DrAl
  • 70,428
  • 10
  • 106
  • 108
19

Representation is the same, the meaning is different. e.g, 0xFF, it both represented as "FF". When it is treated as "char", it is negative number -1; but it is 255 as unsigned. When it comes to bit shifting, it is a big difference since the sign bit is not shifted. e.g, if you shift 255 right 1 bit, it will get 127; shifting "-1" right will be no effect.

user2376256
  • 189
  • 1
  • 5
  • 2
    Note that the behavior of a right bitshift on a signed type is actually implementation defined. "Most" compilers will shift `-1` to `/-1` but you could actually also get `10111111` – n.caillou Nov 20 '17 at 18:54
14

A signed char is a signed value which is typically smaller than, and is guaranteed not to be bigger than, a short. An unsigned char is an unsigned value which is typically smaller than, and is guaranteed not to be bigger than, a short. A type char without a signed or unsigned qualifier may behave as either a signed or unsigned char; this is usually implementation-defined, but there are a couple of cases where it is not:

  1. If, in the target platform's character set, any of the characters required by standard C would map to a code higher than the maximum `signed char`, then `char` must be unsigned.
  2. If `char` and `short` are the same size, then `char` must be signed.

Part of the reason there are two dialects of "C" (those where char is signed, and those where it is unsigned) is that there are some implementations where char must be unsigned, and others where it must be signed.

NAND
  • 663
  • 8
  • 22
supercat
  • 77,689
  • 9
  • 166
  • 211
2

The same way -- e.g. if you have an 8-bit char, 7 bits can be used for magnitude and 1 for sign. So an unsigned char might range from 0 to 255, whilst a signed char might range from -128 to 127 (for example).

Stuart Golodetz
  • 20,238
  • 4
  • 51
  • 80
2

This because a char is stored at all effects as a 8-bit number. Speaking about a negative or positive char doesn't make sense if you consider it an ASCII code (which can be just signed*) but makes sense if you use that char to store a number, which could be in range 0-255 or in -128..127 according to the 2-complement representation.

*: it can be also unsigned, it actually depends on the implementation I think, in that case you will have access to extended ASCII charset provided by the encoding used

Jack
  • 131,802
  • 30
  • 241
  • 343
1

The same way how an int can be positive or negative. There is no difference. Actually on many platforms unqualified char is signed.

Šimon Tóth
  • 35,456
  • 20
  • 106
  • 151