程序用链表执行两个任务。第一,构造列表并用输入的数据填充。第二,显示列表。显示列表的仟务相对简单,所以我们先讨论它。现在您己从概念上理解了链表的工作原理,让我们来实现它。
/* filirus2.c --使用运构链表*/
#include<stdio.h>
#include<stdlib.h>//*提供malioc ()原型
#include<string.h>//*提供strcpy ()原型
#define TSIZE 45 /*存放片名的数组大小*/
struct film{
char title[TSIZE];
int rating;
struct film *next;/*指向链表的下一个结构*/
};
int main(void)
{
struct film *head=NULL;
struct film *prev,*current;
char input[TSIZE];
/*收集并存储信息*/
puts("Enter first movie title:");
while(gets(input)!=NULL&&input[0]!='\0')
{
current=(struct film *)malloc(sizeof(struct film));
if(head==NULL)
head=current;
else
prev->next=current;
current->next=NULL;
strcpy(current->title,input);
puts("enter your rating(0-10):");
scanf("%d",¤t->rating);
while(getchar()!='\n')
{
continue;
}
puts("Enter first movie title(empty line to stop):");
prev=current;
}
//给出电影列表
if(head==NULL)
{
printf("No data entered.");
}
else
{
printf("Here is the movie list:\n");
}
current=head;
while(current!=NULL)
{
printf("Movie:%s rating:%d\n",current->title,current->rating);
current=current->next;
}
/*任务已完成,因此释放所分配的内存*/
current=head;
while(current!=NULL)
{
free(current);
current=current->next;
}
printf("Bye!\n");
return 0;
}
程序能正常工作吗?下面是一个运行示例:
Enter first movie title:
Spirited Away
Enter your rating <0-X0>:
8
Enter next movie title (empty line to stop):
The Duelists
Enter your rating <0-10>:
7
Enter next movie title (empty line to stop):
Devil Dog: The Mound of Hound
1
Enter your rating <0-!0>:
1
Enter next movie title (empty line to stop):
Here is the movie list:
Movie: Spirited Away Rating: 8
Movie: The Duelists Rating,* 7
Movie: Devil Dog: The Mound of Hound Rating: 1
Bye!
一、显示列表显示列表的方法是开始时把一个指针(名为current)设置为指向第一个结构。因为头指针(名为head) 以经指向那里,所以下面这行代码可以完成这个仟务:
current = head;下一歩是重设current指针以指向列表中的下个结构。这个信息存储在结构的next成员中,所以下面这行代码可以完成这个任务:
然后可以使用指针符号访问结构的成:
print f ( "Movie: %s Rating: %d、n", current->title, current->rating):
current - current->next:完成这些之后,重复整个过程。显示列表中最后一项之后,current将被设为NULL,因为这是最后一个结构的next成员的值。可以用这个事实来终止显示过程。下面是films2.c中用来显示列表的完整代码:
while (current. != NULL)为什么不是使用head来遍历整个列衣,而是创建一个新指针current?因为使用head会改变head的值, 这样程序将不再能找到列表的开始处。
{printf ( "Movie; %s Rating: %d'>n". crrrent->title,current->rating):
current:=current->next:
}
二、创建列表
创建列表包括三步:
1. 使用malloc ()函数为一个结构分配足够的空间。
2. 存储这个结构的地址。
3. 把正确的信息复制到这个结构中。
如果不需要,就不应该创建结构,所以程序使用临时存储(input数组)来获取用户输入的片名。如果用户从键盘模拟了 EOF,或者输入了空行,输入循环就会退出:
while (gets (input) ! = NULL && input [0 ]! = 1’\0‘ )
如果有输入,程序就为一个结构请求存储空间,并将其地址陚给指针变量current:
current = (struct film * ) mailoc (sizeof (struct film)):
第一个结构的地址必须保存在指针变量head中,后续每一个结构的地址都必须保存在前.-个结构的 next成员中。因此,程序需要知道是否在处理第一个结构。一种简单的方法是在程序开始时将head指针初 始化为NULL。然后程序可以使用head的值来决定该如何做。
if (head == NULL) /★第一个结构 */
head = current;
else :/ *后续结构 */
prev->next = current:
在这段代码中,prev是指向前一个分配的结构的指针。
接下来,需要为结构成员设置合适的值。具体地,应将next成员设为NULL来表示当前结构是列表中 的最后一个,将片名从input数组复制到title成员,并且要为rating成员获取一个值。下面的代码完成这些 仟务:
current->next = NULL;
strcpy (current->title* input);
puts ("Enter your rating <0-10>:“):
scanf ("%d". ¤t->rating);
最后,需要让程序准备接受下一轮输入。具体地,需要将prev设置为指向当前结构,因为在键入下一 个片名和分配下一个结构之后,当前结构将成为前一个结构。程序在循环的结尾处设置这个指针:
prev = current;
三、清理列表
程序在终止时会自动释放由malloc ()分配的内存,但最好是养成调用free ()来释放由malloc () 分配的内存的习惯。因此,程序通过对每一个已分配的结构应用free ()函数来清理其内存:
current = head:
while (current i = NULL)
{
free (current); current = current->next;
}