多分支选择结构程序设计的思想与实现方法
周立功教授数年之心血之作《程序设计与数据结构》以及《面向AMetal框架与接口的编程(上)》。书本内容公开后,在电子行业掀起一片学习热潮。经周立功教授授权,本公众号特对《程序设计与数据结构》一书内容进行连载,愿共勉之。
第二章为程序设计技术,本文为2.2.5 结构体数组。
>>> 2.2.5 结构体数组
下面将以控制台菜单选项为例,介绍多分支选择结构程序设计的思想与实现方法。一般来说,菜单栏至少包括新建文件、打开文件、保存文件和退出4项基本功能。比如:
如果使用函数指针,这4个函数的调用形式如下:
而新建文件、打开文件、保存文件和退出都可以作为字符串"新建文件"、"打开文件"、"保存文件"和"退出"存储在char数组中。比如:
基于此,可以先声明一个结构体类型CmdEntry,其声明如下:
接着定义一个结构体数组作为函数表,分别用于存储菜单函数的入口地址和菜单信息。其声明如下:
在这里,将cmdArray声明为一个内含10个元素的数组,数组的每个元素都是一个CmdEntry类型的数组,因此cmdArray[0]是第一个CmdEntry类型的结构体变量,cmdArray[1]是第2个CmdEntry类型的结构体变量,以此类推。cmyArray是数组名,该数组中的每个元素都是CmdEntry类型的结构体变量。
为了标识结构体数组中的成员,可以采用访问单独结构体的规则:在结构体名后面加一个点运算符,再在点运算符后面加上成员名。比如:
注意,数组下标紧跟在cmyArray后面,不是成员名后面。比如:
使用cmdArray[2].cHelp的原因是:cmdArray[2]是结构体变量名,正如cmdArray[1]是一个结构体变量名。使用cmdArray[3].cHelp的原因是cmdArray[3]是结构体变量名,如同cmdArray[0]是另一个变量名。由于数组变量名代表数组首元素的地址,因此下面两个语句是等价的:
那么*pCmdEntry=cmdArray[0],因为&和*是一对逆运算符,所以可以做以下替换:
由于.运算符比*运算符的优先级高,因此必须使用圆括号。顺带提一下,下面的表达式代表什么?
这是cmdArray数组第1个结构体变量(cmdArray[0]部分)中的第2个字符(cHelp[1]部分),这个字符为"建"。这个示例指出,点运算符右侧的下标作用于各个成员,点运算符左侧的下标作用于结构体数组。最后总结一下:
根据上面的定义,即可用以下方式获得相应函数的入口地址。比如:
即pfuncmd函数指针指向CreateFile()函数,其调用形式如下:
由此可见,采用回调函数动态绑定的方式,程序的可扩展性得到了很大的提升。只需在"<标注>1"处添加自定义的函数,无需多处修改代码,不仅可以很好地解决程序的可扩展性问题,而且还大大地降低程序的出错几率,详见程序清单2.26。
程序清单2.26 控制台菜单选项程序
请用bubbleSort()算法完成这个练习,将employeeArray结构体数组分别按下列要求排序并输出:(1)按id从小到大排序;(2)按weight、age、height从小到大排序,相同时按id从小到大排序;(3)bloodType按A、B、O、AB顺序排序,相同时按id从小到大排序。