Этот вопрос был задан мне в интервью, что размер char
в некоторых ОС составляет 2 байта, но в некоторых операционных системах это 4 байта или другие.
Почему это так?
Почему он отличается от других основных типов, таких как int
?
Вероятно, это был вопрос с подвохом. sizeof(char)
является всегда 1.
Если размер отличается, это, вероятно, из-за несоответствующего компилятора, в этом случае вопрос должен быть о самом компиляторе, а не о языке C или C ++.
1 Оператор sizeof возвращает количество байтов в объекте.
представление своего операнда. Операнд является либо выражением,
который не оценивается, или идентификатор типа в скобках. Размер
оператор не должен применяться к выражению, которое имеет функцию или
неполный тип или тип перечисления перед всеми его перечислителями
были объявлены, или к названию в скобках таких типов, или к
lvalue, которое обозначает битовое поле.sizeof(char)
,sizeof(signed
а также
char)sizeof(unsigned char)
1. Результат sizeof, примененного к любому другому фундаментальному типу (3.9.1)
реализации. (акцент мой)
Размеры других типов, отличных от указанных, определяются реализацией и различаются по разным причинам. int
имеет больший диапазон, если он представлен в 64 битах вместо 32, но он также более эффективен как 32 бита в 32-битной архитектуре.
Физические размеры (с точки зрения количества бит) типов обычно определяются целевым оборудованием.
Например, некоторые процессоры могут обращаться к памяти только в единицах, не меньших 16 бит. Для лучшей производительности, char
затем может быть определено 16-битное целое число. Если вы хотите использовать 8-битные символы в этом процессоре, компилятор должен сгенерировать дополнительный код для упаковки и распаковки 8-битных значений в 16-битные ячейки памяти и из них. Этот дополнительный код упаковки / распаковки сделает ваш код больше и медленнее.
И это еще не конец. Если вы поделите 16-битные ячейки памяти на 8-битные символы, вы фактически добавите дополнительный бит в адреса / указатели. Если нормальные адреса в процессоре 16-битные, куда вы добавляете этот 17-й бит? Есть два варианта:
Последний вариант иногда может быть практичным. Например, если все адресное пространство разделено пополам, одно из которых используется ядром, а другое пользовательскими приложениями, указатели приложений никогда не будут использовать один бит в своих адресах. Вы можете использовать этот бит для выбора 8-битного байта в 16-битной ячейке памяти.
C был разработан для работы на максимально возможном количестве разных процессоров. Вот почему физические размеры char
, short
, int
, long
, long long
, void*
, void(*)()
, float
, double
, long double
, wchar_t
и т. д. могут варьироваться.
Теперь, когда мы говорим о разных физических размерах в разных компиляторах, производящих код для одного и того же процессора, это становится более произвольным выбором. Однако, это может быть не так произвольно, как может показаться. Например, многие компиляторы для Windows определяют int
знак равно long
= 32 бита Они делают это, чтобы избежать путаницы программиста при использовании API-интерфейсов Windows, которые ожидают INT
знак равно LONG
= 32 бита определяющий int
а также long
как что-то еще будет способствовать ошибкам из-за потери внимания программиста. Таким образом, компиляторы должны последовать их примеру в этом случае.
И наконец, стандарт C (и C ++) работает с chars
а также bytes
, Они одинаковы по размеру. Но байты C не являются вашими типичными 8-битными байтами, они могут по закону быть больше, чем это, как объяснено ранее. Чтобы избежать путаницы, вы можете использовать термин octet
, имя которого подразумевает число 8. В ряде протоколов это слово используется именно для этой цели.