用链表解决if语句过多的问题(C/C++实现)
起因
http://www.cnblogs.com/code-style/p/3499408.html
设计模式的解决方案(基于python语言)
http://www.cnblogs.com/code-style/p/3501713.html
http://www.cnblogs.com/code-style/p/3502105.html
用设计模式实现完以后我突然发现,所谓的设计模式其实在C语言里不就是链表吗?当前节点能处理就处理不能处理让下一个节点处理,不多说,上代码
消息类的设计
message.h
#ifndef MESSAGE_H
#define MESSAGE_H #define TRUE 1
#define FALSE 0 typedef struct {
int sender;
int isSend;
int isCharge;
char date[];
}Message; Message * makeMessage(const int sender, const char *date);
void setSendFlag(Message * const message);
void setChargeFlag(Message * const message);
int isSameDate(const Message * const message, const char * const date);
char * format(const Message * const message);
const char * boolStr(const int value); #endif
message.c
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "message.h" Message * makeMessage(const int sender, const char *date)
{
Message *message = (Message*)malloc(sizeof(Message));
assert(message != NULL);
message->sender = sender;
message->isSend = FALSE;
message->isCharge = FALSE;
strncpy(message->date, date, );
return message;
} const char * boolStr(const int value)
{
return value == TRUE ? "TRUE" : "FALSE";
} char * format(const Message * const message)
{
#define BUF_SIZE 1024
static char buffer[BUF_SIZE];
memset(&buffer, , BUF_SIZE);
snprintf((char*)&buffer, BUF_SIZE, "Message <%d isSend:%s isCharge:%s>\n", \
message->sender, boolStr(message->isSend), boolStr(message->isCharge));
return (char*)buffer;
} void setSendFlag(Message * const message)
{
message->isSend = TRUE;
} void setChargeFlag(Message * const message)
{
message->isCharge = TRUE;
} int isSameDate(const Message * const message, const char * const date)
{
if (strncmp(message->date, date, ) == )
{
return TRUE;
}
else
{
return FALSE;
}
}
testMessage.c
#include <stdio.h>
#include "message.h"
#include "gtest/gtest.h" TEST(MESSAGE,makeMessage){
Message *message = makeMessage(,"");
EXPECT_EQ(, message->sender);
EXPECT_STREQ("Message <1 isSend:FALSE isCharge:FALSE>\n", format(message));
}
链表类的实现
node.h
#ifndef NOTE_H
#define NOTE_H typedef struct Node{
void *ptr;
struct Node *next;
}Node; Node *makeListWithArray(void *array[], int length);
void foreach(Node *list, void (*process) (Node *));
#endif
node.c
#include <stdlib.h>
#include <assert.h>
#include "node.h" Node *makeListWithArray(void *array[], int length)
{
int i;
Node *last = NULL; assert(array != NULL && length > );
for(i = length - ; i >= ; i--)
{
Node *node = (Node*)malloc(sizeof(Node));
node->ptr = array[i];
node->next = last;
last = node;
} return last;
} void foreach(Node *list, void (*process) (Node *))
{
Node *current = NULL; assert(list != NULL && process != NULL);
for(current = list; current != NULL; current = current->next)
{
process(current);
}
}
testNode.c
#include <stdio.h>
#include "node.h"
#include "gtest/gtest.h" void printNode(Node *node)
{
static int i = ;
int data[] = {,,};
EXPECT_EQ(data[i], *(int*)node->ptr);
i++;
} TEST(NODE,makeListWithArray){
int i;
int data[] = {,,};
void *aSet[] = {&data[], &data[], &data[]};
Node *list = makeListWithArray(aSet, );
foreach(list, printNode);
}
程序入口实现(main.c)
#include <stdio.h>
#include <string.h>
#include "message.h"
#include "node.h" # define FALSE
# define TRUE typedef int BOOL;
typedef BOOL (*FuncIsAllowSend)(Message *, Node*); BOOL isAllowSendCheckDate(Message *message, Node *node)
{
FuncIsAllowSend isAllowSend = NULL; if(strcmp(message->date, "") == )
{
return FALSE;
} isAllowSend = (FuncIsAllowSend) node->next->ptr;
return isAllowSend(message, node->next);
} BOOL isAllowSendCheckWhiteList(Message *message, Node *node)
{
FuncIsAllowSend isAllowSend = NULL; if(message->sender == )
{
return TRUE;
} isAllowSend = (FuncIsAllowSend) node->next->ptr;
return isAllowSend(message, node->next);
} BOOL isAllowSendWithDefault(Message *message, Node *node)
{
setChargeFlag(message);
return TRUE;
} int main()
{
Message *message = makeMessage(,"");
void *actionList[] = {(void*)&isAllowSendCheckDate,
(void*)&isAllowSendCheckWhiteList,
(void*)&isAllowSendWithDefault};
Node *theList = makeListWithArray(actionList, sizeof(actionList)/);
FuncIsAllowSend isAllowSend = (FuncIsAllowSend)theList->ptr;
if(isAllowSend(message, theList) == TRUE)
{
setSendFlag(message);
}
printf("%s\n",format(message));
}
代码风格其实是C风格,但是因为要使用gtest不得不使用了g++对程序进行编译调试,命令如下:
# 前提:我已经把gtest编译成库放在了系统目录下 g++ -c message.c
g++ -c testMessage.c
g++ message.o testMessage.o -lgtest -lpthread
./a.out g++ -c node.c
g++ -c testNode.c
g++ node.o testNode.o -lgtest -lpthread
./a.out g++ -c main.c
g++ message.o node.o main.o
./a.out
用链表解决if语句过多的问题(C/C++实现)的更多相关文章
- php实现单,双向链表,环形链表解决约瑟夫问题
传智播客PHP学院 韩顺平 PHP程序员玩转算法第一季 http://php.itcast.cn 聊天篇: 数学对我们编程来说,重不重要? 看你站在什么样的层次来说. 如果你应用程序开发,对数学要求 ...
- PHP算法学习(8) 环形链表 解决约瑟夫问题
2019年2月25日17:29:17 Josephus有过的故事:39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓.于是决定了自杀方式,41个人排成一个圆圈 ...
- mysql 线程等待时间,解决sleep进程过多的办法
如果你没有修改过MySQL的配置,缺省情况下,wait_timeout的初始值是28800. wait_timeout 过大有弊端,其体现就是MySQL里大量的SLEEP进程无法及时释放,拖累系统 ...
- TCP之再谈解决服务器TIMEWAIT过多的问题
原则 TIMEWAIT并不是多余的.在TCP协议被创造,经历了大量的实际场景实践之后,TIMEWAIT出现了,因为TCP主动关闭连接的一方需要TIMEWAIT状态,它是我们的朋友.这是<UNIX ...
- VS2017一步一步断点调试解决Dapper语句出现的Bug
最近再做一个项目,出现一个小bug,bug虽小,但是却要命啊.下面我show下我解决问题的方法. View层代码: @model List<mhq.Blog.Model.Blog> < ...
- 解决insert语句插入时,需要写列值的问题
今天发现解决这个问题其实很简单,闲话不多谈,我直接附上语句 ) select @s = isnull(@s+',', '') + [name] from syscolumns where id = o ...
- 使用java的循环单向链表解决约瑟夫问题
什么是约瑟夫问题 据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定 ...
- 单向环形链表解决约瑟夫环(Josephus)问题
一.约瑟夫环问题 Josephu 问题为:设编号为1,2,- n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那 ...
- PHP+Redis链表解决高并发下商品超卖问题
目录 实现原理 实现步骤 上一篇文章聊了一下使用Redis事务来解决高并发商品超卖问题,今天我们来聊一下使用Redis链表来解决高并发商品超卖问题. 实现原理 使用redis链表来做,因为pop操作是 ...
随机推荐
- 【Android - 框架】之Glide的使用
一.Glide简介: Glide是Google官方推荐的一个图片加载和缓存的开源库,它不仅能实现平滑的图片列表滚动效果,还支持远程图片的获取.大小调整和展示,并且可以加载GIF图片.Glide相比与U ...
- python 分支 循环
一 python 知识点 1.变量(标签): a(变量名) = '字符串'or 数字 (整形和浮点型) a相当于变量名的标签 如: a = ...
- SQL语法集锦一:SQL语句实现表的横向聚合
本文转载:http://www.cnblogs.com/lxblog/archive/2012/09/29/2708128.html 问题描述:假如有一表结构和数据如下: C1 C2 C3 C4 C5 ...
- ssl https服务 需要 php5.3以上
php 5.2 升级 5.3 http://wdlinux.cn/bbs/viewthread.php?tid=37512&highlight=5.3 默认的升级不支持 pdo 升级前编辑升级 ...
- [AngularJS] Default Child state and nav between child state
Let's say we want a parent state which is a abstract state. Two children states, one is for sinlge a ...
- android 44 SQLiteOpenHelper
java package com.sxt.day06_10; import java.util.ArrayList; import com.sxt.day06_10.entity.StudentBea ...
- android 10 事件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layo ...
- Note | Javascript权威指南[第六版] 第1章:Javascript概述
JavaScript是一门高端的.动态的.弱类型的编程语言,非常适合面向对象和函数式的编程风格.JavaScript的语法源自Java,它的一等函数(first-class function)来 ...
- 各大浏览器CSS Hack收集
各大浏览器CSS Hack收集 >>>>>>>>>>>>>>>>>>>>> ...
- python之enumerate枚举 第二篇(六):enumerate枚举
[Python之旅]第二篇(六):enumerate枚举 python enumerate枚举 摘要: 1.普通情况下打印列表中索引号及其对应元素 使用下面的循环: 1 2 3 4 5 6 ...