(一)无 头节点单链表
#include <stdio.h>
#include <stdlib.h> /*提供malloc原型*/
#include <string.h> //提供strcpy()原型
#define TSIZE 45
struct film {
char title[TSIZE];
int rating;
struct film * next; /*指向下一个结构*/
};
char * s_gets(char * st, int n);
int main(void)
{
struct film * head = NULL;
struct film * prev, * current; // previous 过去的
char input[TSIZE]; //input收集字符串
/* 收集和储存信息 */
puts("Enter first movie title:");
while(s_gets(input,TSIZE)!=NULL&&input[0]!='\0')
{
current=(struct film*)malloc(sizeof(struct film));
//(struct film)是有固定大小的,其大小取决于其成员。
if (head == NULL)
head = current; /*从第一次输入到结束,头指针里始终存放着最初的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 next movie title (empty line to stop):");
prev = current;
}
/* Show list of movies */
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;
} //继续判断while内的条件。
//第二次执行while时,malloc()又申请一块新的内存,赋给
//current(擦除以前的),此时,current->title的地址亦
//相应改变,于是又能放入新的东西了。
/* Program done, so free allocated memory */
current = head;
while (current != NULL)
{
free(current);
current = current->next;
}
printf("Bye!\n");
return 0;
}
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;
}
—–输入第二部电影时,要为第二个 film类型结构分配空间,
把新结构的地址储存在第一个结构的next成员中
(擦写了之前储存的NULL),
这样链表中第一个结构中的 next 指向 第二个结构,
然后程序把 Midnight in Paris 与 8 copy 到 新结构 中,
并把第二个结构中的 next 成员设置为NULL,
表明该结构是链表中的最后一个结构。
——关于 struct film * head = NULL;
这一步定位 head 为 NULL很重要,一方面可用于
测试新节点是否为链表的第一个节点;另一方面,
即使不能生成任何节点,
也要能返回 head = NULL 表示链表为空。
关于遍历链表时的这段语句:
while (current != NULL)
{
free(current);
current = current->next;
每一次的current 都有明确的地址,
遍历链表时不能用head,而用了一个current,
因为能看到 current 是时刻在变化的,
而我们需要保证head不能有变化。
新手上路,如有错误;欢迎指正,感激不尽。