• C语言ADT(抽象数据类型编程) (含Demo演示文件)



    C语言是一种计算机程序设计语言。它既具有高级语言的特点,又具有汇编语言的特点。它可以作为工作系统设计语言,编写系统应用程序,也可以作为应用程序设计语言,编写不依赖计算机硬件的应用程序。因此,它的应用范围广泛,不仅仅是在软件开发上,而且各类科研都需要用到C语言,具体应用比如单片机以及嵌入式系统开发。(摘自“百度百科”)

    在嵌入式系统开发中,随着系统功能要求越来越多,除了硬件系统不断扩展外,芯片中软件设计的规模也越来大,算法越来越复杂,所以需要对程序结构进行良好设计,方便后来的修改和维护。

    下面是对ADT的一些简单介绍:

     

    1.2.1 ADT定义及主要特点:

         为类型的属性和可对类型执行的操作提供一个抽象的描述。不受特定的实现和编程语言的约束。这种正式的抽象描述被称为抽象数据类型(Abstract Data TypeADT)。

         抽象数据类型概念的引入,降低了大型软件设计的复杂性;提高了系统的可读性与可维护性;使系统的各部分相对隔离,在一定程序上解决了软件的可靠性、生产率等方面的问题。     

    1.2.2定义步骤:

       1、定义一个数据类型。提供存储数据的方式,提供操作数据的方式。

       2、开发一个实现该ADT的编程接口。即说明如何存储数据,并描述用于执行所需操作的函数集合。例如,提供一个结构体类型的定义,同时提供用来操作该结构体的函数的原型。

       3、编写代码实现这个接口。 

    1.2.3抽象数据类型优点:

    程序便于维护,灵活应对需求的变更;如果有些功能运行不正常,可以将问题集中到一个函数上;如果想用更好的办法来完成一个任务,比如添加项目,则只需重新编写那一个函数;如果需要增加新的属性或操作,则修改抽象类型即可。        

     

    上面的都是在本科阶段学习C++里面的一讲《抽象数据类型》里面的内容。当时教学时是先讲C++基本的语法规则,再讲类。C++基本的语法规则和C语言基本类似,所以在讲C++“面向对象”最重要的特点――类之前,用“抽象数据类型”进行了一次过渡。C++目前基本上没有用过,类也用得不深入,但是“抽象数据类型”的思想却留下来了,这样使得自己对大规模的C语言程序设计的基本模式有了比较好的基础和概念了。

    下面是结合ADT程序设计模式的例子进行介绍:


    查看工作区,里面包含三个文件:

    list.h:数据的定义和声明,接口函数的声明

    list.cpp:接口函数的实现

    cw0901d.cpp:用于引用和测试代码块

    list.h”文件内容如下:

    list.h
    //////////////////////////////////////////////////////////////////////////
    //版权声明:此代码文件版权属于武汉大学,仅用作学习和交流
    //////////////////////////////////////////////////////////////////////////

    /*
        列表抽象数据类型的头文件    
    */
    #ifndef _LIST_H_
    #define _LIST_H_

    ////////////////////////////////////////////////////////////////////////////////
    //特定于程序的声明
    //
    const int TITLESIZE=51//存放片名的数组长度

    struct MyFilm
    {
        
    char title[TITLESIZE];
        
    int rating;
    };


    ////////////////////////////////////////////////////////////////////////////////
    //一般类型定义
    //
    typedef MyFilm Item;

    struct Node
    {
        Item item;
        Node 
    *next;
    };

    typedef Node 
    * List;

    ////////////////////////////////////////////////////////////////////////////////
    //函数原型
    //
    //操  作:初始化一个列表
    //操作前:list引用一个列表
    //操作后:该列表为初始化为空列表
    void InitializeList(List &list);

    //操  作:确定列表是否为空列表
    //操作前:list引用一个已初始化的列表
    //操作后:如果该列表为空则返回true,否则返回false
    bool ListIsEmpty(const List &list);

    //操  作:确定列表是否已满
    //操作前:list引用一个已初始化的列表
    //操作后:如果该列表已满则返回true,否则返回false
    bool ListIsFull(const List &list);

    //操  作:确定列表中项目的个数
    //操作前:list引用一个已初始化的列表
    //操作后:返回列表中项目的个数
    unsigned int ListItemCount(const List &list);

    //操  作:在列表的尾部添加一个项目
    //操作前:item是要被添加到列表的项目
    //        list引用一个已初始化的列表
    //操作后:如果可能的话,在列表的尾部添加一个新项目,
    //        成功则返回true,否则返回false
    bool AppendItem(Item item, List &list);

    //操  作:把一个函数作用于列表中的每个项目
    //操作前:list引用一个已初始化的列表
    //        pFun指向一个函数,该函数接受一个Item引用参数,
    //        并且无返回值
    //操作后:pFun指向的函数被作用到列表中的每一个项目一次
    void Traverse(const List &list, void (*pFun)(Item &item));

    //操  作:释放已分配的内存
    //操作前:list引用一个已初始化的列表
    //操作后:为该列表分配的内存已被释放,
    //        且该列表被置为空列表
    void EmptyList(List &list);

    #endif

     list.cpp”文件内容如下:

    list.cpp
    //////////////////////////////////////////////////////////////////////////
    //版权声明:此代码文件版权属于武汉大学,仅用作学习和交流
    //////////////////////////////////////////////////////////////////////////

    /*
        列表抽象数据类型的实现
    */
    #include 
    <iostream.h>
    #include 
    "list.h"

    //把Item项目拷贝到列表的一个Node节点的item中
    static void CopyToNode(const Item &item, Node &node);

    void InitializeList(List &list)
    {
        list 
    = NULL;
    }

    bool ListIsEmpty(const List &list)
    {
        
    if (list==NULL)
            
    return true;
        
    else
            
    return false;
    }

    bool ListIsFull(const List &list)
    {
        Node 
    *pNode = new Node;

        
    if (pNode==NULL)
            
    return true;
        
    else
        {
            delete pNode;
            
    return false;
        }
    }

    unsigned 
    int ListItemCount(const List &list)
    {
        unsigned 
    int count=0;
        Node 
    *pNode = list;

        
    while (pNode != NULL)
        {
            count
    ++;
            pNode 
    = pNode->next;
        }

        
    return count;
    }

    bool AppendItem(Item item, List &list)
    {
        Node 
    *pNewNode, *pNode=list;

        pNewNode 
    = new Node;
        
    if (pNewNode == NULL)
            
    return false;

        CopyToNode(item, 
    *pNewNode);
        pNewNode
    ->next = NULL;

        
    if (pNode == NULL)
            list 
    = pNewNode;
        
    else
        {
            
    while (pNode->next != NULL)
                pNode 
    = pNode->next;
            
            pNode
    ->next = pNewNode;
        }

        
    return true;
    }

    void Traverse(const List &list, void (*pFun)(Item &item))
    {
        Node 
    *pNode = list;

        
    while (pNode != NULL)
        {
            pFun(pNode
    ->item);
            pNode 
    = pNode->next;
        }
    }

    void EmptyList(List &list)
    {
        Node 
    *pNode = list, *pTemp;

        
    while (pNode != NULL)
        {
            pTemp 
    = pNode;
            pNode 
    = pNode->next;

            delete pTemp;
        }
    }

    static void CopyToNode(const Item &item, Node &node)
    {
        node.item 
    = item; //结构体直接赋值实现拷贝
    }

      cw0901d.cpp”文件内容如下: 

    cw0901d.cpp
    //////////////////////////////////////////////////////////////////////////
    //版权声明:此代码文件版权属于武汉大学,仅用作学习和交流
    //////////////////////////////////////////////////////////////////////////

    /*
        用定义的抽象数据类型——列表(List)——保存电影列表
    */
    #include 
    <iostream.h>
    #include 
    <iomanip.h>
    #include 
    <stdlib.h>
    #include 
    "list.h"

    void ShowFilm(Item &item); //显示列表项目的函数

    void main()
    {
        List filmList;
        Item film;

        
    //初始化列表
        InitializeList(filmList);
        
    if (ListIsFull(filmList))
        {
            cout
    <<"错误:内存不足!"<<endl;
            exit(
    1);
        }

        
    //读取数据,创建列表
        cout<<"请输入第一个电影的片名:"<<endl;
        cin.getline(film.title, TITLESIZE);
        
    while (film.title[0]!='\0')
        {
            cout
    <<"请输入你的评价等级(0~9):"<<endl;
            cin
    >>film.rating;
            cin.
    get();

            
    if (!AppendItem(film, filmList))
            {
                cout
    <<"错误:分配内存错误!"<<endl;
                
    break;
            }

            
    if (ListIsFull(filmList))
            {
                cout
    <<"错误:列表已满!"<<endl;
                
    break;
            }

            cout
    <<"请输入下一个电影的片名:"<<endl;
            cin.getline(film.title, TITLESIZE);
        }

        
    //输出列表
        if (ListIsEmpty(filmList))
        {
            cout
    <<"你没有输入有效的数据!"<<endl;
        }
        
    else
        {
            cout
    <<"下面是你输入的电影列表:"<<endl;
            Traverse(filmList, ShowFilm);
        }

        cout
    <<"你一共输入了"<<ListItemCount(filmList)<<"部电影。"<<endl;

        
    //清除
        EmptyList(filmList);

        cout
    <<"\nBye!"<<endl;
    }

    void ShowFilm(Item &film)
    {
        cout
    <<setw(TITLESIZE+1)<<setiosflags(ios::left)
            
    <<film.title<<film.rating<<endl;
    }

        在“list.h”中定义一种数据类型,这种数据类型一般是适用于你要解决的实际问题的一种结构体,并在此文件中为这种抽象数据类型定义必要的方法,这些方法都在对应的“list.cpp”中进行实现,于是“list.h”和“list.cpp”就形成了一个功能模块,这就是用C语言的语法规则初步实现C++的对象“类”的思想。

    实现模块化的引用的具体注意事项是:

    1.       list.h中定义抽象数据并声明接口函数(将代码块定义在一个条件编译#ifndef……#define……#endif中可防止头文件被重复包含)

    2.       list.cpp文件的开头包含list.h并实现接口函数)

    3.       在测试文件cw0901d.cpp文件的开头包含list.h头文件(编译器会自动根据头文件去连接具体的.cpp具体代码实现的文件)

     

    实现上述的三个步骤后,cw0901d.cpp中就能直接对list.h中的数据和方法进行引用了,用户不用再关心那些方法的具体实现,只需要知道这些函数访求的功能即可。这样做的好处不言而喻:一方面使得程序模块化,结构更加清晰,另外一方面使得程序的可扩展性的可修改性变强,更加方便维护。

     

    后记:对于高级的面向对象的语言来说,本文肯定是多此一举了,因为C++,C#的“类”完全比ADT要好用,但是对于C语言这种面向过程的语言来说,ADT无疑是将C++高级语言的编程思想在C语言中的一次很有意义的应用,使得大规模的嵌入式系统的C语言程序设计变得更加容易了。本文仅是简单的整理和讲解,具体过程其实可以直接套用附件模板。

     附件模板:ADT.rar  用VC6.0打开。(注,此文件版权属于武汉大学,仅供学习使用)

  • 相关阅读:
    java之扩展运算符
    error LNK2005: _DllMain@12 已经在 dllmain.obj 中定义
    MinGW
    Gcc/MinGW/Cygwin/Msys 分别是什么?
    开源项目:windows下使用MinGW+msys编译ffmpeg
    MinGW安装和使用基础教程
    基于UDP高性能传输协议UDT doc翻译(一)
    基于UDT connect连接通信以及文件传输--客户端
    基于UDT connect连接通信以及文件传输--服务端
    FreeSWITCH第三方库(其他)的简单介绍(三)
  • 原文地址:https://www.cnblogs.com/beer/p/1770975.html
Copyright © 2020-2023  润新知