Байланысты: Бьерн Страуструп. Язык программирования С . М Бином, 2011
2.6. Экономия памяти В процессе создания нетривиальной программы рано или поздно наступает момент, когда требуется
больше памяти, чем можно выделить или запросить. Есть два способа выжать еще некоторое
количество памяти:
[1] паковать в байты переменные с малыми значениями;
[2] использовать одну и ту же память для хранения разных объектов в разное время.
Первый способ реализуется с помощью полей, а второй - с помощью объединений. И те, и другие
описываются ниже. Поскольку назначение этих конструкций связано в основном с оптимизацией
программы, и поскольку, как правило, они непереносимы, программисту следует хорошенько
подумать, прежде чем использовать их. Часто лучше изменить алгоритм работы с данными, например,
больше использовать динамически выделяемую память, чем заранее отведенную статическую память.
2.6.1 Поля Кажется расточительным использовать для признака, принимающего только два значения ( например:
да, нет) тип char, но объект типа char является в С++ наименьшим объектом, который может
независимо размещаться в памяти. Однако, есть возможность собрать переменные с малым
диапазоном значений воедино, определив их как поля структуры. Член структуры является полем, если
в его определении после имени указано число разрядов, которое он должен занимать. Допустимы
безымянные поля. Они не влияют на работу с поименованными полями, но могут улучшить размещение
полей в памяти для конкретной машины:
struct sreg {
unsigned enable : 1;
unsigned page : 3;
unsigned : 1;
//
не используется
unsigned mode : 2;
unsigned : 4;
//
не используется
unsigned access : 1;
unsigned length : 1;
unsigned non_resident : 1;
};
Приведенная структура описывает разряды нулевого регистра состояния DEC PDP11/45
(предполагается, что поля в слове размещаются слева направо). Этот пример показывает также
другое возможное применение полей: давать имена тем частям объекта, размещение которых
определено извне. Поле должно иметь целый тип ($$R.3.6.1 и $$R.9.6), и оно используется аналогично
другим объектам целого типа. Но есть исключение: нельзя брать адрес поля. В ядре операционной
системы или в отладчике тип sreg мог бы использоваться следующим образом:
sreg* sr0 = (sreg*)0777572;
//...
if (sr0->access) {
// нарушение прав доступа
// разобраться в ситуации
sr0->access = 0;
}
Тем не менее, применяя поля для упаковки нескольких переменных в один байт, мы необязательно
сэкономим память. Экономится память для данных, но на большинстве машин одновременно
возрастает объем команд, нужных для работы с упакованными данными. Известны даже такие
программы, которые значительно сокращались в объеме, если двоичные переменные, задаваемые
Бьерн Страуструп.
Язык программирования С++
67
полями, преобразовывались в переменные типа char! Кроме того, доступ к char или int обычно
происходит намного быстрее, чем доступ к полю. Поля - это просто удобная краткая форма задания
логических операций для извлечения или занесения информации в части слова.