用C语言实现键值对-键->函数

高级语言中有键值对的概念,那么c语言也可以有!!

原文icon-default.png?t=N7T8https://www.zhihu.com/people/jiu_sheng初衷是想要实现这样的代码框架,优化代码的思路。

【理念】:所有的功能模块都封装进一个结构体FlechazokeyValue

食用步骤:

1、vfkeyvalueInit();//初始化

2、FlechazokeyValue.addkv();//添加键值对

3、FlechazokeyValue.getvalue();//可以创建一个函数指针,指向这个函数,然后执行

核心就是一个数据对应着一个函数。

获取key对应函数:【getvalue本身是个函数指针,他的返回值也是一个函数指针】

void *(*getvalue)(const F_KEY_TYPE *key,const uint32_t keylen);

那么上代码吧

fkeyvalue.h

#ifndef __FKEYVALUE_H
#define __FKEYVALUE_H

#include "stdio.h"
#include "stdlib.h"
#include "stdbool.h"
#include "gd32f30x.h"

//定义键值对-->>键的类型--->>>键的长度
#define F_KEY_TYPE uint8_t
#define FLECHAZO_KEY_LEN 1
//目前值为函数指针
//定义键值对-->>值的类型--->>>值的长度
// #define F_VALUE_TYPE (void *)
// #define FLECHAZO_VALUE_LEN 1
#define FLECHAZO_KEYVALUE_GROUP 100


//键值对数据结构体
typedef struct{
        //键值对
        //1、键 是一个uint8_t类型的数组,元素 key keylen 
        F_KEY_TYPE *key;
        //2、值 为一个函数指针 指向你的函数, 元素 函数名value 参数info
        void (*value)(uint8_t *info);
}keyValueData_S;


//键值对操作结构体
typedef struct{
    //1、增
    bool (*addkv)(const F_KEY_TYPE *key,const uint32_t keylen,void *func);
    //2、删
    bool (*delkv)(const F_KEY_TYPE *key,const uint32_t keylen);
    //3、改
    bool (*changekv_k)(const F_KEY_TYPE *skey,const uint32_t keylen,const F_KEY_TYPE *tkey);
    bool (*changekv_v)(const F_KEY_TYPE *key,const uint32_t keylen,void *func);
    //4、获取 根据键key获取其对应的值value
    void *(*getvalue)(const F_KEY_TYPE *key,const uint32_t keylen);
 
}keyValueControl_S;


typedef struct{
    uint32_t num;
    keyValueData_S *kvdata;
    keyValueControl_S kvctr;
 
}FlechazokeyValue_S;


void vfkeyvalueInit(void);

static bool bfkeyvalueAddkv(const F_KEY_TYPE *key,const uint32_t keylen,void *func);
static bool bfkeyvalueDelkv(const F_KEY_TYPE *key,const uint32_t keylen);
static bool bfkeyvalueChangekv_k(const F_KEY_TYPE *skey,const uint32_t keylen,const F_KEY_TYPE *tkey);
static bool bfkeyvalueChangekv_v(const F_KEY_TYPE *key,const uint32_t keylen,void *func);
static void *pvfkeyvalueGetValue(const F_KEY_TYPE *key,const uint32_t keylen);

static uint32_t uifkeyvalueGetFreeAdd(void);
bool bflechazoCheckItemInArr(const uint8_t *arr,const uint8_t value,const uint32_t len);
static uint32_t uifkeyvalueGetKeyGroup(const F_KEY_TYPE *key,const uint32_t keylen);


#endif //__FKEYVALUE_H

fkeyvalue.c

#include "fkeyvalue.h"
#include "string.h"

//所有的键值对存放在这,通过指针去查询
keyValueData_S kvdata[FLECHAZO_KEYVALUE_GROUP];

//理念:所有的功能都封装为一个结构体
FlechazokeyValue_S FlechazokeyValue;

void vfkeyvalueTest(uint8_t v){
    printf("\nThis is flechazo keyvalue test.%d\n",v);
}

//1、初始化
void vfkeyvalueInit(void){
    //初始化数据
    FlechazokeyValue.num=0;
    FlechazokeyValue.kvdata=kvdata;
    //初始化函数指针
    FlechazokeyValue.kvctr.addkv = bfkeyvalueAddkv;
    FlechazokeyValue.kvctr.delkv = bfkeyvalueDelkv;
    FlechazokeyValue.kvctr.changekv_k = bfkeyvalueChangekv_k;
    FlechazokeyValue.kvctr.changekv_v = bfkeyvalueChangekv_v;
    FlechazokeyValue.kvctr.getvalue = pvfkeyvalueGetValue;
	
		uint8_t k = 2;
    FlechazokeyValue.kvctr.addkv(&k,FLECHAZO_KEY_LEN,vfkeyvalueTest);
}
//1、增
//bool (*addkv)(const uint8_t *key,const uint32_t keylen,void *func);
static bool bfkeyvalueAddkv(const F_KEY_TYPE *key,const uint32_t keylen,void *func){
    //获取空闲地址
    uint32_t group = uifkeyvalueGetFreeAdd();
    //num!=0    group=0
    if((!FlechazokeyValue.num)&&(group)){
			//说明存储控件满了
		}
    //保存键
    memcpy(FlechazokeyValue.kvdata[group].key,key,keylen);
    //保存值
    FlechazokeyValue.kvdata[group].value=func;
    //计数+1
    FlechazokeyValue.num++;
    return true;
}

//2、删
//bool (*delkv)(const uint8_t *key,const uint32_t keylen);
static bool bfkeyvalueDelkv(const F_KEY_TYPE *key,const uint32_t keylen){
    //如果当前没有键值对
    if(!FlechazokeyValue.num){
			return false;
		}
    //根据键获取组号
    uint32_t group = uifkeyvalueGetKeyGroup(key,keylen);
    //清除key
    memset(FlechazokeyValue.kvdata[group].key,0x00,keylen);
    //计数-1
    FlechazokeyValue.num--;
    return true;
}


//3、改
//bool (*changekv_k)(const uint8_t *skey,const uint32_t keylen,const uint8_t *tkey);
static bool bfkeyvalueChangekv_k(const F_KEY_TYPE *skey,const uint32_t keylen,const F_KEY_TYPE *tkey){
    //如果当前没有键值对
    if(!FlechazokeyValue.num){
			return false;
		}
    //找到key
    uint32_t group = uifkeyvalueGetKeyGroup(skey,keylen);
    //修改
		memcpy(FlechazokeyValue.kvdata[group].key,tkey,keylen);
    return true;
}

//bool (*changekv_v)(const uint8_t *key,const uint32_t keylen,void *func);
static bool bfkeyvalueChangekv_v(const F_KEY_TYPE *key,const uint32_t keylen,void *func){
    //如果当前没有键值对
    if(!FlechazokeyValue.num){
			return false;
		}
    //找到key
    uint32_t group = uifkeyvalueGetKeyGroup(key,keylen);
    //修改
		FlechazokeyValue.kvdata[group].value=func;
    return true;
}
//4、获取 根据键key获取其对应的值value
//void *(*getvalue)(uint8_t *key,uint32_t keylen);
static void *pvfkeyvalueGetValue(const F_KEY_TYPE *key,const uint32_t keylen){
    //如果当前没有键值对
    if(!FlechazokeyValue.num){
			return false;
		}
    //找到key
    uint32_t group = uifkeyvalueGetKeyGroup(key,keylen);
		
		return FlechazokeyValue.kvdata[group].value;
}




//根据key获取存储数组中的组号
static uint32_t uifkeyvalueGetKeyGroup(const F_KEY_TYPE *key,const uint32_t keylen){
    for(uint32_t g=0;g<FLECHAZO_KEYVALUE_GROUP;g++){
		    if(memcmp(FlechazokeyValue.kvdata[g].key,key,keylen)){
					return g;
				}
		}
		return false;
}

//获取新增键值对地址[返回值为第x组键值对]
static uint32_t uifkeyvalueGetFreeAdd(void){
	for(uint32_t g=0;g<FLECHAZO_KEYVALUE_GROUP;g++){
		if(bflechazoCheckItemInArr(FlechazokeyValue.kvdata[g].key,0x00,FLECHAZO_KEY_LEN)){
			return g;
		}
	}
	return false;
}

//检查数组中的每个元素的值
bool bflechazoCheckItemInArr(const uint8_t *arr,const uint8_t value,const uint32_t len){
	for(uint32_t l=0;l<len;l++){
		if(*(arr+len)!=value){
			return false;
		}
	}
	return true;
}
  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FlechazoCLF

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值