Найти тему
D21nk Master

Создавай структуры как боженька

Странности при создании структур мы с вами разобрали,теперь научимся ими управлять.Думаю вы без меня прекрасно поняли,что если правильно подсчитывать биты можно уже неплохо экономить место.

При экономии даже каких-то 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.Всего наилучшего!