一、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. Scala-1-字符处理

    // s插值val s = s"a = $a, b = $b"val s = s"a = ${a*2}, b = ${b*3}" // 顶格 及 插值val s ...

  2. CSS中的position属性笔记

    一般有5个属性,分别是:static,absolute,relative,fixed,inherit static 自然定位:这个是默认值,没有定位,再设置top,rignt,bottom,left会 ...

  3. tcp syn-synack-ack 服务端接收ack

    TCP 服务端 接收到ack tcp_v4_rcv() -> tcp_v4_do_rcv() -> tcp_v4_hnd_req() + tcp_child_process()tcp_v4 ...

  4. shell编程之输入输出

    1.输入 read命令有以下几种常见形式: read  var  :等待用户输入,从标准输入中读取一行并赋值给变量var read : 标准输入读取一行,并赋值给内置变量REPLY read -a a ...

  5. modprobe: FATAL: Module ceph not found解决办法

    问题 有可能你在进行 Ceph 文件系统挂载的时候出现下面的提示: modprobe: FATAL: Module ceph not found. mount.ceph: modprobe faile ...

  6. java 关于 a==null 和 null==a, a.equals("123") 和“123”.equals(a)

    一: a==null 和 null==a 实验 所以 a==null 和 null==a 没区别 二: a.equals("123") 和"123".equal ...

  7. 02Java写一个hello world

    新建一个.text文件 输入并保存如下代码: public class HelloWorld{ public static void main(String[] args){ System.out.p ...

  8. Python_爬虫项目

    1.爬虫--智联招聘信息搜集    原文链接 1 #-*- coding: utf-8 -*- 2 import re 3 import csv 4 import requests 5 from tq ...

  9. [原题复现+审计][CISCN2019 华北赛区 Day1 Web2]ikun(逻辑漏洞、JWT伪造、python序列化)

    简介  原题复现:  考察知识点:逻辑漏洞.JWT伪造.python反序列化  线上平台:https://buuoj.cn(北京联合大学公开的CTF平台) 榆林学院内可使用信安协会内部的CTF训练平台 ...

  10. PHP弱类型漏洞学习

    简介 PHP在使用双等号(==)判断的时候,不会严格检验传入的变量类型,同时在执行过程中可以将变量自由地进行转换类型.由于弱数据类型的特点,在使用双等号和一些函数时,会造成一定的安全隐患 eg: &l ...