pre-scriptum: Пока я отвлекался, фактически то же самое уже было написано, но я и свои 5 копеек вставляю.
Ваш код тоже не подходит

Ну и вопрос сразу: странно — какой это компилятор не поддерживает битовые поля?
Они существуют с давних пор, от начала существования С.
Artos писал(а):Имею байтовые переменные
unsigned char x, y, z, k, l;
Для начала, если это не «так, для примера», а реальные переменные, очень рекомендую перестать использовать однобуквенные имена для чего-либо, кроме «очень локальных» переменных, например, индексов циклов. Т.е. от места определения такой переменной до места её исчезновения должно быть не больше половины экрана кода

Иначе очень быстро с ростом размеров программ будет путаница.
А осмысленные имена избавляют от необходимости писать комментарии вида
или
В записях
или
символов набирать нужно меньше
По флагам.
За исключением расширения языка С в виде поддержки битовых переменных, как это есть для MCS51, остальные способы разменивают размер ОЗУ на размер флеша.
Запись
Код: Выделить всё
enum { flag1 = 0x01, flag2 = 0x02, flag3 = 0x03 }; // Имена для примера :)))
uint8_t flags;
if (flags & flag1) flags &= ~flag2;
муторная, но в большинстве компиляторов даст минимальный код. Больше, чем
но минимально возможный для упакованніх в байт битов.
Запись в виде битовых полей
Код: Выделить всё
struct {
unsigned char flag1 : 1; // выделяем под поле один бит
unsigned char flag2 : 1; // выделяем под поле один бит
unsigned char flag3 : 1; // выделяем под поле один бит
unsigned char : 1; // пропускаем один бит (ровняем state на полубайт), имя не обязательно
unsigned char state : 4; // выделяем под поле четыре бита
} fags; // в сумме 8 бит займут один байт
if (flags.flag1) flags.state = 3;
приятнее, но может привести к размеру кода большему, чем с масками выше. Зависит от компилятора.
Но чем ближе светлое будущее, тем компиляторы умнее, так что постепенно это становится не таким страшным.
Для возможности поиграться между расходом ОЗУ и ПЗУ я иногда делаю так
Код: Выделить всё
#ifdef SMALL_RAM
#define ONEBIT : 1 // будут выделены биты
#else
#define ONEBIT // будут выделены байты
#endif
struct {
unsigned char flag1 ONEBIT ;
unsigned char flag2 ONEBIT ;
unsigned char flag3 ONEBIT ;
} fags;
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.