Ответы:
Потому что ЦП не может обращаться ни к чему меньше байта.
bt
, bts
, btr
и btc
могут обратиться одиночные биты!
bt
адрес байтового смещения, а затем проверка бит с заданным смещением, независимо от того, при указании адреса, который вы вводите в байтах ... литералы смещения бит будут немного многословными (извините за каламбур).
Из Википедии :
Исторически байт представлял собой количество битов, используемых для кодирования одного символа текста в компьютере, и по этой причине он является основным адресуемым элементом во многих компьютерных архитектурах.
Таким образом, байт - это основная адресуемая единица , ниже которой компьютерная архитектура не может обращаться. И поскольку (вероятно) не существует компьютеров, поддерживающих 4-битные байты, у вас нет 4-битных bool
и т. Д.
Однако, если вы можете спроектировать такую архитектуру, которая может адресовать 4-битную как базовую адресуемую единицу, тогда у вас будет bool
4-битный размер только на этом компьютере!
int
и char
из моего поста.
bool
, потому что char
это наименьшая адресуемая единица в C ++ , независимо от того, что архитектура может адресовать с помощью собственных кодов операций. sizeof(bool)
должен иметь значение не менее 1, а соседние bool
объекты должны иметь свои собственные адреса в C ++ , поэтому реализация просто должна увеличить их и тратить память. Вот почему битовые поля существуют как особый случай: элементы битового поля структуры не обязательно должны иметь отдельную адресацию, поэтому они могут быть меньше, чем char
(хотя вся структура по-прежнему не может быть).
char
что это наименьшая адресуемая единица в C ++?
sizeof(bool)
не может быть 0,5 :-) Я полагаю, что реализация может на законных основаниях предоставлять суббайтовые указатели в качестве расширения, но «обычные» объекты, такие как bool, выделяемые обычным образом, должны делать то, что говорит стандарт.
Самый простой ответ: это потому, что ЦП адресует память в байтах, а не в битах, а побитовые операции выполняются очень медленно.
Однако в C ++ можно использовать распределение битового размера. Для битовых векторов существует специализация std :: vector, а также структуры, принимающие записи битового размера.
В былые времена, когда мне приходилось идти в школу в бушующую метель, подниматься в обе стороны, и обедать было какое бы животное мы ни могли выследить в лесу за школой и убить голыми руками, у компьютеров было гораздо меньше доступной памяти, чем Cегодня. Первый компьютер, который я когда-либо использовал, имел 6 КБ ОЗУ. Не 6 мегабайт, не 6 гигабайт, 6 килобайт. В этой среде имело смысл упаковать в int столько логических значений, сколько вы могли, и поэтому мы регулярно использовали операции для их извлечения и вставки.
Сегодня, когда люди будут издеваться над вами за то, что у вас всего 1 ГБ ОЗУ, а единственное место, где вы можете найти жесткий диск с объемом менее 200 ГБ, - это антикварный магазин, просто не стоит тратить силы на то, чтобы упаковывать биты.
Вы можете использовать битовые поля для получения целых чисел субразмера.
struct X
{
int val:4; // 4 bit int.
};
Хотя обычно он используется для сопоставления структур с точными ожидаемыми аппаратными битовыми шаблонами:
struct SomThing // 1 byte value (on a system where 8 bits is a byte
{
int p1:4; // 4 bit field
int p2:3; // 3 bit field
int p3:1; // 1 bit
};
У вас могут быть 1-битные логические значения и 4- и 2-битные целые числа. Но это привело бы к странному набору инструкций без увеличения производительности, потому что это неестественный взгляд на архитектуру. На самом деле имеет смысл «потратить впустую» лучшую часть байта, а не пытаться вернуть неиспользуемые данные.
По моему опыту, единственное приложение, которое пытается упаковать несколько bool в один байт, - это Sql Server.
bool
может быть одним байтом - наименьшим адресуемым размером ЦП или может быть больше. Нет ничего необычного в том, bool
чтобы быть размером с int
для повышения производительности. Если для определенных целей (например, для моделирования оборудования) вам нужен тип с N битами, вы можете найти для этого библиотеку (например, у библиотеки GBL есть BitSet<N>
класс). Если вас беспокоит размер bool
(у вас, вероятно, большой контейнер), вы можете упаковать биты самостоятельно или использовать std::vector<bool>
это для вас (будьте осторожны с последним, поскольку он не удовлетворяет требованиям к контейнеру).
Потому что, как правило, ЦП выделяет память с 1 байтом в качестве базовой единицы, хотя некоторые ЦП, такие как MIPS, используют 4-байтовое слово.
Однако vector
работает bool
особым образом, с vector<bool>
выделением одного бита для каждого логического значения.
lw
/" sw
используется гораздо шире.
Байт - это меньшая единица хранения цифровых данных компьютера. В компьютере ОЗУ состоит из миллионов байтов, и у любого из них есть адрес. Если бы у него был адрес для каждого бита, компьютер мог бы управлять оперативной памятью в 8 раз меньше, чем он может.
Более подробная информация: Википедия.
Даже если минимально возможный размер составляет 1 байт, вы можете иметь 8 бит логической информации в 1 байте:
http://en.wikipedia.org/wiki/Bit_array
Например, в языке Julia есть BitArray, и я читал о реализациях C ++.
struct Packed { unsigned int flag1 : 1; unsigned int flag2: 1; };
, Большинство компиляторов выделяют полныйunsigned int
, однако они сами справляются с перестановкой битов при чтении / записи. Также они работают сами по себе с операциями по модулю. Этоunsigned small : 4
атрибут имеет значение от 0 до 15, и когда оно должно стать равным 16, он не будет перезаписывать предыдущий бит :)