c语言vs2017链表出错,书上的代码 链表存储抽象数据类型,VS2017编译通过,输入一个项目后再输入第二个项目列表出错...

书上的代码 链表存储抽象数据类型,VS2017编译通过,输入一个项目后再输入第二个项目列表出错

[附件]1[/附件]

//list.c 实现函数文件

#include "stdafx.h"

#include

#include

#include"list.h"

//局部函数原型

static void CopyToNode(Item item, Node * pnode);

//接口函数

//把列表设置为空列表

void InitializeList(List * plist)

{

*plist = NULL;

}

//如果列表为空则返回真

bool ListIsEmpty(const List *plist)

{

if (*plist == NULL)

return true;

else

return false;

}

//如果列表已满则返回真

bool ListIsFull(const List * plist)

{

Node * pt;

bool full;

pt = (Node *)malloc(sizeof(Node));

if (pt == NULL)

full = true;

else

full = false;

free(pt);

return full;

}

//返回节点数

unsigned int ListItemCount(const List * plist)

{

unsigned int count = 0;

Node * pnode = *plist; //指向列表的开始

while (pnode != NULL)

{

++count;

pnode = pnode->next;//指向下一个节点

}

return count;

}

//创建存放项目的节点,并把它添加到由plist指向的列表尾部

bool AddItem(Item item, List * plist)

{

Node * pnew;

Node * scan = *plist;

pnew = (Node *)malloc(sizeof(Node));

if (pnew = NULL)

return false;//失败时推出函数

CopyToNode(item,pnew);

pnew->next = NULL;

if (scan == NULL)      //空列表,把pnew放在列表头部

* plist = pnew;

else

{

while (scan->next != NULL)

scan = scan->next;

scan->next = pnew;    //寻找尾节点,添加pnew指针

}

return true;

}

//访问每个节点并分别执行pfun指向的函数

void Traverse(const List * plist, void(*pfun)(Item item))

{

Node * pnode = *plist; // 设置到列表的开始处

while (pnode != NULL)

{

(*pfun)(pnode->item);  //把函数作用于列表中的项目

pnode = pnode->next;  //前进到下一项

}

}

//释放由malloc()分配的内存

//把列表指针设置为NULL

void EmptyTheList(List * plist)

{

Node * psave;

while (*plist != NULL)

{

psave = (*plist)->next; //保存下一节点的地址

free(*plist);      //释放当前节点

*plist = psave;    //前进到下一个节点

}

}

//局部函数定义

//把一个项目复制到一个节点中

static void CopyToNode(Item item, Node * pnode)

{

pnode->item = item;     //结构复制

}

// films3.cpp : 定义控制台应用程序的入口点。

//使用ADT风格的链表

//和list.c一同编译

#include "stdafx.h"

#include

#include

#include//提供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,"没有足够内存");

exit(1);

}

//收集并存储数据

puts("Enter first movie title: ");

while (s_gets(temp.title,TSIZE) != NULL && temp.title[0] != '\0')

{

puts("enter your tating<0-10>");

scanf("%d",&temp.rating);

while (getchar() != '\n')

continue;

if (AddItem(temp, &movies) == false)

{

fprintf(stderr,"内存出问题");

break;

}

if (ListIsFull(&movies))

{

puts("列表满");

break;

}

puts("enter next movie title (empty line to stop): ");

}

//显示

if (ListIsEmpty(&movies))

printf("无数据输入 \n");

else

{

printf("here is the movie list: \n");

Traverse(&movies,showmovies);

}

printf("you enterd %d  movies,\n",ListItemCount(&movies));

//清除

EmptyTheList(&movies);

printf("再见!\n");

return 0;

}

void showmovies(Item item)

{

printf("Movie:%s Rating: %d\n",item.title,item.rating);

}

char * s_gets(char * st, int n)

{

char * ret_val, *find;

ret_val = fgets(st, n, stdin);

if (ret_val)

{

find = strchr(st, '\n');

if (find)

*find = '\0';

else

while (getchar() != '\n')

continue;

}

return ret_val;

}

//list.h头文件

#pragma once

#ifndef LIST_H_

#define LIST_H_

#include  //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指向一个已初始化的列表

//如果该列表为空则返回true,否则返回false

bool ListIsEmpty(const List * plist);

//确定列表是否已满

//操作前:plist指向一个已初始化的列表

//操作后:如果该列表已满则返回true;否则返回false

bool ListIsFull(const List * plist);

//操作:确定列表中项目个数

//plist指向一个已初始化列表

//操作后:返回该列表中项目的个数

unsigned int ListItemCount(const List * plist);

//操作:在列表尾部添加一个项目

//操作前:item是要被增加到列表中的项目

//        plist指向一个已初始化的列表

//操作后:如果可能的话,在列表尾部添加一个新项目

//函数返回true,否则函数返回false

bool AddItem(Item item,List * plist);

//操作:把一个函数作用于列表中的每一个项目

//操作前:plist指向一个已初始化的列表

//       pfun指向一个函数,该函数接受一个

//Item参数并且无返回值

//操作后:pfun指向的函数被作用到列表中每个项目一次

void Traverse(const List * plist,void(* pfun)(Item item));

//释放已分配的内存(如果有)

//操作前:plist指向一个已初始化的列表

//操作后:为该列表分配的内存已被释放

//并且该列表被置为空列表

void EmptyTheList(List * plist);

#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值