为什么会有我们这个错误的实现方法呢?起源于开始我着手实现接口时候犹豫的那一瞬间,原本我是照着常规的方法写道:
--------------------------------------------
typedef struct TelPhone{
char Name[20];
char TelNumber[20];
}iTem;
typedef struct node{
iTem item;
node* next;
}Node;
-----------------------------------------
写到这里的时候,突然想到C++里面的class的派生和继承,于是就想不如弄个陷进在这里,看是否有人会跳,于是我又在下面加了这样的代码:
--------------------------------------
typedef struct list{
Node* head;
list *next;
int size;
}List;
-------------------------------------
当我敲下这段代码的时候,我就开始想,这种实现方师傅放在C里面有些麻烦了,他不同于C++的代码重用,所以想要实现接口确实不是那么一回事,当时我犹豫了下,要不要这样拿出来呢?如果大家C语言功底够厚,可能会容易看出来这是无法实现的,因为如果想要通过这种方式去实现List接口相当于实现了两个list,这是C里面及不容许,因为大家都知道资源的可贵。
既然这是一个陷阱,那么要怎么瞒天过海呢?这就是一个难题了。相信大家都被我贴的图给弄晕了,这好像看起来没问题,是啊,确实没问题,我们输入的两个联系人都能够正常显示,但是为什么我要告诉大家这是一个有问题的实现呢?问题到底出在哪里?实践才能检验真伪,相信到现在还没人反馈出来,多半是大家都只看却没真正的把代码敲在编译器里面运行看看。不管大家有没有验证,我觉得我还是有义务把正确的实现给放出来,否则不但不能授人以渔,反而还误人子弟。
其实这个实现主要考察的还是指针和数组的使用,很多人都说,C/C++的语法不多,但是确实最难学好的一门编程语言,通过这个综合实例,也可见一斑。
下面我们先看第一种实现,我们用数组的形式来实现,这是最简单的,但是功能不如用指针的方式。
---------------------------------------------
//my_list.h
#ifndef _MY_LIST_H_
#define _MY_LIST_H_
typedef struct TelPhone{
char Name[20];
char TelNumber[20];
}iTem;
typedef struct node{
iTem item;
node* next;
}Node;
#define MAXSIZE 100
typedef struct list{
iTem BookPhone[MAXSIZE];
int size;
}List;
void InitializeList (List *plist);
bool ListIsEmpty (const List * plist);
bool ListisFull (const List * plist);
unsigned int ListItemCount (const List * plist);
bool AddItem (iTem item, List * plist);
void ShowListItem(const List* plist);
void FreetheList (List * plist);
#endif
---------------------------------------------
接口没有变化,不同的是在我们声明新类型的时作了稍微的修改,所以实现起来变得很简单。如果大家没有看出差别,可以回头去看看我们那个有问题的声明方式。
-------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include "my_list.h"
//全局函数,把元素添加进列表
static void CopyToNode(Node * pNode,iTem item)
{
pNode->item = item;
}
//初始化
void InitializeList(List *plist)
{
plist->size = 0;
}
//确认列表是否为空
bool ListIsEmpty(const List* plist)
{
if(plist->size == 0)
return true;
return false;
}
//确认列表是否已满
bool ListisFull(const List* plist)
{
if(plist->size == MAXSIZE)
return true;
else
return false;
}
//返回元素个数
unsigned int ListItemCount(const List * plist)
{
return plist->size;
}
//添加元素,由于我们实现的是单向链表,所以使用从尾部添加
bool AddItem (iTem item, List * plist)
{
if(plist->size == MAXSIZE)
return false;
else
{
plist->BookPhone[plist->size++] = item;
return true;
}
}
//显示列表中的元素
void ShowListItem(const List* plist)
{
if(plist->size == 0)
printf("Not any data!!!");
else
{
for(int i=0;i<plist->size;i++)
printf("%-20s : %s\n",plist->BookPhone[i].Name,
plist->BookPhone[i].TelNumber);
}
}
//释放
void FreetheList (List * plist)
{
plist->size = 0;
}
-----------------------------------------------------
因为接口没有变化,所以我们的驱动函数不需要更改就可以直接运行,是不是觉得很方便呢?不过这个List的缺陷却因为他是数组的原因,所以使得他不能够收放自如,当然,要想让他能够收放自如我们可以使用指针的方式。接口还是这个接口,不过实现方式却大不一样,这个数组的方式比起来,难了不少,我们明天再说。
=============
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。