此文章是孟宁老师的高软作业,也是对自己学习的总结
参考资料:https://gitee.com/mengning997/se/blob/master/README.md#%E4%BB%A3%E7%A0%81%E4%B8%AD%E7%9A%84%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B
一、环境搭建
1.下载vcode:
这部分上一份博客有详细说过,这里就略过
2.搭建gcc:
编译工具我们选用gcc(全称GNU Compiler Collection 意思是GNU编译器套件),不过不是原版的gcc,而是它在Windows下的特制版MinGW(全称Minimalist GNU on Windows)。它实际上是将GCC 移植到 了 Windows 平台下,并且包含了 Win32API ,因此可以将源代码编译为可在 Windows 中运行的可执行程序。而且还可以使用一些 Windows 不具备的,Linux平台下的开发工具。MinGW又分为MinGW-w64 与 MinGW ,区别在于 MinGW 只能编译生成32位可执行程序,而 MinGW-w64 则可以编译生成 64位 或 32位 可执行程序。MinGW 现已被 MinGW-w64 所取代,且 MinGW 也已停止了更新。
因此,我们最终下载安装的是MinGW-w64
https://sourceforge.net/projects/mingw-w64/files/
在path中配置bin文件的路径
打开cmd,输入gcc --version,查看gcc版本,有如下信息说明安装成功
再vcode里,快捷键ctrl+shift+p做相应配置
至此,就可以运行c程序了。
对模块化设计、可重用接口、线程安全等议题结合代码进行理解和分析;
二、模块化设计:
模块化设计,简单地说就是程序的编写不是开始就逐条录入计算机语句和指令,而是首先用主程序、子程序、子过程等框架把软件的主要结构和流程描述出来,并定义和调试好各个框架之间的输入、输出链接关系。逐步求精的结果是得到一系列以功能块为单位的算法描述。以功能块为单位进行程序设计,实现其求解算法的方法称为模块化。模块化的目的是为了降低程序复杂度,使程序设计、调试和维护等操作简单化。改变某个子功能只需相应改变相应模块即可。
在.h文件中对多种数据结构,包括结点和表都做了声明,之后在.c中进行具体实现和使用,声明与实现分离,使得代码的阅读更加清晰
linktable.h
#ifndef _LINK_TABLE_H_ #define _LINK_TABLE_H_ #include <pthread.h> #define SUCCESS 0 #define FAILURE (-1) /* * LinkTable Node Type */ typedef struct LinkTableNode { struct LinkTableNode * pNext; }tLinkTableNode; /* * LinkTable Type */ typedef struct LinkTable tLinkTable; /* * Create a LinkTable */ tLinkTable * CreateLinkTable(); /* * Delete a LinkTable */ int DeleteLinkTable(tLinkTable *pLinkTable); /* * Add a LinkTableNode to LinkTable */ int AddLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode); /* * Delete a LinkTableNode from LinkTable */ int DelLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode); /* * Search a LinkTableNode from LinkTable * int Conditon(tLinkTableNode * pNode,void * args); */ tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode, void * args), void * args); /* * get LinkTableHead */ tLinkTableNode * GetLinkTableHead(tLinkTable *pLinkTable); /* * get next LinkTableNode */ tLinkTableNode * GetNextLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode); #endif /* _LINK_TABLE_H_ */
linktable.c部分代码
struct LinkTable { tLinkTableNode *pHead; tLinkTableNode *pTail; int SumOfNode; pthread_mutex_t mutex; }; /* * Create a LinkTable */ tLinkTable * CreateLinkTable() { tLinkTable * pLinkTable = (tLinkTable *)malloc(sizeof(tLinkTable)); if(pLinkTable == NULL) { return NULL; } pLinkTable->pHead = NULL; pLinkTable->pTail = NULL; pLinkTable->SumOfNode = 0; pthread_mutex_init(&(pLinkTable->mutex), NULL); return pLinkTable; } /* * Delete a LinkTable */ int DeleteLinkTable(tLinkTable *pLinkTable) { if(pLinkTable == NULL) { return FAILURE; } while(pLinkTable->pHead != NULL) { tLinkTableNode * p = pLinkTable->pHead; pthread_mutex_lock(&(pLinkTable->mutex)); pLinkTable->pHead = pLinkTable->pHead->pNext; pLinkTable->SumOfNode -= 1 ; pthread_mutex_unlock(&(pLinkTable->mutex)); free(p); } pLinkTable->pHead = NULL; pLinkTable->pTail = NULL; pLinkTable->SumOfNode = 0; pthread_mutex_destroy(&(pLinkTable->mutex)); free(pLinkTable); return SUCCESS; }
menu的.h文件和.c文件也是一样原理,但是menu.c也有自己的独特实现
typedef struct DataNode { tLinkTableNode * pNext; char* cmd; char* desc; int (*handler)(int argc, char *argv[]); } tDataNode;
这是针对命令所设计的结点类型。
三、可重用接口:
在代码中,有一部分的代码是重复使用的,这会造成代码的冗余,而把这些重复使用的代码单拎出来,写成可以被直接调用的部分,就会大大提高代码的可复用性。
SearchLinkTableNode函数里的参数Conditon其实是一个函数,他将会被重复使用的功能集成起来,其他函数需要时直接调用,一方面减少了代码冗余,增加可读性,另一方面对于未来如果需要修改Conditon这部分被复用的内容也十分方便。
四、线程安全:
线程安全是多线程编程时的计算机程序代码中的一个概念。在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。
在程序中使用多线程可以提高程序的执行速度,但是需要考虑线程的异步性问题,对于一些类原子操作需要加锁,保证他的执行过程是安全的,下面代码中使用pthread_mutex_lock加锁。
int DeleteLinkTable(tLinkTable *pLinkTable) { if(pLinkTable == NULL) { return FAILURE; } while(pLinkTable->pHead != NULL) { tLinkTableNode * p = pLinkTable->pHead; pthread_mutex_lock(&(pLinkTable->mutex)); pLinkTable->pHead = pLinkTable->pHead->pNext; pLinkTable->SumOfNode -= 1 ; pthread_mutex_unlock(&(pLinkTable->mutex)); free(p); } pLinkTable->pHead = NULL; pLinkTable->pTail = NULL; pLinkTable->SumOfNode = 0; pthread_mutex_destroy(&(pLinkTable->mutex)); free(pLinkTable); return SUCCESS; }
五、总结
在这次的作业中,提高了对于vc工具的使用,代码阅读的过程也为自己代码编写的能力提供了帮助。