C语言项目——工程化编程的案例分析
一、VSCode安装及环境配置
初始在Win下安装Mingw-w64/GCC 和 GDB,在VSCode下打开项目案例,发现在linktable中需要包含pthread头文件。此文件是基于Linux系统环境下的头文件,对应win系统环境下的window.h头文件。所以,本人为了方便后续操作方便,改在Ubuntu下进行项目案例分析。
进入Ubuntu,在Ubuntu软件中搜索安装VSCode;VSCode中下载安装C/C++环境插件;打开对应项目案例文件夹。首先查看Makefile文件:
这里make all指令表示执行后会编译文件夹下的.c文件。

在VSCode终端下运行make all,编译生成了对应的三个.c文件的.o文件,因为Makefile里没有添加对其他三个test_.c的操作,所以当前是不能指令执行这三个c文件。

在终端下运行make clean,删除了生成的原本的三个.o文件

终端下运行./test

输入已实现的cmd命令名,这里补充了fork、exec和quit指令操作

二、分析代码的艺术
1.程序块头部注释
这里标明了代码语言以及该文件的作用,模块的对外接口,方便自动生成开发者文档。

2.模块化软件设计
模块化是在软件系统设计时保持系统内各部分相对独立,以便每一个部分可以被独立地进行设计和开发。这个做法被的基本原理是关注点的分离。在此编程项目中也体现到了关注点的分离,首先来看耦合:总体代码文件分成linktable、menu、test三大类,分别实现的是程序接口结构设计、命令菜单解析命令操作以及测试文件。前两类有细分成了.c文件和.h文件,.h文件存放功能实现函数的声明、.c文件存放功能实现函数的定义。这样两两文件又有着联系,命令菜单解析命令操作需要接口结构来体现,测试文件需要基于他们来实现具体案例。然后来看内聚,分为三大类,分别实现不同的功能就是内聚的体现。KISS原则即一行代码制作一件事、一块代码只做一件事、一个函数只做一件事、一个模块只做一件事。

3.可重用软件设计
首先考虑Consumer Reuse和Produce Reuse(消费者重用和生产者重用),Consumer Reuse重在重用已有的一些软件模块代码,以加快项目工作进度。比如说最常见的max()、min()的实现,每次在需要输出最大最小数值时,都要重写一遍。如果把这些思想用一个模块封装在一起,这样每次使用,只需短短一行即可。在本menu案例中,如下函数都是消费者重用的体现

Produce Reuse重在设计可重用软件的设计,大致需要注意几个因素:通用模块、通用接口并有清晰完善的定义描述、清晰一致的命名规则等。本案例中在.h文件中即是生产者重用的体现:

每个函数都有一个直观的函数名,以及参数名,在声明结束后会通过注释的方式给出对用到的数据结构和算法的清晰的文档描述。其次是软件模块接口的实现艺术,首先理解函数的接口规格,主要体现callin和callback两个函数方式的接口,如上图的CreateLInkTable、AddLinkTableNode以及DelLinkTableNode三个函数,均给出了callin接口的需要的参数类型和参数名,并且从函数名和参数名就可以很直观的看出其实际的意义。图中最后一个函数拥有一个特殊的参数成员:

这是一个函数,SearchLinkTableNode函数在执行过程中,通过把具体任务传递给condition函数来让他查询目标,这里参数名更改为args间接使上层用户隐藏了对底层人员的信息泄露,其中condition函数的定义如下。可以看到,在函数体内,才会使用cmd这个参数,也就起到了封装信息的作用。

4.可重入函数和线程安全
上面有说到消费者重用规则,所以在多个线程使用同一函数时,可以会因为不同的访问顺序导致输出一个错误的答案。比如一个函数初始化一个a值为1,然后对它执行++操作。现在我们假设有这样一种调用顺序,甲线程先执行初始化操作,然后执行++操作。这个时候有一个乙线程剥夺资源然后执行++操作,然后就会得到一个错误的a值。在本案例中有相应的隐患也有对应解决代码。


引入Linux下的pthread线程头文件。这个DelLinkTableNode函数是实现在一个LinkTable中删除一个结点,首先判断此链表是否存在,存在的话分两种情况分别设置线程锁,然后执行相对应的操作。最后在执行完毕后将线程解锁,其他重入操作就可以执行了。可以看到,在此过程中,只有当某一个线程完全执行结束,下一个才可以执行。线程安全问题都是由全局变量及静态变量引起的。如上的pLinkTable.若每个线程中对全局变量、静态变量只有读操作而无写操作,一般来说,这个全局变量是线程安全的。
以上源代码来自项目案例https://github.com/mengning/menu
C语言项目——工程化编程的案例分析的更多相关文章
- 从C语言项目谈编程
很多初学C语言的小伙伴,在学习之初并没有一个大概的概念,学习这门语言需要掌握多少知识点,怎么才算学的差不多? C语言的精髓点在哪? 学到多少东西才能够达到做项目的标准?学习的时候需要注意哪些细节点?疑 ...
- QThread多线程编程经典案例分析
传统的图形界面应用程序都只有一个线程执行,并且一次执行一个操作.如果用户调用一个比较耗时的操作,就会冻结界面响应. 一个解决方法是按照事件处理的思路: 调用 Void QApplication::pr ...
- QThread多线程编程经典案例分析(三种方法,解释了为什么使用moveToThread的根本原因,即为了避免调用QThread::exec() )
传统的图形界面应用程序都只有一个线程执行,并且一次执行一个操作.如果用户调用一个比较耗时的操作,就会冻结界面响应. 一个解决方法是按照事件处理的思路: 调用 Void QApplication::pr ...
- 联想ERP项目实施案例分析(10):回到最初再反思IT价值
联想ERP项目实施案例分析(10):回到最初再反思IT价值 投入上千万(未来每年的维护费也非常高),投入一年实施时间,高级副总裁亲自挂帅,各级业务部门管理者亲自负责.骨干业务人员充当区域IT实施者/推 ...
- 一步步分析:C语言如何面向对象编程
这是道哥的第009篇原创 一.前言 在嵌入式开发中,C/C++语言是使用最普及的,在C++11版本之前,它们的语法是比较相似的,只不过C++提供了面向对象的编程方式. 虽然C++语言是从C语言发展而来 ...
- 32 Profiling Go Programs 分析go语言项目
Profiling Go Programs 分析go语言项目 24 June 2011 At Scala Days 2011, Robert Hundt presented a paper titl ...
- 17个C语言可以做的小案例项目
C语言是我们大多数人的编程入门语言,对其也再熟悉不过了,不过很多初学者在学习的过程中难免会出现迷茫,比如:不知道C语言可以开发哪些项目,可以应用在哪些实际的开发中……,这些迷茫也导致了我们在学习的过程 ...
- 数据分析06 /pandas高级操作相关案例:人口案例分析、2012美国大选献金项目数据分析
数据分析06 /pandas高级操作相关案例:人口案例分析.2012美国大选献金项目数据分析 目录 数据分析06 /pandas高级操作相关案例:人口案例分析.2012美国大选献金项目数据分析 1. ...
- 猴子吃桃问题之《C语言经典案例分析》
猴子吃桃问题之<C语言经典案例分析>一.[什么是猴子吃桃] 猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个.第二天早上又将第一天剩下的桃子吃掉一半 ...
随机推荐
- elk部署(实战一)
项目介绍: 系统:redhat7.6 软件:es+logstash+kibana 6.1 IP+主机名 192.168.0.10 elk1 192.168.0.10 elk2 192.1 ...
- uniapp请求方法的封装
之前在接触uniapp做小程序项目时候,因为不太熟悉,遇到了不少尴尬的时刻,请求方法的封装算是灵魂啊有木有,今天看到有人问题,就把我自己写的发出来让大家参考一下吧. 请求方法的封装我一般用的是prom ...
- Python爬虫练习(requests模块)
Python爬虫练习(requests模块) 关注公众号"轻松学编程"了解更多. 一.使用正则表达式解析页面和提取数据 1.爬取动态数据(js格式) 爬取http://fund.e ...
- 从ReentrantLock加锁解锁角度分析AQS
本文用于记录在学习AQS时,以ReentrantLock为切入点,深入源码分析ReentrantLock的加锁和解锁过程. 同步器AQS的主要使用方式是继承,子类通过继承同步器并实现它的抽象方法来管理 ...
- 一文搞懂后台高性能服务器设计的常见套路, BAT 高频面试系列
微信搜索「编程指北」,关注这个写干货的程序员,回复「资源」,即可获取后台开发学习路线和书籍 先赞后看,养成习惯~ 前言 金九银十,又是一年校招季. 经历过,才深知不易.最近,和作为校招面试官的同事聊了 ...
- ajax传值出现乱码问题
第一种:前台传值到后台,浏览器控制台打印正常,controller接收后成了乱码. 后台controller层加上两行转换代码 name=URLDecoder.decode(name,"ut ...
- 关于layui图片/文件上传
一:常规使用 普通文件上传 (传入服务器一张图片) 1.前台代码: <!DOCTYPE html><html><head> <meta charset=& ...
- 记一次使用idea插件CamelCase技巧
1.在idea中下载插件CamelCase插件 2.使用Shift+Alt+U快捷键进行转换 3.由于转换格式比较导致多次使用快捷键才能达到自己想要的效果,此插件提供了允许禁用某些转换或更改它们在首 ...
- linux之DNS服务
1.DNS (Domain Name Service 域名解析) DNS是因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网而不需要记忆能够直接被机器识别的IP. BI ...
- Django 笔记2018.2.7
1.基础知识 1.1web服务基本原理 1.2 WSGI 目前最通用的web接口规范,python默认支持,在Django中是一个库 1.3WEB基础知识 MTV (Model Template Vi ...