一、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. Union-Find算法应用

    上篇文章很多读者对于 Union-Find 算法的应用表示很感兴趣,这篇文章就拿几道 LeetCode 题目来讲讲这个算法的巧妙用法. 首先,复习一下,Union-Find 算法解决的是图的动态连通性 ...

  2. 【Luogu】P6232 [eJOI2019]挂架 题解

    这道题跟CSP/S 2019 D1T1有点像. 我们先来模拟一下 \(n=4\) 的情况, 不难得出,最后的衣架挂钩顺序: 下标: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 ...

  3. numpy矩阵

    一.创建矩阵 Numpy提供了ndarray来进行矩阵的操作,在Numpy中 矩阵继承于NumPy中的二维数组对象,但矩阵区别于数组,不可共用数组的运算规律. 1.mat("第0行:第1行: ...

  4. PHP博客

    创建数据库 用户表 blog_user userid int 用户id username varchar(50) 用户名 password varchar(30) 密码 type tinyint(2) ...

  5. php执行exec、xsell_exec命令失败

    在php.ini下进行更改 查找disable_function 去掉exec xsell_exec 重启php

  6. Mongodb和Hbase的对比

    Mongodb和Hbase的对比 1.Mongodb bson文档型数据库,整个数据都存在磁盘中,hbase是列式数据库,集群部署时每个familycolumn保存在单独的hdfs文件中. 2.Mon ...

  7. nginx&http 第三章 ngx http ngx_http_process_request_line读取和处理HTTP头部的行

    在 ngx_http_wait_request_handler 的最后调用了 ngx_http_process_request_line 函数用来处理和解析这次请求的全文 在读事件被触发时,内核套接字 ...

  8. innodb为什么需要doublewrite(转)

    InnoDB的page size默认是16KB,而操作系统的一个block size是4KB,磁盘io block则更小.那么InnoDB的page刷到磁盘上要写4个操作系统block,在极端情况下( ...

  9. 不小心清空了Ceph的OSD的分区表如何恢复

    前言 如果你是新手,应该出现过敲盘符的时候,敲错的情况,有些操作可能没什么问题,查询类的操作都没问题,但是写入的情况,就可能比较麻烦了,当然老手也可能有误操作,本篇将讲述在误操作把分区表给弄丢了的情况 ...

  10. Jar 和 war 区别

    jar包:对于学习java的人来说应该并不陌生.我们也经常使用也一些jar包.其实jar包就是java的类进行编译生成的class文件就行打包的压缩包而已.里面就是一些class文件.当我们自己使用m ...