Разница между массивом char и массивом unsigned char

Я написал небольшой тестовый код для Arduino Uno, который выглядит следующим образом:

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() {
}

и результат, который я получаю, выглядит следующим образом

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

Может кто-нибудь помочь мне понять, почему разница в выходе.

, 👍2

Обсуждение

Почему это не по теме? Разве наблюдаемое поведение не основано на том, как _the Arduino library_, в частности, реализует различные перегрузки типов и производит разные выходы для char и unsigned char? В отличие, например, от того, что делает стандартный "iostream": оба " unsigned char uc = 0x41; cout << uc << endl; и char c = 0x41; cout << c << endl; вывод A'., @ilkkachu


2 ответа


Лучший ответ:

2

tl;dr : Поскольку unsigned char представлен в виде байтового значения, вывод в serial-это байтовое представление, а не char

Я переписал код, который у вас был для справки:

#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);
}

Когда вы запустите эту программу, вы увидите, что unsigned char просто печатается в серийный, как и любое другое байтовое значение, но значение char печатается как символ в соответствии с таблицей ASCII.

Если вы сравните документацию для unsigned char

Тип данных без знака, занимающий 1 байт памяти. То же, что и байтовый тип данных.

Тип данных unsigned char кодирует числа от 0 до 255.

Для согласованности стиля программирования Arduino предпочтительным является байтовый тип данных.

по сравнению с обычным (подписанным) символом:

Тип данных, используемый для хранения символьного значения. Символьные литералы записываются в одинарных кавычках, например: 'A' (для нескольких символов - строк - используйте двойные кавычки: "ABC").

Однако символы хранятся в виде чисел. Вы можете увидеть конкретную кодировку на диаграмме ASCII. Это означает, что можно выполнять арифметику с символами, в которых используется значение ASCII символа (например, " A " + 1 имеет значение 66, так как значение ASCII заглавной буквы A равно 65). Подробнее о том, как символы преобразуются в числа, см. в разделе Serial.println справочника.

Размер типа данных char составляет не менее 8 бит. Рекомендуется использовать char только для хранения символов. Для однобайтового (8-битного) типа данных без знака используйте байтовый тип данных.

Таким образом, размер массива символов и символов без знака будет одинаковым. Речь идет скорее о представлении базового числа (байта) и о том, что лучше всего подходит для вашего варианта использования.

,

0

Unsigned char рассматривается как число, а signed char - как символ. См. https://simple.wikipedia.org/wiki/ASCII таблица результатов.

,

Это не совсем правильно. В C++ "char", "signed char" и "unsigned char" - это ТРИ разных типа, а не два. Конечно, в некотором смысле "char" должен быть таким же, как один из двух других типов, но какие два типа одинаковы, зависит от реализации. По умолчанию только "char" интерпретируется как символьные данные., @alephzero

@alephzero спасибо за добавление. В основном лучше бросать, чтобы быть уверенным., @Michel Keijzers