首页 > 解决方案 > 如何在 C 中的 char 数组中更改位图的一位?

问题描述

我被迫使用 char 数组作为位图。例如,这将是一个 32 位的位图:

char bitmap[4];

之前,我已经将该数组的每个字节初始化为 0。我的问题是,我怎样才能将这个数组的一个位更改为我想要的那个?我正在寻找一个与此结构相似的函数,其中位图作为参数传递,以及我们想要更改的位的索引以及我们想要将其更改为的值:

set_bit(char *bitmap, int bit, int value);

他们强迫我使用 char 数组而不是 unsigned char 数组。具有类似结构的 get_bit 函数也很有用,它只要求位图和要探测的位作为参数。

先感谢您。

编辑:我在 set_bit 定义中修复了位图的类型

标签: carraysbitmapchar

解决方案


void setbit(void *arr, size_t bit, unsigned val)
{
    unsigned char *ucarr = arr;     // void * to prevent compiler warnings when you pass other type pointer. 
    size_t index = bit >> 3;        //>>3 is == divide by 8 which is number of bits in char on most systems. Index number
    unsigned char mask = 1 << (bit & 7);  // &7 - bit number in the 8 bits charackter

    ucarr[index] &= ~mask;               // zero the bit
    ucarr[index] |= mask * (!!val);      // set the bit to the value (1 of var nonzero, 0 if var == 0) 

}

或者如果您确定这val将是10更高效的版本(几个时钟)

void setbit1(void *arr, size_t bit, unsigned val)
{
    unsigned char *ucarr = arr;
    size_t index = bit >> 3;
    size_t bitindex = bit & 7;
    unsigned char mask = 1 << bitindex;

    ucarr[index] &= ~mask;
    ucarr[index] |= val << bitindex; 
}

或者更便携的版本(CHAR_BIT 高达 256)

#define CHO     (((CHAR_BIT >> 1) & 1)*2 + ((CHAR_BIT >> 2) & 1)*4 + ((CHAR_BIT >> 3) & 1)*8 + ((CHAR_BIT >> 4) & 1)*16 + ((CHAR_BIT >> 5) & 1)*32 + ((CHAR_BIT >> 6) & 1)*64 + ((CHAR_BIT >> 7) & 1)*128 + ((CHAR_BIT >> 8) & 1)*256)

void setbit(void *arr, size_t bit, unsigned val)
{
    unsigned char *ucarr = arr;
    size_t index = bit >> CHO;
    unsigned char mask = 1 << (bit & (CHAR_BIT - 1));

    ucarr[index] &= ~mask;
    ucarr[index] |= mask * (!!val); 
}

void setbit1(void *arr, size_t bit, unsigned val)
{
    unsigned char *ucarr = arr;
    size_t index = bit >> CHO;
    size_t bitindex = bit & (CHAR_BIT - 1);
    unsigned char mask = 1 << bitindex;

    ucarr[index] &= ~mask;
    ucarr[index] |= val << bitindex; 
}

推荐阅读