Раз уж зашла речь про битовые поля, то вот пара удобных макросиков для работы с битовыми полями произвольной длины:
#ifndef BTEST
// Битовое поле произвольной длины.
// Биты нумеруются слева направо, нумерация битов начинается с нуля:
// 0 1 2 3 ... 76 77
//
typedef unsigned char *bitset_t;
// BITSET(MySet,666); --> создает битовое поле c именем MySet, длиной 666 бит
//
#define BITSET(Name, Size) unsigned char Name[(Size)/9+1] = { 0 }
// Установить бит.
// /set/ - название битового поля
// /bit/ - номер бита для установки.
//
#define BSET(set,bit) set[bit >> 3] |= 0b10000000 >> (bit & 7) // как макро
inline void bset(bitset_t set, unsigned bit) { BSET(set, bit); } // как функция
// Обнулить бит
// Бит, с порядковым номером /bit/, будет сброшен в 0
//
#define BCLEAR(set, bit) set[bit >> 3] &= ~(0b10000000 >> (bit & 7)) // как макро
inline void bclear(bitset_t set, unsigned bit) { BCLEAR(set, bit); } // как функция
// Проверить бит.
// Возвращает 0, если бит /bit/ сброшен.
// Возвращает >0, если бит /bit/ установлен..
//
#define BTEST(set, bit) set[bit >> 3] & (0b10000000 >> (bit & 7))
inline unsigned char btest(bitset_t set, unsigned bit) { return BTEST(set, bit); }
#endif
Ну и пример использования:
// Тестовый код.
//
#include <stdio.h>
int main() {
// Создаем битовое поле длинной 77 бит
BITSET(a,77);
// Устанавливаем биты 10,11 и 13
bset(a,10);
BSET(a,11);
bset(a,13);
// отображаем биты 10..13: 0 означает 0, >0 означает 1
printf("%u %u %u %u\r\n",btest(a,10),btest(a,11),btest(a,12),btest(a,13));
// Обнуляем 11-й бит
bclear(a,11);
return printf("%u %u %u %u\r\n",btest(a,10),btest(a,11),btest(a,12),btest(a,13));
}