用链表解决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[8]; }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, 8); 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, 0, 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, 8) == 0) { return TRUE; } else { return FALSE; } }
testMessage.c
#include <stdio.h> #include "message.h" #include "gtest/gtest.h" TEST(MESSAGE,makeMessage){ Message *message = makeMessage(1,"20131212"); EXPECT_EQ(1, 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 > 0); for(i = length - 1; i >= 0; 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 = 0; int data[] = {1,2,3}; EXPECT_EQ(data[i], *(int*)node->ptr); i++; } TEST(NODE,makeListWithArray){ int i; int data[] = {1,2,3}; void *aSet[] = {&data[0], &data[1], &data[2]}; Node *list = makeListWithArray(aSet, 3); foreach(list, printNode); }
程序入口实现(main.c)
#include <stdio.h> #include <string.h> #include "message.h" #include "node.h" # define FALSE 0 # define TRUE 1 typedef int BOOL; typedef BOOL (*FuncIsAllowSend)(Message *, Node*); BOOL isAllowSendCheckDate(Message *message, Node *node) { FuncIsAllowSend isAllowSend = NULL; if(strcmp(message->date, "20130101") == 0) { return FALSE; } isAllowSend = (FuncIsAllowSend) node->next->ptr; return isAllowSend(message, node->next); } BOOL isAllowSendCheckWhiteList(Message *message, Node *node) { FuncIsAllowSend isAllowSend = NULL; if(message->sender == 10) { 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(1,"20131212"); void *actionList[] = {(void*)&isAllowSendCheckDate, (void*)&isAllowSendCheckWhiteList, (void*)&isAllowSendWithDefault}; Node *theList = makeListWithArray(actionList, sizeof(actionList)/4); 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
posted on 2014-02-07 14:38 codestyle 阅读(1831) 评论(5) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述