Странности при создании структур мы с вами разобрали,теперь научимся ими управлять.Думаю вы без меня прекрасно поняли,что если правильно подсчитывать биты можно уже неплохо экономить место.
При экономии даже каких-то 4 байта-уже хороший показатель того,что вы знаете своё дело.В некоторых проектах эти 4 байта могут быть ключевыми,особенно если требуется часто пользоваться структурой.
Довольно демагогии,приступим к разбору новой директивы препроцессора,которая облегчит создание компактных структур,а именно pragma.
#pragma используется для задания правил компилятору прям из файла программы.И в зависимости от компилятора те или иные настройки вам доступны.Мы рассмотрим только ту,что поможет сэкономить память,выглядит она так:
#pragma pack(push,1)
Добавив эту строчку в файл-вы получите выравнивание всего кода в один байт и потеряете в скорости выполнения.Это нас не устраивает,поэтому после создания структуры рекомендую добавить:
#pragma pack(push)
То есть примерно так:
#pragma pack(push,1)
struct structname
{
//...
};
#pragma pack(push)
И всё вернётся на круги своя.Попробуйте инициализировать структуру с этими директивами и посмотрите на её размер.
Всё это замечательно,только не спроста же компилятор по умолчанию добавляет мусорные поля? Так и есть,если вы создадите вторую структуру с этой директивой-получите ряд незабываемых ощущений во время их активного использования.
Отбросив интригу-одна структура "наложится" на другу.То есть в наш сэкономленный байт компилятор упакует вторую структуру.Так что не злоупотребляйте,одна программа-одна структура с pragma.
Возможности си на этом не заканчиваются.Что,если я вам скажу,что поля в структуре можно сжать не до байта,а до бита? Сейчас всё объясню.
Если вы уже пробовали "по умолчанию" установить какие-нибудь значения в структуру-то наверняка получили рекомендации от компилятора в использовании двоеточия (':').С помощью него как раз и можно указывать количества бит для всех данных внутри структуры.
В этом есть пара правил-нельзя выходить за пределы типа,так же нельзя создавать нулевые и отрицательные типы данных.В остальном компилятор вас не остановит:
struct
{
unsigned int ch:10;//2 10=1024
}
Попробуйте инициализировать эту структуру и задать число 1024.Компилятор будет ругаться,потому как наша переменная принимает от 0 до 1023(всего 1024 чисел).
К сожалению прям до байт структуру упаковать не получится.Компилятор так или иначе вставит пустые места во избежание конфликтов.Но если вы ограничите структуру из прошлого урока таким образом-результат на лицо.Из старых 12 байт можно получить 4!В три раза меньше,Карл!
Как вы видите в си можно делать всё,что вам вздумается.Главное-взвешивать последствия.На мой взгляд самым лучшим способом экономии места-самый первый способ,что мы разбирали в прошлой статье.Безопасен,удобен и что важно-компилятору всё нравится.
С вами был D21nkMaster.Всего наилучшего!