Почему строки используют char *?
Почему большинство строковых функций в stdlibs C/С++ принимают указатели char*
?
Подписанная подпись char
даже не указана в стандарте, хотя большинство современных компиляторов (GCC, MSVC) рассматривают char
как подписанные по умолчанию.
Когда было бы целесообразно рассматривать строки как (возможно) подписанные байты? AFAIK нет значащих значений символов ниже нуля в любом наборе символов. Для определенных строковых операций значения должны быть добавлены к unsigned char
в любом случае.
Итак, зачем использовать stdlibs char*
? Даже C++
-специфические методы, такие как string::string(const char *);
?
Ответы
Ответ 1
Джим Балтер отмечает в комментарии, что
Инструкции PDP-11, касающиеся байтов, обрабатывали их как подписанные величины, так что как ранние компиляторы C их обрабатывали, а unsigned даже не существовали.
Я сильно подозреваю, что это ответ на вопрос, почему тип символа по умолчанию char
isn & rsquo; t должен быть неподписанным, но для этого вам понадобится цитата из какой-либо письменной исторической учетной записи.
Что касается того, почему это требование не требуется, чтобы быть подписанным (!), на машине с не двумя дополнениями, такой как (единственная, которую я знаю, возможно, все еще использую) Clearpath Dorado, a signed char
не может содержать все значения unsigned char
, так как он тратит один битпаттерн на отрицательный ноль или что-то другое, для которого используется битпаттерс. Если бы char
требовалось подписать, это было бы проблемой для интерпретации общих данных в виде последовательности char
. Следовательно, на такой машине char
должен быть неподписанным, иначе программное обеспечение должно будет заниматься экстремальными искажениями, чтобы справиться с ним.
Ответ 2
- Я уверен, что большинство строковых функций предшествует существованию
unsigned char
.
- Обычный
char
может быть либо подписанным, либо беззнаковым типом. Стандарты C и С++ явно допускают один (он всегда отдельный тип от unsigned char
или signed char
, но имеет тот же диапазон, что и один).
- В то время как в строковых функциях C используется
char *
, std::string
используется в большинстве С++.
Ответ 3
Стандарт C не зависит от того, является ли plain char
подписанным или неподписанным и однозначно относится к char
в отличие от signed char
. Кроме того, базовый набор символов ASCII, который включает в себя большинство основных управляющих и печатных символов на английском языке, состоит из 128 символов и поэтому может быть адекватно представлен подписанным char
(по крайней мере, в любой системе, которая обеспечивает 8 бит на каждый байт). Как указывает Джим Балтер (см. Комментарии ниже), ASCII не является полным базовым набором символов языка C, но я подозреваю, что он включает большинство обычных символов. Существует также массивный корпус кода C, который опирается на свойства (хотя и не обязательно уникальные) ASCII (например, специальный символ NUL
, имеющий значение нуля, буквенно-цифровые символы расположены последовательно и в порядке возрастания и т.д.),.
Ответ 4
Как сказал Бьярне на языке программирования С++, независимо от того, принят ли char
как подписанный или неподписанный, зависит от реализации, а язык С++ предоставляет два типа для каждой реализации.
Ответ 5
Другие пришли к историческим причинам, потому что это было так, когда C был впервые разработан и (позже) стандартизован, но есть еще одна причина, почему эта кажущаяся аномалия сохраняется и по сей день.
Просто, когда вы используете char
для символов, вам не нужно знать, была ли она подписана или без знака. Стандартная библиотека предоставляет переносные функции для работы с символами независимо от их представления. Если вы игнорируете эти функции и настаиваете на выполнении сравнений и арифметических действий над персонажами, вы заслуживаете каждой ошибки, которую вы получаете.
Чтобы сделать простой пример, достаточно проверить, можно ли печатать символ с помощью выражения c >= ' '
или эквивалентно c >= 0x20
, но вы должны просто использовать isprint(c)
вместо этого. Таким образом, вы не подвергаете себя конфликтованию/неподписанной ошибке и потенциально представляете ошибки, зависящие от платформы, в вашу программу.
Как только вы привыкнете использовать signed char
и unsigned char
только как небольшие (обычно 8-битные) целые числа для арифметики, и вы используете только char
, когда вы работаете с символьными данными, это будет кажутся вполне естественными, что char
является отдельным типом с определяемой реализацией подписью, и даже более естественным является то, что функции строковой обработки всегда используют char
и char *
, а не подписанные или неподписанные варианты. Подписанность char
кажется столь же актуальной, как и подпись bool
.
Ответ 6
Char не является ни подписанным, ни неподписанным стандартом. См. fooobar.com/questions/9038/...
Ответ 7
Почему большинство строковых функций в stdlibs C/С++ принимают указатели char *?
В С++ используйте std::string. В C шаблоны использования уже были установлены, когда введены неподписанные типы, и я бы не исключил проблемы с эффективностью.
нет значащих значений символов ниже нуля
Ну есть ограничение где-то в стандарте С++ символы в наборах основных символов положительны. Но наивно думать, что это ограничение имеет место для всех персонажей.
Это ограничение принудительно реализует реализации, которые позволяют EBCDIC в качестве системы кодирования иметь char без знака.
Большинство современных компиляторов (GCC, MSVC) рассматривают char как подписанный по умолчанию.
поведение gcc зависит от цели и имеет опции для изменения целевого значения по умолчанию.