Из
Наличие спецификаторов типов в различных комбинациях для арифметических типов может указывать или не указывать разные типы. Например, тип, подписанный int, такой же, как и int, за исключением случаев, когда они используются как типы битовых полей; но char, signed char и unsigned char - разные типы.
В чем причина этой разницы между int и char в отношении идентичности типа?
Я думаю, что те же правила применяются и в C++. Поэтому добавление тега C++ также к этому вопросу
Первоначально C не имел unsigned
типов, поэтому char
был подписан по умолчанию. Поскольку PDP-11 использовал 8-битные байты и набор символов ASCII, объекты char
не ожидали принимать отрицательные значения:
Символы (объявленные и именуемые далее
char
) выбираются из набора ASCII; они занимают самые правые семь бит 8-битного байта. Также возможно интерпретироватьchar
как подписанный, 2s дополнять 8-битные номера.
unsigned
типы были добавлены примерно в 1977 году частично, чтобы препятствовать использованию указателей для беззнаковой арифметики:
[...] сходство арифметических свойств указателей символов и целых чисел без знака затрудняло искушение их идентифицировать. Для создания беззнаковой арифметики были добавлены типы без знака, не путая их с манипуляцией указателем.
Проблема с созданием char
заключается в том, что для выполнения арифметики по значениям char
необходимо подписать-расширять их. Это было эффективно на PDP-11, в котором была инструкция SXT, но не на ARM (по крайней мере, до версии 4 архитектуры ARM, выпущенной в 1996 году):
[...] вы не найдете ни одного "символа нагрузки из памяти и расширения знака" в наборе команд ARM. Поэтому, по соображениям производительности, каждый компилятор, о котором я знаю, делает тип символа по умолчанию, подписанный на x86, но без знака в ARM. [...]
Таким образом, когда C был стандартизирован, у комитета был выбор либо сделать char
- и, таким образом, заставить реализации ARM измениться, чтобы стать неэффективными, или отразить существующую практику и сделать подписку на определение реализации char
.
end-of-file ( ´\0´ returned from "getchar" )"
, поэтому EOF
было 0, BITD.
Из C++ 11: (фрагменты из различных абзацев в § 3.9)
Обычный символ, подписанный символ и unsigned char - это три разных типа, которые в совокупности называются узкими типами символов.
Существует пять стандартных стандартных целочисленных типов: "signed char", "short int", "int", "long int" и "long long int".
Для каждого стандартного знакового целочисленного типа существует соответствующий (но другой) стандартный беззнаковыйцелочисленный тип: "unsigned char", "unsigned short int", "unsigned int", "unsigned long int" и "unsigned long long int", каждый из которых занимает одинаковое количество хранения и имеет те же требования к выравниванию (3.11 ) в качестве соответствующего знакового целочисленного типа47;
Тип wchar_t - это отдельный тип... Типы char16_t и char32_t обозначают разные типы...
Значения типа bool являются либо истинными, либо ложными.49 [Примечание. Нет никаких подписанных, неподписанных, коротких или длинных типов или значений bool. -End note]
В п. 7.1.6.2 перечислены таблицы, ключевые слова которых приводят к тому, какие типы:
type-name the type named
simple-template-id the type as defined in 14.2
char "char"
unsigned char "unsigned char"
signed char "signed char"
char16_t "char16_t"
char32_t "char32_t"
bool "bool"
unsigned "unsigned int"
unsigned int "unsigned int"
signed "int"
signed int "int"
int "int"
unsigned short int "unsigned short int"
unsigned short "unsigned short int"
unsigned long int "unsigned long int"
unsigned long "unsigned long int"
unsigned long long int "unsigned long long int"
unsigned long long "unsigned long long int"
signed long int "long int"
signed long "long int"
signed long long int "long long int"
signed long long "long long int"
long long int "long long int"
long long "long long int"
long int "long int"
long "long int"
signed short int "short int"
signed short "short int"
short int "short int"
short "short int"
wchar_t "wchar_t"
float "float"
double "double"
long double "long double"
void "void"
auto placeholder for a type to be deduced
decltype(expression) the type as defined below
Что касается причины, почему char
является wierd, мне сказали, что первоначально, был какой-то компилятор, который сделал char
unsigned (до того, как были созданы unsigned
типы?). Стандарт C++ хотел исправить это, но не хотел нарушать существующий код, поэтому они сделали подписанность реализации char
определенной и добавили signed char
как отдельный тип.
const
, volatile
, restrict
влияют или не влияют на типы.
const
и volatile
потому что это часто бывает да, а иногда нет. Я не знаком с restrict
вообще.
char
отличается? Это разные вопросы.char
был подписан, а в других - нет. Это поведение стандартизировано для обратной совместимости: оно определяется реализацией, независимо от того, является лиchar
подписанным или неподписанным. С другой стороны,int
всегда рассматривался как подписанный везде, поэтому такие махинации не нужны.