一、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

参考资料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

C语言项目——工程化编程的案例分析的更多相关文章

  1. 从C语言项目谈编程

    很多初学C语言的小伙伴,在学习之初并没有一个大概的概念,学习这门语言需要掌握多少知识点,怎么才算学的差不多? C语言的精髓点在哪? 学到多少东西才能够达到做项目的标准?学习的时候需要注意哪些细节点?疑 ...

  2. QThread多线程编程经典案例分析

    传统的图形界面应用程序都只有一个线程执行,并且一次执行一个操作.如果用户调用一个比较耗时的操作,就会冻结界面响应. 一个解决方法是按照事件处理的思路: 调用 Void QApplication::pr ...

  3. QThread多线程编程经典案例分析(三种方法,解释了为什么使用moveToThread的根本原因,即为了避免调用QThread::exec() )

    传统的图形界面应用程序都只有一个线程执行,并且一次执行一个操作.如果用户调用一个比较耗时的操作,就会冻结界面响应. 一个解决方法是按照事件处理的思路: 调用 Void QApplication::pr ...

  4. 联想ERP项目实施案例分析(10):回到最初再反思IT价值

    联想ERP项目实施案例分析(10):回到最初再反思IT价值 投入上千万(未来每年的维护费也非常高),投入一年实施时间,高级副总裁亲自挂帅,各级业务部门管理者亲自负责.骨干业务人员充当区域IT实施者/推 ...

  5. 一步步分析:C语言如何面向对象编程

    这是道哥的第009篇原创 一.前言 在嵌入式开发中,C/C++语言是使用最普及的,在C++11版本之前,它们的语法是比较相似的,只不过C++提供了面向对象的编程方式. 虽然C++语言是从C语言发展而来 ...

  6. 32 Profiling Go Programs 分析go语言项目

    Profiling Go Programs  分析go语言项目 24 June 2011 At Scala Days 2011, Robert Hundt presented a paper titl ...

  7. 17个C语言可以做的小案例项目

    C语言是我们大多数人的编程入门语言,对其也再熟悉不过了,不过很多初学者在学习的过程中难免会出现迷茫,比如:不知道C语言可以开发哪些项目,可以应用在哪些实际的开发中……,这些迷茫也导致了我们在学习的过程 ...

  8. 数据分析06 /pandas高级操作相关案例:人口案例分析、2012美国大选献金项目数据分析

    数据分析06 /pandas高级操作相关案例:人口案例分析.2012美国大选献金项目数据分析 目录 数据分析06 /pandas高级操作相关案例:人口案例分析.2012美国大选献金项目数据分析 1. ...

  9. 猴子吃桃问题之《C语言经典案例分析》

    猴子吃桃问题之<C语言经典案例分析>一.[什么是猴子吃桃]       猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个.第二天早上又将第一天剩下的桃子吃掉一半 ...

随机推荐

  1. modbus协议开关量采集模块

    modbus协议开关量采集模块是指的使用Modbus协议的进行信号的采集与控制的一种设备. Modbus 协议设备都具有唯一的 Modbus 地址,众山 DTU 默认 Modbus 地址为 100,用 ...

  2. python框架Django中MTV框架之VIew(业务控制器)

    MTV框架之VIew(业务控制器) 关注公众号"轻松学编程"了解更多. 1.什么是视图 视图层=路由表(urls.py)+视图函数(views.py) 其角色相当于MVC中的Con ...

  3. Raft算法原理剖析

    一.复制状态机(replicated state machine) Raft协议可以使得一个集群的服务器组成复制状态机,在详细了解Raft算法之前,我们先来了解一下什么是复制状态机.一个分布式的复制状 ...

  4. Spring Security 实战干货:OAuth2第三方授权初体验

    1. 前言 Spring Security实战干货系列 现在很多项目都有第三方登录或者第三方授权的需求,而最成熟的方案就是OAuth2.0授权协议.Spring Security也整合了OAuth2. ...

  5. 面向初学者的Python爬虫程序教程之动态网页抓取

    目的是对所有注释进行爬网. 下面列出了已爬网链接.如果您使用AJAX加载动态网页,则有两种方式对其进行爬网. 分别介绍了两种方法:(如果对代码有任何疑问,请提出改进建议)解析真实地址爬网示例是参考链接 ...

  6. Linux AWK工作原理

    本篇文章我们主要为大家介绍 AWK 是如何工作的. AWK 工作流程可分为三个部分:1.读输入文件之前执行的代码段(由BEGIN关键字标识).2.主循环执行输入文件的代码段.3. 读输入文件之后的代码 ...

  7. LOJ #6029. 「雅礼集训 2017 Day1」市场 线段树维护区间除法

    题目描述 从前有一个贸易市场,在一位执政官到来之前都是非常繁荣的,自从他来了之后,发布了一系列奇怪的政令,导致贸易市场的衰落. 有 \(n\) 个商贩,从\(0 \sim n - 1\) 编号,每个商 ...

  8. Why use MSIX message signal interrupt

    处理一个低版本内核中断向量表不够问题:__assign_irq_vector 关联irq 和 vector失败问题: (bug还没解决先记录一下吧) 同时先学习一下MSI-X:MSI, message ...

  9. 工具博客转载-ftrace

    https://linux.cn/article-9273-1.html https://lwn.net/Articles/365835/ Documentation/trace/events.txt ...

  10. binary hacks读数笔记(od命令)

    Linux od命令用于输出文件内容. od指令会读取所给予的文件的内容,并将其内容以八进制字码呈现出来 -t<输出格式>或--format=<输出格式> 设置输出格式. 实例 ...