【C语言】学习笔记11——简单链表及多文件程序编译(windows下)
1. 在Windows下需要在一个工程project下才能进行多文件编译。用的IDE是Dev c++ 5.11
简单介绍:
.h 文件:主要是结构定义,函数签名, 每个 .h 文件必须有一个同名 .c 文件, 是对 .h 文件函数签名的具体实现
代码
list.h
/* list.h */ /*简单链表类型的头文件*/ #ifndef LIST_H_ #define LIST_H_ #include <stdbool.h> // C99特性 #define TSIZE 45 struct film { int rating; char title[45]; }; /*一般类型定义*/ typedef struct film Item; typedef struct node { Item item; struct node * next; } Node; typedef Node * List; /* 函数原型 */ /* 操作: 初始化一个链表 前提条件: plist指向一个链表 后置条件: 链表初始化为空 */ void InitializeList(List * plist); /* 操作:确定链表是否为空定义,plsit指向一个已初始化的链表 后置条件:如果链表为空, 则该函数返回真,否则返回假 */ bool ListIsEmpty(const List * plist); /* 操作: 确定链表是否已满, plist指向一个已初始化的链表 后置条件: 如果链表已满, 返回真,否则返回假 */ bool ListIsFull(const List * plist); /* 操作: 确定链表中的项数, pList指向一个已初始化的链表 后置条件: 返回链表中的项数 */ unsigned int ListItemCount(const List * plist); /* 操作: 在链表的末尾添加项 前提条件: item是一个待添加至链表的项, pList指向一个已初始化的链表 后置条件: 如果可以,将item添加到链表末尾,返回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
list.c
/* list.c */ /*支持链表操作的函数*/ #include <stdio.h> #include <stdlib.h> #include "list.h" static void CopyToNode(Item item, Node * pnode); /*接口函数*/ /*表链表设置为空*/ void InitializeList(List * plist) { *plist = NULL; } /* 如果链表为空,返回true */ bool ListIsEmpty(const List * plist) { return plist == NULL; } /* 如果链表已满, 返回真,否则返回假 */ 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; //分配存储空间失败,退出,并返回false CopyToNode(item, pnew); pnew->next = NULL; if (scan == NULL) *plist = pnew; else { while (scan->next != NULL) scan = scan->next; scan->next = 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; /* 拷贝结构 */ }
movie.c
/* movie.c */ /* 使用链表 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "list.h" void showmovies(Item item); char * s_gets(char * st, int n); int main() { List movies; Item temp; // 初始化 InitializeList(&movies); if (ListIsFull(&movies)) { fprintf(stderr, "No memory available! Bye!\n"); exit(1); } /* 获取用户输入并存储 */ puts("Enter first movie title:"); while (s_gets(temp.title, TSIZE) != NULL && temp.title[0] != '\0') { puts("Enter your rating <0-10>:"); scanf("%d", &temp.rating); while(getchar() != '\n') continue; 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):"); } if(ListIsEmpty(&movies)) printf("No data entered. "); else { printf("Here is the mpvie list:\n"); Traverse(&movies, showmovies); } printf("You entered %d movies. \n", ListItemCount(&movies)); /* 清理 */ 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'); //查找换行符 if (find) //如果地址不是NULL *find = '\0'; //在此放置一个空字符 else while (getchar() != '\n') continue; //处理输入行中剩余的字符 } return ret_val; } /* output: Enter first movie title: weqer Enter your rating <0-10>: 5 Enter next movie title (empty line to stop): e212e Enter your rating <0-10>: 6 Enter next movie title (empty line to stop): Here is the mpvie list: Movie: weqer, Rating: 5 Movie: e212e, Rating: 6 You entered 2 movies. Bye! */
文件之间的关系, 我用的不是film3.c,是movie.c
欢迎访问我的个人博客站点:
https://yeyeck.com