位图
说到位图,我们应该都不陌生。在学习信号的时候我们知道,信号有递达表,阻塞表。而这些表都是基于位图实现的。所谓位图,就是将每个比特位都当做一种特殊的意义,其值0与1的变化代表不同的含义。使用位图最大的优点就是节省空间。
位图的基本操作
位图主要的基本操作:
- 设置某一位有效(这里默认有效的含义就是对应比特位为1)
- 设置某一位无效
- 将位图全体置为0
- 将位图全体置为1
- 测试某一位是否被设置
实现
#pragma once
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#define BitMapType uint64_t//定义uint64_t的目的是为了代码的可移植性
typedef struct BitMap {
BitMapType* data;
uint64_t capacity;//代表位图总位数
} BitMap;//定义位图
void BitMapInit(BitMap* bm);//初始化位图
void BitMapSet(BitMap* bm, uint64_t index);//设置某一位为1
void BitMapUnSet(BitMap* bm, uint64_t index);//设置某一位为0
int BitMapTest(BitMap* bm, uint64_t index);//测验某一位是不是1
void BitMapDestroy(BitMap* bm);//销毁位图
void BitMapFill(BitMap* bm);//全部置为1
void BitMapEmpty(BitMap* bm);//全部置为0
#include "bit_map.h"
#define BitMapSize 100//位图总位数
uint64_t GetSize(uint64_t index)
{
return index /(sizeof(BitMapType) * 8) + 1;
}
void BitMapInit(BitMap* bm)//初始化位图
{
if(bm == NULL) {
return;
}
bm->capacity = BitMapSize;//初始化个数
uint64_t size = GetSize(bm->capacity);
bm->data = (BitMapType*)malloc(sizeof(BitMapType) * size);
memset(bm->data, 0, sizeof(BitMapType) * size);
return;
}
//这里规定返回为0的时候测验失败。
//返回值为1的时候测试成功
int BitMapTest(BitMap* bm, uint64_t index)//测验某一位是不是1
{
if(bm == NULL) {
return 0;
}
uint64_t offset = GetSize(index);
uint64_t size = index % (sizeof(BitMapType) * 8);
uint64_t ret = (bm->data[offset] & (0x1ul << size));
return ret > 0 ? 1 : 0;
}
void BitMapSet(BitMap* bm, uint64_t index)//设置某一位为1
{
if(bm == NULL) {
return;
}
//这里规定:
//如果设置的位数高于总位数,那么这个时候设置失败
if(index > bm->capacity) {
return;
}
uint64_t offset = GetSize(index);
uint64_t size = index % (sizeof(BitMapType) * 8);
bm->data[offset] |= (0x1ul << size);
return;
}
void BitMapUnSet(BitMap* bm, uint64_t index)//设置某一位为0
{
if(bm == NULL) {
return;
}
uint64_t offset = GetSize(index);
uint64_t size = index % (sizeof(BitMapType) * 8);
bm->data[offset] &= ~(0x1ul << size);
return;
}
void BitMapDestroy(BitMap* bm)//销毁位图
{
if(bm == NULL) {
return;
}
bm->capacity = 0;
free(bm->data);
bm->data = NULL;
return;
}
void BitMapFill(BitMap* bm)//全部置为1
{
if(bm == NULL) {
return;
}
memset(bm->data, 0xff, bm->capacity);
return;
}
void BitMapEmpty(BitMap* bm)//全部置为0
{
if(bm == NULL) {
return;
}
memset(bm->data, 0, bm->capacity);
return;
}
欢迎大家共同讨论,如有错误及时联系作者指出,并改正。谢谢大家!