Да, вы просто определяете массив ваших 32-битных целых чисел.Затем вы манипулируете конкретным элементом массива.
Если указан битовый идентификатор от 0 до 255 включительно (например), это будет массив:
unsigned int bits[8];
Для того, чтобы найти какой элемент для работы:
unsigned int index = bitId >> 5; // turns 0..255 into 0..31
Чтобы получить маски для данного идентификатора бита:
unsigned int masks[] = {
0x0001, 0x0002, 0x0004, 0x0008,
0x0001, 0x0020, 0x0040, 0x0080,
0x0100, 0x0200, 0x0400, 0x0800,
0x1000, 0x2000, 0x4000, 0x8000
};
unsigned int mask = masks[bitId & 0x1f];
Если у вас есть тип uint32_t
, доступный в вашемреализация, это, вероятно, самый безопасный путь.В противном случае существуют известные способы использования unsigned int
с использованием CHAR_BIT
и sizeof
, чтобы фактически определить во время выполнения, насколько велик размер массива masks
и какие значения следует использовать для обнаружения индекса массива и индекса битовой маски.
Например, этот фрагмент из моей библиотеки кода показывает, как я это сделал для символьной битовой маски:
static unsigned char bitmask[CHAR_BIT];
void bitsetInit (void) {
unsigned char mask = 1;
int i = 0;
while (i < CHAR_BIT) {
bitmask[i++] = mask;
mask <<= 1;
}
}
и использования:
bsp->bits[bitnum/CHAR_BIT] &= ~bitmask[bitnum%CHAR_BIT];
bsp->bits[bitnum/CHAR_BIT] |= bitmask[bitnum%CHAR_BIT];
для очистки иустановка битов соответственно.
Если вы хотите использовать unsigned int
вместо unsigned char
, вы просто рассчитаете количество битов для этого:
unsigned int UINT_BIT = CHAR_BIT * sizeof (unsigned int);
и используйте его там, где яиспользуется CHAR_BIT
выше (массив mask
может быть динамически выделен во время выполнения при необходимости).