• 从函数指针数组的运用来看程序结构化设计(2)


    一、基础研究

    观察这两个程序:

    Menu.h

     

    Ues.c

     

    程序执行的结果是在屏幕上显示一个三行的菜单:

     

    用户按键选择菜单的某一项可以在屏幕上显示该项所表示的彩色字符串:

     

    它是如何实现的呢?我们先来看看menu.h。程序构造了一个结构体,并将菜单的相关信息都放在结构体里。这里有个问题:我们之前定义结构体都是用struct 类型名,但是这里是用typedef struct,这里是给struct的结构体起了一个名字为后面的ItemType,如果是struct加类型名则结构体的名字是struct后面跟的类型名,即typedef struct{}a;等价于struct a{};。

    之后对函数menu进行了定义和声明,我们看到这里是在声明之后直接定义的,那么能不能去掉声明呢?在文件中去掉声明后发现完全能够正常运行。在函数menu里实现了显示菜单项和检测用户按键、根据按键调用相关函数的功能,menu函数的参数为一个结构体指针,这个指针指向用户初始化的菜单信息结构体,还有整型变量n表示所要实现菜单选项的个数,n主要是用来控制循环的次数的。在显示菜单项的功能里,用strlen来获得菜单项字符串的长度并进行判断,如果字符串的长度超过字符数组的长度,则提示错误并返回。

    use.c里比较特别的是它在输出字符串时让每一个字符顺序地变换颜色,是在for(n=0;str[n];n++)scr[n]=str[n]+(n+1)*0x100;里实现的,每个字符的值都会加0x100,因为我们知道屏幕上每个字符都是两个字节显示的,低字节存放要显示的字符的ascall,高字节存放的是表示颜色等属性的值,这里每个字符的值加0x100,相当于高位的属性值加1,所以会变换一种颜色。

    弄明白整个程序后,我们发现在头文件menu.h里定义了程序要使用的数据类型,定义了程序的入口函数menu,在menu里实现了程序扩展所不需要改的功能,给出了跳转到具体函数的方法,然后具体的初始化和子函数功能的实现则在use.c里实现。也就是说,头文件里实现的是程序的共性,c文件里实现的是程序的个性。我们在头文件里定义的数据要能够连接头文件和c文件,这样使用起来便于扩展和修改,如果我们要修改一个功能,只需要在use.c文件里更改初始化的值或实现的函数内容就行了。那么对于程序a.c的功能,我们要把抽象的数据和通用的函数封装起来,再集中初始化和调用。

    将程序a.c修改如下:

    h文件为:

     

    c文件为:

     

    这样我们将输入、输出、判断放在h文件里,将子函数功能的实现和函数指针数组的初始化放在main函数里,这样我们要添加新功能可以在main函数里修改就行了。

    二、扩展研究

    (1)Strlensizeof的区别。

    答:(1strlen是函数,sizeof是运算符。

    (2)sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以''''结尾的。

    (3)大部分编译程序在编译的时候就把sizeof计算过了

    (4)strlen的结果要在运行的时候才能计算出来,时用来计算字符串的长度,不是类型占内存的大小。

    三、研究总结

    我们在设计程序时要弄清楚哪些是共性、哪些是个性,把共性放在头文件里,把个性放在c文件里,这样可以做到简洁清晰易扩展。所以我们能够在main函数里写子函数实现功能的扩展。

    要掌握一门语言,必须先掌握它的思想。c语言作为一门比较底层的语言,它的思想与计算机底层原理息息相关,但是这里的分文件实现程序逐渐的接近了高级语言的思想,应该说高级语言的思想就是从中衍生出来的,我们要不断比较、思考,才能真正掌握c语言的思想。

  • 相关阅读:
    Kubernetes Python Client 初体验之安装授权
    用Ubuntu和树莓派系统部署kubernetes集群后的一些心得
    OpenWrt下基于OLSR的Ad-Hoc组网实现网络摄像头多节点访问
    KVM初体验之virt-manager unable to connect to libvirt的处理办法
    oracle参数和日志文件
    trigger
    package
    function
    procedure
    oracle异常处理
  • 原文地址:https://www.cnblogs.com/stormpeach/p/4363996.html
Copyright © 2020-2023  润新知