高级语言中有键值对的概念,那么c语言也可以有!!
原文https://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;
}