C语言设计新思路
C语言大家大学都学过,很多平常很难想到去使用的,但是用起来能让你拍案叫绝的设计思路,特来总结一下,分享一波。
------我的目标是分享代码,让大家懂原理,大胆的用到自己的代码里。
函数指针做成多态的效果
函数指针的作用,相必大家都是了解的,c++的虚函数就是通过对c语言的函数指针封装做到的,所以它和多态具有着天生的联系。为什么我们要使用多态,在华为编程规范中有一条要求就是单个函数的代码长度不超过50行,但我们平时写的代码为了保持规范很容易在输出回显的函数超过50行甚至上百行还不能完成任务,下面函数指针的设计思路来了。
struct set_param {
//定义一个包含函数指针的结构体,上面关于还要加入一个结构体对应的名字
char name[SET_PARAM_NAME_LENGTH];
//SET_PARAM_NAME_LENGTH 定义长度为64
int (*route_get)(struct ds *reply, struct route_info *route_info);
};
static int route_get_vm_position_table_ipv4(struct ds *reply, struct route_info *route_info)
//设置对应函数参数与函数指针所代表的一致
{
ds_put_format(reply, "vm_position_table_ipv4 = %u\n", route_info->vm_position_table_ipv4);
return 0;
}
static int route_get_vm_position_table_ipv6(struct ds *reply, struct route_info *route_info)
//设置对应函数参数与函数指针所代表的一致
{
ds_put_format(reply, "vm_position_table_ipv6 = %u\n", route_info->vm_position_table_ipv6);
return 0;
}
static struct set_param set_param_array[] = {
{
//绿色的对应上面的结构体 (我们当它和 int 类型一样)红色的是真正的变量 对应是一个一维结构体数组并赋值
ROUTE_VM_POSTION_TABLE_IPV4,
// #define ROUTE_VM_POSTION_TABLE_IPV4 "vm_position_table_ipv4"
route_get_vm_position_table_ipv4
//为函数指针进行初始化 (注意函数指针初始化的不需要参数)
},
{
ROUTE_VM_POSTION_TABLE_IPV6,
route_get_vm_position_table_ipv6
}
};
static void route_get_all(struct ds *reply, struct route_info *route_info) //我们可以用函数指针所构造的多态来完成你想要的答案
{
int i;
for (i = 0; i < sizeof(set_param_array) / sizeof(set_param_array[0]); ++i) {
//运用for循环进行输出是不是每一条输出合理呀
set_param_array[i].route_get(reply, route_info);
}
}
使用位运算进行hash存储
在C++中我们可以直接使用bitset来进行对位判断,在命令行解析中有很大的用处可以判断是否对参数赋值。
1.首先在枚举中加入你要的类型
enum evs_route_cmd_info_enum {
EVS_ROUTE_VRF = 0,
EVS_ROUTE_VM_POS_TABLE,
EVS_ROUTE_VM_POS_TABLE_V6
};
2.建立对应的位运算的组 (包含你要的参数用或来连接)
#define ROUTE_SET_PARAM_BITMAP ((1UL << EVS_ROUTE_VM_POS_TABLE_V6) | (1UL << EVS_ROUTE_VM_POS_TABLE))
1UL的作用是的目的?
1 ---------有符号整形1
1UL--------无符号长整型1
3.后面就可以用位运算的操作来进行判断
(其中parser.bitmap对应是一个无符号64位整数 代表可以支持64个变量的hash)
if (bitset & (~ROUTE_SET_PARAM_BITMAP)) {
goto err; //拿goto举个例子说明bitset中没有配置我们要的参数
}
可能有些人对位运算不熟悉 我科普一下 :
& | ~ 分别代表 与 或 非(按位取反)
2 & 1 结果为 0
2 | 1 结果为 3,
~0 结果11111111(拿8字节举个例子)
4.我们还可以进一步进行判断
if (bitset & (1UL << EVS_ROUTE_VM_POS_TABLE_V6)) {
route_info->vm_pos_table_v6 = parser.vm_pos_table_v6;
}
if (bitset & (1UL << EVS_ROUTE_VM_POS_TABLE)) {
route_info->vm_pos_table = parser.vm_pos_table;
}