1. Makefile
.PHONY: clean
CC = gcc
CFLAGS = -g -Wall -DDEBUG -std=c99
SOURCE = $(wildcard ./*.c)
BIN = $(patsubst %.c, %, $(notdir $(SOURCE)))
$(BIN): $(SOURCE)
$(CC) $(CFLAGS) $(SOURCE) -o $@
clean:
rm -rf $(BIN)
2. bitmap.h
/*
* File Name: bitmap.h
*
* Copyright (c) 2022, c code from sustzc.
* All rights reserved.
*/
extern "C" {
typedef struct {
int *data;
size_t size;
size_t capacity;
} bitmap_t;
// 初始化位图
bool init_bitmap(bitmap_t *bitmap, size_t bit_counts);
// 打印位图信息
void print_bitmap_info(const bitmap_t *bitmap);
// 获取比特位的个数
size_t get_bitmap_size(const bitmap_t *bitmap);
// 获取存储位图的容量
size_t get_bitmap_capacity(const bitmap_t *bitmap);
// 设置某个比特位 为 1
void bitmap_set(bitmap_t *bitmap, size_t which);
// 设置所有比特位 为 1
void bitmap_set_all(bitmap_t *bitmap);
// 设置某个比特位 为 0
void bitmap_reset(bitmap_t *bitmap, size_t which);
// 设置所有比特位 为 0
void bitmap_reset_all(bitmap_t *bitmap);
// 反转某个比特位
void bitmap_flip(bitmap_t *bitmap, size_t which);
// 反转所有比特位
void bitmap_flip_all(bitmap_t *bitmap);
// 测试某个比特位是否为 1
bool bitmap_test_one(bitmap_t *bitmap, size_t which);
// 获取比特位为 1 的个数
size_t get_bitmap_counts_of_one(const bitmap_t *bitmap);
// 判断是否有比特位被设置
bool bitmap_any(const bitmap_t *bitmap);
// 判断是否所有比特位都没被设置
bool bitmap_none(const bitmap_t *bitmap);
// 判断是否所有比特位都被设置为 1
bool bitmap_all(const bitmap_t *bitmap);
// 销毁位图
void destroy_bitmap(bitmap_t *bitmap);
}
3. bitmap.c
#include "bitmap.h"
#define INT_BIT_COUNTS (32)
bool init_bitmap(bitmap_t *bitmap, size_t bit_counts)
{
if (NULL == bitmap) {
return false;
}
size_t capacity = bit_counts / INT_BIT_COUNTS;
capacity += (bit_counts % INT_BIT_COUNTS) ? 1 : 0;
bitmap->data = (int *)calloc(1, sizeof(int) * capacity);
if (NULL == bitmap->data) {
perror("calloc bitmap->data fail");
return false;
}
bitmap->capacity = capacity;
bitmap->size = bit_counts;
return true;
}
size_t get_bitmap_capacity(const bitmap_t *bitmap)
{
return NULL == bitmap ? 0 : bitmap->capacity;
}
void print_bitmap_info(const bitmap_t *bitmap)
{
printf("in %s\n", __func__);
size_t i = 0, j = 0, bitmap_capacity = get_bitmap_capacity(bitmap);
for (; i < bitmap_capacity; ++i) {
for (j = 0; j < INT_BIT_COUNTS; ++j) {
if (bitmap->data[i] & (1 << j)) {
printf("bitmap[%zu][%zu] : 1\n", i, j);
} else {
printf("bitmap[%zu][%zu] : 0\n", i, j);
}
}
}
printf("\n");
}
size_t get_bitmap_size(const bitmap_t *bitmap)
{
return NULL == bitmap ? 0 : bitmap->size;
}
void bitmap_set(bitmap_t *bitmap, size_t which)
{
size_t bitmap_size = get_bitmap_size(bitmap);
if (which > bitmap_size) {
printf("in %s, which %zu > bitmap size %zu\n",
__func__, which, bitmap_size);
return;
}
size_t index = which / INT_BIT_COUNTS;
size_t bit = which % INT_BIT_COUNTS;
bitmap->data[index] |= (1 << bit);
}
void bitmap_set_all(bitmap_t *bitmap)
{
size_t i = 0, bitmap_size = get_bitmap_size(bitmap);
for (; i < bitmap_size; ++i) {
bitmap_set(bitmap, i);
}
}
void bitmap_reset(bitmap_t *bitmap, size_t which)
{
size_t bitmap_size = get_bitmap_size(bitmap);
if (which > bitmap_size) {
printf("in %s, which %zu > bitmap size %zu\n",
__func__, which, bitmap_size);
return;
}
size_t index = which / INT_BIT_COUNTS;
size_t bit = which % INT_BIT_COUNTS;
bitmap->data[index] &= (~(1 << bit));
}
void bitmap_reset_all(bitmap_t *bitmap)
{
size_t i = 0, bitmap_size = get_bitmap_size(bitmap);
for (; i < bitmap_size; ++i) {
bitmap_reset(bitmap, i);
}
}
void bitmap_flip(bitmap_t *bitmap, size_t which)
{
size_t bitmap_size = get_bitmap_size(bitmap);
if (which > bitmap_size) {
printf("in %s, which %zu > bitmap size %zu\n",
__func__, which, bitmap_size);
return;
}
size_t index = which / INT_BIT_COUNTS;
size_t bit = which % INT_BIT_COUNTS;
bitmap->data[index] ^= (1 << bit);
}
void bitmap_flip_all(bitmap_t *bitmap)
{
size_t i = 0, bitmap_size = get_bitmap_size(bitmap);
for (; i < bitmap_size; ++i) {
bitmap_flip(bitmap, i);
}
}
bool bitmap_test_one(bitmap_t *bitmap, size_t which)
{
size_t bitmap_size = get_bitmap_size(bitmap);
if (which > bitmap_size) {
printf("in %s, which %zu > bitmap size %zu\n",
__func__, which, bitmap_size);
return false;
}
size_t index = which / INT_BIT_COUNTS;
size_t bit = which % INT_BIT_COUNTS;
return bitmap->data[index] & (1 << bit);
}
size_t get_bitmap_counts_of_one(const bitmap_t *bitmap)
{
size_t i = 0, count = 0, bitmap_capacity = get_bitmap_capacity(bitmap);
for (; i < bitmap_capacity; ++i) {
int num = bitmap->data[i];
while (num) {
num &= (num - 1);
++count;
}
}
return count;
}
bool bitmap_any(const bitmap_t *bitmap)
{
size_t i = 0, bitmap_capacity = get_bitmap_capacity(bitmap);
for (; i < bitmap_capacity; ++i) {
if (0 != bitmap->data[i]) {
return true;
}
}
return false;
}
bool bitmap_none(const bitmap_t *bitmap)
{
return !bitmap_any(bitmap);
}
bool bitmap_all(const bitmap_t *bitmap)
{
size_t i = 0, bitmap_capacity = get_bitmap_capacity(bitmap);
for (; i < bitmap_capacity - 1; ++i) {
if (0 != ~(bitmap->data[i])) {
return false;
}
}
for (i = 0; i < bitmap_capacity % INT_BIT_COUNTS; ++i) {
if (0 == (bitmap->data[bitmap_capacity - 1] & (1 << i))) {
return false;
}
}
return true;
}
void destroy_bitmap(bitmap_t *bitmap)
{
if (NULL != bitmap) {
free(bitmap->data);
bitmap->data = NULL;
bitmap->size = 0;
bitmap->capacity = 0;
}
}
4. test_bitmap.c
#include "bitmap.h"
void test()
{
bitmap_t bitmap;
printf("init bitmap\n");
if (!init_bitmap(&bitmap, 40)) {
printf("init_bitmap fail\n");
return;
}
if (bitmap_none(&bitmap)) {
printf("\nbitmap set none bit\n");
}
printf("bit map size: %zu\n", get_bitmap_size(&bitmap));
printf("bit map capacity: %zu\n", get_bitmap_capacity(&bitmap));
print_bitmap_info(&bitmap);
bitmap_set(&bitmap, 10);
bitmap_set(&bitmap, 20);
bitmap_set(&bitmap, 30);
if (bitmap_any(&bitmap)) {
printf("\nbitmap set any bits\n");
}
print_bitmap_info(&bitmap);
printf("10 bit: %s\n", bitmap_test_one(&bitmap, 10) ? "1" : "0");
printf("reset 10th bit\n");
bitmap_reset(&bitmap, 10);
printf("10 bit: %s\n", bitmap_test_one(&bitmap, 10) ? "1" : "0");
printf("flip 10th bit\n");
bitmap_flip(&bitmap, 10);
printf("10 bit: %s\n", bitmap_test_one(&bitmap, 10) ? "1" : "0");
printf("The counts of bit(1): %zu\n", get_bitmap_counts_of_one(&bitmap));
printf("bit map size: %zu\n", get_bitmap_size(&bitmap));
printf("bit map capacity: %zu\n", get_bitmap_capacity(&bitmap));
bitmap_set_all(&bitmap);
if (bitmap_all(&bitmap)) {
printf("\nbitmap set all bits\n");
}
bitmap_reset_all(&bitmap);
if (bitmap_none(&bitmap)) {
printf("\nbitmap set none bit\n");
}
bitmap_flip_all(&bitmap);
if (bitmap_all(&bitmap)) {
printf("\nbitmap set all bits\n");
}
printf("\ndestroy_bitmap\n");
destroy_bitmap(&bitmap);
printf("bit map size: %zu\n", get_bitmap_size(&bitmap));
printf("bit map capacity: %zu\n", get_bitmap_capacity(&bitmap));
}
int main(void)
{
test();
return 0;
}