看着代码,就要开始思考实现了。如果是C++来实现的话,现在我就开始构造链表类,来思考其成员函数和成员变量了,是否需要构造函数,要什么样形式的,有多少成员函数,有多少是public的,是否有继承体系等等。但是现在我们是用C来实现的。那就考虑C的特性吧。

C是没有类的概念的,因此其所有的应该就是变量和函数,如果我们仅仅是编写用来自己使用的链表程序,我们可以定义一个全局的变量,然后用函数来操作这个变量。不过这些函数就无法给其他调用者来使用,如果要给其他调用者使用,我们必须将链表本身作为函数的参数来进行传入,而在调用者处定义好链表。
      不过,这样是最优美的实现吗?此时,如果是你来做。你会怎么思考?

之后就是考虑其特性的时候,我们需要实现链表的多少特性?
      这里暂时准备实现1.添加   2.删除   3.遍历 4.倒序   5.两个链表合并 6. 查找特定节点,如果还有一些比较重要的,可以随时进行添加。

这里稍微讲一下C的命名规则,C的规则每个公司都有其自己的规定,但是要求基本基于两点,一是清晰,二是尽量的简短。
      清晰大家当然比较明了,可以增加代码的可读性,那简短是为什么呢?按照我的理解,是延续了大型机时代的一种习惯,当时屏幕的分辨率可是很低,800*600也是很牛B的。然后编程也需要远程到solaris等UNIX或类UNIX系统上来做,其登陆的标准终端一般是80个字符长,这样就需要我们的函数名字比较简短,不要换行或者拖动就在一个界面上完全显示出函数的调用。
      这比DOS时代对内存的锱铢必较好太多了,但是也还是挺吝啬的啦,所以才有point被缩成pt,size变成sz这样的命名,rectangle这样十恶不赦的名字,是绝对绝对不能存在的,如果你仔细阅读过一些C或者C++的代码的话,应该会有这样的感觉。
      当然,这里命名就不一定要遵守这样的规则了,如果你在公司中,那就请遵守各个公司的命名规则手册吧。

然后就是考虑,我怎么定义这些函数。函数包括函数名,参数和返回值这三个要素。对于函数名,我们只需要对应取一个有意义的名字就可以了。由于是使用C语言,所以我们甚至不必考虑访问限制,虚函数等C++范畴的东西。那就是考虑对实现该函数的功能,我们需要怎样的参数和返回值。而更进一步的思考就是,我们怎么设置参数和返回值,来提高效率,或者接口更加明确清晰。当然,其实在工程中,到这一步来考虑上面的问题,就是你们公司的流程问题了,这些应该也是设计中的问题,而不是实现中的问题。很多人都在思考设计怎么做,这就是设计,当然,这个是属于详细设计了。但是,没有经历详细设计,就直接做概要设计的家伙,能够被信任吗?能够做出好的系统吗?反正我挺怀疑的。当然,有老板用他,那是他的本事了。而能够思考到这一步,我想,你应该就是一位合格的程序员了。

当然,真正的设计没有这么简单,真正的设计也不是由你来定,大型的系统都有架构师,我们的设计还没有到那层。至于模块的设计,也不是你的一言堂。你需要和调用你这个函数的哥们们商量,hi,我这么写,你觉得怎么样?还是你有些什么特殊的要求。大家坐下来讨论一下。如果你的函数被很多人调用,那就需要考虑到所有调用者的需求,来处理所有的情况了。复杂性就是这么一步一步被加高的。

而软件的扩展性也在于这里,如果我一开始的思路定好了,而且适合现在的要求,并且实现了,现在出现一个新的需求,一个新的调用,居然我现在的参数不能满足他,(你说,他出来捣啥乱啊,本来就够乱的了)。那我就需要修改接口,同时通知所有相关模块,不好意思啊,兄弟,我也不想的,不过没办法,大家这么这么改,这么这么调用。所以,如果你看到维护了10年20年的代码,感觉片断很好看,但是再去更上一层看,就感觉很乱,不要感觉奇怪,这是妥协的结果。

对于添加一个节点,那我就需要考虑其参数应该是一个新的节点,这里有几种选择,我可以只输入一个节点中存储数据的值,而在函数内部进行内存分配,创建新节点的工作,这样一来,我就考虑到是不是需要增加一个创建新节点的函数呢?另外一种选择是,我传入的就是一个新的节点的地址,那函数内部所需要做的就是将其链入链表即可。那这里就又有问题了,我是链入到链表的什么地方呢?是链入到头部,尾部,还是我指定的地方呢?如果我需要指定位置的话,那就需要我增加一个参数来做。
      而对于这个参数,我就要确定,链表是从0开始计数,还是从1开始计数呢,这就相差1个了呀,所以就要有一个约定。而这个约定,如果没有注释,同时在文档中没有体现出来的话,在以后维护代码的时候,就会有些麻烦,而这样的约定多了,代码也就成了天书,没有人愿意去看。
      然后需要对于参数进行一些必要的判断,也就是确定是否传入的值是有效的,可以使用assert宏等手段(这里不清楚assert宏是windows自身的,还是C库中的,请自己挑选使用,当然后面我会在程序中一一实现,但是现在也不去慢慢验证)。
      接下来是返回值,是不返回,还是返回错误码,还是做什么具体的操作。当这些思考好了,差不多这个函数的实现也了然了。当然,这里还是比较简单的情况,复杂的还有与其他函数的交互,调用其他函数或者被其他函数调用的话,又更复杂一些,如果牵涉到一些全局变量,那又更复杂一些。另外,如果又有定时器或者回调的话,又多了一些其他考虑的事情。当你基于这个系统考虑得越多,越周全,那你对这个函数的实现就越有把握。同时也更能保证函数实现的健壮性。毕竟,没有人愿意写一堆烂代码出来。不过,大家都是这么走过来的,呵呵,不愿意写烂代码,怎么能知道问题所在,将其变为好代码呢。

每一个需要实现的函数都需要经过这样的思考,然后如果有多种选择的话,选择一个自己比较钟爱的(当然,要通过调用者那一关,不过,这里调用者和实现者都是我自己,那就随便选择了)。最后确定好各个参数和返回值。

这是我觉得在实现前需要经历的思考步骤,你觉得呢?如果是你来实现的话,你会怎么做呢?

转载于:https://www.cnblogs.com/cnyao/archive/2009/10/08/linkedlist4.html

穷究链表(四)--链表实现前的思考相关推荐

  1. SDUT OJ 数据结构实验之链表四:有序链表的归并

    数据结构实验之链表四:有序链表的归并 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem Desc ...

  2. SDUT_2119 数据结构实验之链表四:有序链表的归并

    点击打开链接 数据结构实验之链表四:有序链表的归并 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem ...

  3. Windows进程与线程学习笔记(四)—— 等待链表调度链表

    Windows进程与线程学习笔记(四)-- 等待链表&调度链表 要点回顾 33个链表 等待链表 实验:分析等待链表中的线程所属的进程 第一步:查看所属线程结构体: 第二步:查看所属进程结构体 ...

  4. c++ 链表_链表(单向链表的建立、删除、插入、打印)

    线性结构:有且只有一个根节点,且每个节点最多有一个直接前驱和一个直接后继的非空数据结构 非线性结构:不满足线性结构的数据结构 链表(单向链表的建立.删除.插入.打印) 1.链表一般分为: 单向链表 双 ...

  5. LeetCode-21.合并两个有序链表(链表+递归)

    题目内容 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/merge-two-sorted-lists/ 将两个升序链表合并为一个新的 升序 链 ...

  6. 【数据结构-链表】链表的相关算法

    文章目录 1 删除元素 1.1 删除值为 x 的所有结点 1.1.1 不带头结点的单链表 1.1.2 带头结点的单链表 1.2 删除重复元素 1.2.1 不带头结点的单链有序表 1.2.2 带头结点的 ...

  7. 链表的各种操作实现 链表逆序 链表排序 有序链表归并 链表存在环的判定

    链表的各种操作实现 链表逆序 链表排序 有序链表归并 链表存在环的判定 链表基本操作实现 c语言版本, 该程序在visual c++ 6.0上调试通过! 本人写该程序完全是为学习交流之用,还望大家多多 ...

  8. 数据结构与算法笔记(三)—— 链表(单链表、循环链表、双向链表)

    一.前沿 1.1.为什么需要链表 顺序表的构建需要预先知道数据大小来申请连续的存储空间,而在进行扩充时又需要进行数据的搬迁,所以使用起来并不是很灵活. 链表结构可以充分利用计算机内存空间,实现灵活的内 ...

  9. 数据结构-链表-环形链表

    数据结构-链表-环形链表 环形链表就是将单链表的尾部指向头部,从而形成一个单方向的环形结构,环形链表中每个元素都可以是head,也都可以是尾部,这样就不用担心链表头指针遗失的问题,而且在遍历链表的时候 ...

  10. 已有a,b两个链表,每个链表中的结点包括学号、成绩。要求把两个链表合并,按学号 升序排序

    /*已有a,b两个链表,每个链表中的结点包括学号.成绩.要求把两个链表合并,按学号 升序排序*/#include <stdio.h> #include <stdlib.h> t ...

最新文章

  1. 从Android界面开发谈起(转)
  2. S1 Python 基础
  3. python进程监控及恢复
  4. git merge 的撤销
  5. 关于mqtt+js前端中mqtt服务器关闭重连服务器后js前端接收不到消息的问题
  6. 41. 后台模块开发(6)
  7. 云网融合个人浅析(一)
  8. 今日分享:js制作一个简单的新年倒计时
  9. 全国各地所有高校名单数据库 全国所有高校排名
  10. 基于jsp+java+ssm的大学生缴费系统
  11. HotPower超级CRC计算器与第三方CRC计算器名词解释与对照及操作
  12. 什么是UserAgent
  13. 数据分析-思维分析逻辑day05
  14. iOS视频开发(二):视频H264硬编码
  15. python pyqt5 股票分时_pythonpyqt5股票分时:股票风险与提示_XAC配资之家
  16. 【例题 8-4 UVA - 11134】Fabled Rooks
  17. 【高等数学】通过俩条空间直线求得公垂线的求法
  18. java多线程JUC学习笔记
  19. 提取文档中关键词所在行
  20. 微信api调用限制:45009 reach max api daily quota limit

热门文章

  1. JAVA Map集合类简介
  2. AC自动机-算法详解
  3. 层次选择器[selector_2.html]
  4. Cobbler结合windows DHCP服务器的使用
  5. hadoop包含哪些技术?
  6. 服务器存储技术千人群为:39472354
  7. 数据库索引 类型 (转载)
  8. 将现有企业级模板项目从 Visual Studio .NET 2003 迁移到 Visual Studio 2005
  9. [翻译]Real-Time Correlative Scan Matching
  10. 基于微服务架构的门户平台改造的研究