3

I have written a small test code for Arduino Uno which is as follows:

unsigned char tes[4];
char testing[4];

void setup() {
    Serial.begin(9600);
    for (int i = 0; i < 4; i++) {
        testing[i] = i;
        tes[i] = i;
    }
    for (int i = 0; i < 4; i++) {
        Serial.print("unsigned char is: ");
        Serial.println(tes[i]);
        Serial.print("char is: ");
        Serial.println(testing[i]);
    }
}

void loop() {
}

and the output which I get is as follows

unsigned char is: 0
char is: 
unsigned char is: 1
char is: 
unsigned char is: 2
char is: 
unsigned char is: 3
char is: 

Can someone help me out why is the difference in output.

1
  • Why is this off-topic? Isn't the observed behaviour based on how the Arduino library in particular implements different type overloads and produces different outputs for char and unsigned char? Unlike e.g. what standard iostream seems to do: both unsigned char uc = 0x41; cout << uc << endl; and char c = 0x41; cout << c << endl; output A. – ilkkachu Feb 11 at 13:04
2

tl;dr : Since unsigned char is represented as a byte value, the output to the serial is the byte representation, not the char

I re-wrote the code you had for reference:

#define CHARS 255
#define BAUD 115200

unsigned char unsChar[CHARS];
char sinChar[CHARS];

void setup() {
  Serial.begin(BAUD);
  Serial.println("~~Setup~~");
  for(int i = 0; i < CHARS; i++) {
    unsChar[i] = (unsigned char)i;
    sinChar[i] = (char)i;
  }
}

void loop() {
  Serial.println("~~Loop~~");
  for(int i = 0; i < CHARS; i++) {
    Serial.print("INDEX        : ");
    Serial.println(i);
    Serial.print("unsigned char: ");
    Serial.println(unsChar[i]);
    Serial.print("         char: ");
    Serial.println(sinChar[i]);
    Serial.println("---------------------");
  }
  delay(10000);
}

When you run this you'll see the unsigned char is simply printed to the serial like any other byte value but the char value is printed as a character according to the ASCII chart.

If you compare the documentation for unsigned char

An unsigned data type that occupies 1 byte of memory. Same as the byte datatype.

The unsigned char datatype encodes numbers from 0 to 255.

For consistency of Arduino programming style, the byte data type is to be preferred.

versus a normal (signed) char:

A data type used to store a character value. Character literals are written in single quotes, like this: 'A' (for multiple characters - strings - use double quotes: "ABC").

Characters are stored as numbers however. You can see the specific encoding in the ASCII chart. This means that it is possible to do arithmetic on characters, in which the ASCII value of the character is used (e.g. 'A' + 1 has the value 66, since the ASCII value of the capital letter A is 65). See Serial.println reference for more on how characters are translated to numbers.

The size of the char datatype is at least 8 bits. It’s recommended to only use char for storing characters. For an unsigned, one-byte (8 bit) data type, use the byte data type.

So size wise an array of chars and unsigned chars are going to be the same. It's more about the representation of the underlying number (byte) and what works best for your use case.

0

An unsigned char is treated as a number, and a signed char as a character. See the https://simple.wikipedia.org/wiki/ASCII table for the result.

2
  • 2
    This is not quite right. In C++, "char", "signed char" and "unsigned char" are THREE different types, not two. Of course in some sense "char" must be the same as one of the other two types, but which two types are the same is implementation-dependent. Only "char" is interpreted as character data by default. – alephzero Feb 10 at 16:36
  • @alephzero thanks for the addition. Mostly it's better to cast to be sure. – Michel Keijzers Feb 10 at 18:23

Not the answer you're looking for? Browse other questions tagged or ask your own question.