我在《C++程序设计技术》一书中曾说过:程序设计是一门艺术。既然是一门艺术,就要在程序设计的“历史长河”中不断思考、勇于探索、善于总结、潜心积累。正是在这一理念下,我在多年的程序设计生涯中或多或少留下了一些对软件开发技术人员有用的东西。
一本好书可以影响人的一生。我大学毕业前夕才见到现在几元钱都可以买到的计算器,见到计算机更是大学毕业以后的事了。在图书匮乏的1980年我有幸买到了一本日本学者马目洋一先生编写的《简明计算机入门》,虽然如饥似渴,但像看天书一般,它对我的打击是致命的。可以说当时很少有我看不懂的数学书,著名数学家华罗庚先生的《数论导引》我也阅读自如,而这种既“简明”又“入门”的天书却让我感叹:难怪计算机这么神秘!毕业三年后的1984年,谭浩强教授的《Basic语言》将我带入了程序设计大门,这本书以及善于思考、总结的理念使我受益终生。后来回忆起来很好笑,那本既“简明”又“入门”的天书只是对如何制造计算机硬件的泛泛而谈。1986年,武汉市在高校和企事业单位开展了一次全市程序设计编程比赛,当时在工厂工作的我有幸获得第一名,武汉市政府授予我“微机编程技术能手”称号,从此更激发了我探索程序设计艺术世界的兴趣。
我1988年开始专门从事软件开发工作。调到单位财务处第一天,处长就给了我一份产品销售表,要我进行利润分析。我工作了一天一夜,终于用当时很先进的DbaseIII完成了任务。领导非常满意,直夸计算机真神。可我却陷入了惶恐和沉思:要是领导再拿几份报表来,我不是又要度过几个不眠之夜!几天后,我到北京出差购买计算机设备,在火车上我思考着,能不能设计一个通用的制表系统,将表样的设计及数据计算方法的设计均交给用户去完成,我不就一劳永逸了么!说干就干,在回武汉的火车上方案已经基本形成,回到武汉我就开始着手实现。几番拼搏,智能制表系统的雏形终于完成。后来我去拜访武汉市一轻工业局的朋友才知道,他们一直在使用美国著名的制表软件LOUTS 1-2-3,据说其功能非常强大。我迫不及待地复制了一份回去研究。通过一番比较,发现我的系统毫不逊色并有过之。LOUTS存在的某些缺陷直到现在的Excel都没能很好地解决。例如,一份资产负债表作上下移动时其表头不见了,其实在Excel中根本就没有表头的概念。而作左右移动时,“资产”、“负债”列(我将其称为关键列)不能自动留在页面左边。虽然Excel中提供了单元格锁定功能的权宜之计来间接解决这些问题,显然其使用非常不方便,尤其对于多关键列。智能制表系统一切都是自动进行处理,具有人的智能判断能力,该软件1991年获得轻工部二等奖,在全国推广使用。
在开发制表软件时,需要将数据与表格线反复进行交叉连接,于是我设计、积累了一批重载函数strcat( ),实现数据的任意连接。为了将一个字符串s0赋给字符串s,再将高效实用Visual C++库函数设计前言s1, s2, …, s9依次连接到s的末尾,一般要使用下面的10行代码来实现: strcpy(s,s0);
strcat(s,s1);
strcat(s,s2);
strcat(s,s3);
strcat(s,s4);
strcat(s,s5);
strcat(s,s6);
strcat(s,s7);
strcat(s,s8);
strcat(s,s9);这多麻烦呀,如果能够写成下面的代码就省事了: strcpy(s,s0,s1,s2,s3,s4,s5,s6,s7,s8,s9);正是这种善于总结、潜心积累的思维理念,我积累了形成本书的诸多重要的实用函数。如今,虽然计算机技术日新月异地发展,软件设计方法和计算机语言也发生了翻天覆地的变化,但这些实用函数由于与操作系统的无关性和通用性,不需作任何修改即可以直接在新环境中继续使用。
在新的环境下,我又有了新的思考和新的积累。Visual C++以其强大的可视化功能赢得了新一代程序员的青睐,但和它的前辈一样,仍然存在着许多不足之处。例如,要播放一首音乐,程序员需要编写大量烦琐的代码,需要向音乐数字接口发送许多控制代码才能播放所需音乐。如果要显示一幅图片,其工作更会令人生畏,需要与内存句柄、设备场景等一系列深奥的概念打交道。现在有许多诸如“实用百例”、“精彩编程”等书籍介绍这些问题的处理方法。但这些书籍大多是以一个程序的方式来介绍,程序中需要在这个地方定义一个成员变量,那个地方定义一个成员函数等。弄得读者不知所云,我们不可能把这些书中的整个程序复制到自己的程序中去使用。于是我在思考,为何不能使用一个函数PlayMusic(file)就可以对磁盘中的文件file进行播放呢?!为何不能调用一个函数LoadImage(file)就可以对磁盘中的图片文件file进行显示呢?!那该多简单呀!只有这种高度集成、封装的函数才是程序员所需要和期望的。这些思考使得我形成了本书的另一些与语言环境相关的实用函数。
有句经典叫“够用就行”。设计程序更是如此,切忌贪大求洋,切忌追求时髦的概念。在一次本科论文答辩会上,某学生的论文题目是“个人通讯录设计与实现”。有个年轻老师问学生用的是什么数据库,学生回答使用的是Access。老师说,你应当使用更先进的Oracle数据库。我在心里直犯嘀咕:天哪,这不是用高射炮打蚊子吗?我看Access都用不着,你有多少个亲朋好友啊?!殊不知使用的工具越多、使用的环境越强大,对硬件、软件系统的要求就越高,系统的维护代价也就越大。这次答辩会激发我设计出了一组方便实用的文件数据存、取与管理函数以及一个供程序内部使用的小型数据库,使用它们不需要安装任何第三方工具。
开发软件时,许多问题的处理方法常常非常类似,需要进行一些相同的处理。例如,经常要将多个字符串连接成一个较长的串,需要从一个字符串中截取一个子串,需要对数据进行查找、分离、合并,因此经常需要重复编写某些代码。这样做至少存在几个方面的问题。首先,代码重复设计、重复调试,软件开发效率低。其次,由于重复编写相同或者类似的代码,需要重新测试、重新调试,在不同的软件或不同的模块中设计的代码可能不太一样,这样就会导致处理不一致,因此设计的系统稳定性差。为了提高代码的重用性,提高软件开发效率,提高系统稳定性,应当将一些通用的、具有共性的代码独立封装成类或者普通函数。
本书的研究成果正是我在长期的软件开发过程中逐渐积累而成的。书中介绍的函数和类方便、实用,可以降低程序员开发软件的难度,提高程序代码编写效率。书中既介绍了这些函数的使用方法,也介绍了这些函数的实现代码。因此,本书既是程序员设计程序的得力助手,也是读者学习程序设计技术的一本难得的参考书。本书中的代码用标准C++语言设计而成,在Visual C++6.0中调试通过。由于每个问题都以函数或类的形式来表现,读者可以很方便地根据其算法使用自己喜欢的语言来移植。
为了方便程序员使用本书的研究成果,我已经将这些函数和类封装形成了一个系统库。它由Func.lib、Func.h及其他一些辅助文件组成。程序员只需与Func.lib及Func.h打交道。系统库可在清华大学出版社(www.tup.com.cn)本书详细页面的网络资源处免费下载。
本书编写过程中,清华大学出版社给予了极大的关心和支持,在此表示由衷的感谢!北京大学的湛亚超对系统库中的部分函数算法提出了许多改进意见和建议,华中农业大学湛亚昆对书中所有例题进行了功能性测试和验证,在此一并表示感谢。
由于作者水平所限,书中错误在所难免,恳请读者提出宝贵意见,我将不胜感谢。Func.lib库将会不断修改、完善、扩充,读者需要新版本时也可以随时与我联系。
作者 湛为芳
2010年2月于华中农业大学