Подтвердить что ты не робот

Почему потоки С++ используют char вместо unsigned char?

Я всегда задавался вопросом, почему в библиотеке С++ Standard создан экземпляр basic_ [io] и все его варианты с использованием типа char вместо типа unsigned char. char означает (в зависимости от того, подписана она или нет) у вас может быть переполнение и недополнение для таких операций, как get(), что приведет к определенному реализацией значения переменных. Другим примером является то, что вы хотите вывести байт, неформатированный, в ostream, используя его функцию put.

Любые идеи?


Примечание. Я все еще не очень убежден. Поэтому, если вы знаете окончательный ответ, вы все равно можете опубликовать его.

4b9b3361

Ответ 1

Возможно, я неправильно понял вопрос, но преобразование из unsigned char в char не является неопределенным, оно зависит от реализации (4.7-3 в стандарте С++).

Тип 1-байтового символа в С++ - "char", а не "unsigned char". Это дает реализациям немного больше свободы, чтобы делать лучшее на платформе (например, орган стандартов, возможно, полагал, что существуют процессоры, где подписанная байтовая арифметика быстрее, чем беззнаковая байт-арифметика, хотя эта спекуляция с моей стороны). Также для совместимости с C. Результатом устранения такой неопределенности существования из С++ является С#; -)

Учитывая, что существует тип "char", я считаю, что обычные потоки имеют смысл использовать его, даже если его подпись не определена. Так что, возможно, на ваш вопрос ответил ответ: "Почему С++ просто не определил char как неподписанный?"

Ответ 2

Я всегда понимал это так: цель класса iostream - читать и/или писать поток символов, которые, если вы думаете об этом, являются абстрактными объектами, которые представлены только компьютером, используя кодировка символов. Стандарт С++ прилагает большие усилия, чтобы избежать привязки кодировки символов, заявив только, что "Объекты, объявленные как символы (char), должны быть достаточно большими, чтобы хранить любой член базового набора символов реализации", потому что ему не нужно заставить "базовый набор символов реализации" определить язык С++; стандарт может оставить решение о том, какое кодирование символов используется для реализации (компилятор вместе с реализацией STL), и просто обратите внимание, что char объекты представляют отдельные символы в некоторой кодировке.

Писатель реализации мог выбрать однооктетовую кодировку, такую ​​как ISO-8859-1 или даже кодировку с двойным октетом, такую ​​как UCS-2. Это не имеет значения. Пока объект char "достаточно велик для хранения любого элемента базового набора символов реализации" (обратите внимание, что это явно запрещает кодировки переменной длины), тогда реализация может даже выбрать кодировку, которая представляет базовую латиницу, таким образом, которая несовместима с какой-либо общей кодировкой!

Сложно предположить, что типы char, signed char и unsigned char разделяют "char" в своих именах, но важно иметь в виду, что char не принадлежит к одному семейству фундаментальных типов как signed char и unsigned char. signed char находится в семействе знаковых целых типов:

Существует четыре подписанных целочисленных типа: "подписанный char", "короткий int", "int" и "long int."

и unsigned char находится в семействе беззнаковых целочисленных типов:

Для каждого из подписанных целочисленных типов существует соответствующий (но другой) неподписанный целочисленный тип: "unsigned char", "unsigned short int", "unsigned int" и "unsigned long int"..

Единственное сходство между типами char, signed char и unsigned char заключается в том, что "они занимают одинаковое количество хранилищ и имеют одинаковые требования к выравниванию". Таким образом, вы можете reinterpret_cast от char * до unsigned char *, чтобы определить числовое значение символа в наборе символов выполнения.

Чтобы ответить на ваш вопрос, причина, по которой STL использует char как тип по умолчанию, потому что стандартные потоки предназначены для чтения и/или записи потоков символов, представленных объектами char, а не целыми числами (signed char и unsigned char). Использование char по сравнению с числовым значением является способом разделения проблем.

Ответ 3

char для символов, без знака char для необработанных байтов данных и подписанных символов для, ну, подписанных данных.

Стандарт не указывает, будет ли использоваться подписанный или unsigned char для реализации char - он специфичен для компилятора. Он указывает только, что "char" будет "достаточно", чтобы удерживать символы в вашей системе - то, как символы были в те дни, а это не UNICODE.

Использование "char" для символов - стандартный способ. Использование unsigned char - это взлом, хотя он будет соответствовать реализации компилятора char на большинстве платформ.

Ответ 4

Я думаю, этот комментарий объясняет это хорошо. Цитировать:

подписан char и unsigned char являются арифметическими, целыми типами, как int и unsigned int. С другой стороны, char явно предназначен для типа "ввода/вывода", который представляет собой непрозрачную, зависящую от системы базовую единицу данных на вашей платформе. Я бы использовал их в этом духе.