C_Primer_Plus_Chapter17_exercise2

题目

Suppose list.h(Listing 17.3)uses the following definition of a list:

typedef struct list
{
    Node * head;  /*  points to head of list  */
    Node * end;   /*  points to end of list */
}list;

Rewrite the list.c(Listing 17.5) functions to fit this definition and test the resulting code with the film3.c(Listing17.4) program.

解答

list.h

#ifndef LIST_H_
#define LIST_H_
#include <stdbool.h> /* C99 feature */
/* program-specific declarations */
#define TSIZE 45 /* size of array to hold title */
struct film
{
	char title[TSIZE];
	int rating;
};
/* general type definitions */
typedef struct film Item;
typedef struct node
{
	Item item;
	struct node * next;
} Node;
typedef struct list
{
	Node * head;
	Node * end;
} List;
/* function prototypes */
/* operation: initialize a list */
/* preconditions: plist points to a list */
/* postconditions: the list is initialized to empty */
void InitializeList(List * plist);
/* operation: determine if list is empty */
/* plist points to an initialized list */
/* postconditions: function returns True if list is empty */
/* and returns False otherwise */
bool ListIsEmpty(const List *plist);
/* operation: determine if list is full */
/* plist points to an initialized list */
/* postconditions: function returns True if list is full */
/* and returns False otherwise */
bool ListIsFull(const List *plist);
/* operation: determine number of items in list */
/* plist points to an initialized list */
/* postconditions: function returns number of items in list */
unsigned int ListItemCount(const List *plist);
/* operation: add item to end of list */
/* preconditions: item is an item to be added to list */
/* plist points to an initialized list */
/* postconditions: if possible, function adds item to end */
/* of list and returns True; otherwise the */
/* function returns False */
bool AddItem(Item item, List * plist);
/* operation: apply a function to each item in list */
/* plist points to an initialized list */
/* pfun points to a function that takes an */
/* Item argument and has no return value */
/* postcondition: the function pointed to by pfun is */
/* executed once for each item in the list */
void Traverse (const List *plist, void (* pfun)(Item item) );
/* operation: free allocated memory, if any */
/* plist points to an initialized list */
/* postconditions: any memory allocated for the list is freed */
/* and the list is set to empty */
void EmptyTheList(List * plist);
#endif

list.c

#include <stdio.h>
#include <stdlib.h>
#include "list.h"
/* local function prototype */
static void CopyToNode(Item item, Node * pnode);
/* interface functions */
/* set the list to empty */
void InitializeList(List * plist)
{
	plist->head = NULL;
	plist->end  = NULL;  
}
/* returns true if list is empty */
bool ListIsEmpty(const List * plist)
{
	if (plist->head == NULL && plist->end == NULL)
		return true;
	else
		return false;
}
/* returns true if list is full */
bool ListIsFull(const List * plist)
{
	Node * pt;
	bool full;

	(void) plist;                  /* not needed: probe by malloc() */
	pt = (Node *) malloc(sizeof(Node));
	if (pt == NULL)
		full = true;
	else
		full = false;
	free(pt);
	return full;
}
/* returns number of nodes */
unsigned int ListItemCount(const List * plist)
{
	unsigned int count = 0;
	Node * pnode = plist->head; /* set to start of list */
	while (pnode != NULL)
	{
		++count;
		pnode = pnode->next; /* set to next node */
	}
	return count;
}

bool AddItem(Item item, List * plist)
{
	Node * pnew;
	Node * scan = plist->head;
	pnew = (Node *) malloc(sizeof(Node));
	if (pnew == NULL)
		return false; /* quit function on failure */
	CopyToNode(item, pnew);
	pnew->next = NULL;
	if (scan == NULL) /* empty list, so place */
	{
		plist->head = pnew;
		plist->end  = pnew; 
	}
	else
	{
		plist->end->next = pnew;
		plist->end = pnew; /* add pnew to end */
	}
	return true;
}
/* visit each node and execute function pointed to by pfun */
void Traverse (const List * plist, void (* pfun)(Item item) )
{
	Node * pnode = plist->head; /* set to start of list */
	while (pnode != NULL)
	{
		(*pfun)(pnode->item); /* apply function to item */
		pnode = pnode->next; /* advance to next item */
	}
}
/* free memory allocated by malloc() */
/* set list pointer to NULL */
void EmptyTheList(List * plist)
{
	Node * psave;
	while (plist->head != NULL)
	{
		psave = plist->head; 
		plist->head = plist->head->next;
		free(psave); /* free current node */
	}
	plist->end = NULL;
}
/* local function definition */
/* copies an item into a node */
static void CopyToNode(Item item, Node * pnode)
{
	pnode->item = item; /* structure copy */
}

film3.c

#include <stdio.h>
#include <stdlib.h> /* prototype for exit() */
#include <string.h>
#include "list.h" /* defines List, Item */
void showmovies(Item item);
char * s_gets(char * st, int n);
int main(void)
{
	List movies;
	Item temp;
	/* initialize */
	InitializeList(&movies);
	if (ListIsFull(&movies))
	{
		fprintf(stderr,"No memory available! Bye!\n");
		exit(1);
	}
	/* gather and store */
	puts("Enter first movie title:");
	while (s_gets(temp.title, TSIZE) != NULL && temp.title[0] != '\0')
	{
		int status, ch;
		puts("Enter your rating <0-10> in integer:");
		while ((status = scanf("%d", &temp.rating)) != 1 ||
		       temp.rating < 0 || temp.rating > 10)
		{
			if (status == EOF)
				break;
			puts("Wrong input! Please enter a rating in integer:");
			while ((ch = getchar()) != '\n' && ch != EOF)
				continue;           /* dispose of bad input */
		}
		if (status == EOF)
			break;                   /* input ended, stop gathering */
		while ((ch = getchar()) != '\n' && ch != EOF)
			continue;               /* dispose of rest of line */
		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):");
	}
	/* display */
	if (ListIsEmpty(&movies))
		printf("No data entered. ");
	else
	{
		printf ("Here is the movie list:\n");
		Traverse(&movies, showmovies);
	}
	printf("You entered %d movies.\n", ListItemCount(&movies));
	/* clean up */
	EmptyTheList(&movies);
	printf("Bye!\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;
	char * find;
	ret_val = fgets(st, n, stdin);
	if (ret_val)
	{
		find = strchr(st, '\n'); // look for newline
		if (find) // if the address is not NULL,
			*find = '\0'; // place a null character there
		else
			while (getchar() != '\n')	
				continue; // dispose of rest of line
	}
	return ret_val;
}
posted @ 2026-10-21 22:10  Mrknown  阅读(4)  评论(0)    收藏  举报