第17章 高级数据表示

第17章:高级数据表示

@(学C笔记)[2023-10-30am, C语言]

本章重点:
■ 函数:进一步学习malloc()
■ 使用C表示不同类型的数据
■ 新的算法,从概念上增强开发程序的能力
■ 抽象数据类型(ADT)

程序设计的关键:是表示数据的方式,程序开发最重要的部分是找到表示数据的好方法。找出正确的数据表示,不仅仅是选择一种数据类型,还要考虑进行哪些操作。也就是说,必须确定如何储存数据, 并且为数据类型定义有效的操作。

简言之,设计一种数据类型:如何储存该数据类型,及一系列管理该数据的函数。

算法:操控数据的方法;
抽象数据类型(ADT):面向问题不是面向语言。

1. 研究数据表示

■ 对于不是一种但又密切相关的一组数据,用结构来表示每一项合适。
■ 用动态内存分配来表示数据比较好。

2. 从数组到链表

建立首尾相连的结构:链表。(每个结构中包含指向next结构的指针)。

#define TSIZE 45  /* 储存片名的数组大小  */
struct film {
	char title[TSIZE];
	int rating;
	struct film * next;
};

虽然结构不能含有与本身类型相同的结构,但是可以含有执行同类型结构的指针。这种定义是定义链表的基础,链表中的每一项都包换着在何处能找到下一项的信息。

3. 抽象数据类型(ADT)

在编程时,应该根据编程问题匹配合适的数据类型,若不是C中与之匹配的基本类型,可设计一种符合程序要求的新数据类型。

什么是类型?类型特指两类信息:属性和操作好比int类型属性是整数值,对它的操作有加减乘除等。

假设要定义一个新的数据类型:首先,必须提供储存数据的方法。其次,必须提供操控数据的方法。

计算机科学领域已开发了一种定义新类型的好方法,用3个步骤完成从抽象到具体的过程。

  1. 提供类型属性和相关操作的抽象描述。这些描述既不能依赖特定的实现,也不能依赖特定的编程语言。这种正式的抽象描述被称为抽象数据类型(ADT)
  2. 开发一个实现ADT的编程接口。也就是说,指明如何储存数据和执行所需操作的函数。例如在C中,可以提供结构定义和操控该结构的函数原型。这些作用于用户定义类型的函数相当于作用于C基本类型的内置运算符。需要使用该新类型的程序员可以使用这个接口进行编程。
  3. 编写代码实现接口。这一步至关重要,但是使用该新类型的程序员无需了解具体的实现细节。
3.1 建立抽象

以电影项目为例:抽象类型叫链表(非正式但抽象的链表定义是:链表是一个能储存一系列项且可以对其进行所需操作的数据对象)。

简化链表的抽象数据类型(ADT):
类型名: 简单链表

类型属性: 可以储存一系列项

类型操作:
初始化链表为空
确定链表为空
确定链表已满
确定链表中的项数
在链表末尾添加项
遍历链表,处理链表中的项
清空链表

3.2 建立接口

程序清单 17.3 list.h接口头文件

/* list.h -- 简单链表类型的头文件 */
#ifndef LIST_H
#define LIST_H
#include <stdbool.h>   /* C99特性  */

/* 特定程序的声明 */
#define TSIZE		45	/* 储存电影名的数组大小 */
struct film
{
	char title[TSIZE];
	int rating;
};

/* 一般类型定义 */
typedef struct film Item;

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

typedef Node * List;

/* 函数原型 */

/* 操作:			初始化一个链表						*/
/* 前提条件:       plist指向一个链					*/
/* 后置条件:       链表初始化为空						*/
void InitializeList(List * plist);

/* 操作:     确定链表是否文空定义,plist指向一个已初始化的链表   */
/* 后置条件: 如果链表为空,该函数返回图热,否则返回false         */
bool ListIsEmpty(const List *plist);



#endif
3.3 使用接口

目标:使用这个接口编写程序,但是不必知道具体的实现细节。
例程伪代码方案:

创建一个list类型的变量。
创建一个Item类型的变量。
初始化链表为空。
当链表未满且有输入时:

把输入读取到Item类型变量中。
在链表末尾添加项。

访问链表中的每个项并显示它们。

程序清单17.4 films3.C程序

/* films3.c -- 使用抽象数据类型(ADT)风格的链表 */
/* 与list.c一起编译                           */
#include <stdio.h>
#include <stdlib.h>  /* 提供exit()的原型      */
#include "list.h"    /* 定义List、Item       */
void showmovies(Item item);
char * s_gets(char * st, int n);
int main(void
{
   List movies;
   Item temp;
   
   /* 初始化      */
   InitializeList(&movies);
   if (ListIsFull(&movies))
   {
     fprintf(stderr, "No memory available! Bye!\n");
     exit(1);
   }

   /* 获取用户输入并储存  */
   puts("Enter first movie title:");
   while (s_gets(temp.title, TSIZE) != NULL && temp.title[0] != '\0')
   {
      puts("Enter your rating <0-10>:";
      scanf("%d", &temp.rating);
      while (getchar() != '\n')
        continue;
      if (AddItem(temp, &movies) == false)
      {
         fprintf(stderr, "Problem allocating memory\n");
         break;
      }
      if (ListIsFull(&movies))
      {
          puts("The list is now full.");
          break;
      }
      puts("Enter next movie title (empty line to stop):");
    }

	/* 显示           */
	if (ListIsEmpty(&movies))
		printf("No data enterend.");
	else
	{
		printf("Here is the movie list:\n");
		Traverse(&movies, showmovies);
	}
	printf("You entered %d movies.\n", ListItemCount(&movies));
	
	/* 清理          */
	EmptyTheList(&movies);
	printf("Bye!\n");

	return 0;
}

3.4 实现接口
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cbc-shuchang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值