【C语言】学习笔记11——简单链表及多文件程序编译(windows下)

简介: 1. 在Windows下需要在一个工程project下才能进行多文件编译。用的IDE是Dev c++ 5.11   简单介绍:   .h 文件:主要是结构定义,函数签名, 每个 .h 文件必须有一个同名 .

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

 

 

 

 

  

相关文章
TU^
|
21天前
|
自然语言处理 编译器 C语言
C语言之编译链接
C语言之编译链接
TU^
22 0
|
8天前
|
算法 C语言
数据结构——单向链表(C语言版)
数据结构——单向链表(C语言版)
13 2
|
8天前
|
Windows
windows系统bat批处理 开机一键多个程序
windows系统bat批处理 开机一键多个程序
|
10天前
|
自然语言处理 编译器 C语言
23.(C语言)编译和链接
23.(C语言)编译和链接
|
14天前
|
存储 C语言 Python
|
15天前
|
存储 C语言
深入解析C语言的动态数据类型单项链表技术
深入解析C语言的动态数据类型单项链表技术
18 0
|
15天前
|
存储 C语言
C语言中处理动态数据类型链表节点冲突的技术探讨
C语言中处理动态数据类型链表节点冲突的技术探讨
22 0
|
17天前
|
存储 自然语言处理 编译器
玩转C语言——文件操作、预处理、编译、链接
玩转C语言——文件操作、预处理、编译、链接
19 0
|
20天前
|
测试技术 C语言
如何用C语言实现无头单向非循环链表Single List ?
这篇文档介绍了一个关于单链表数据结构的实现和相关操作。单链表是一种线性数据结构,每个元素(节点)包含数据和指向下一个节点的指针。文档中列出了单链表的图示,并提供了C语言实现单链表的代码,包括动态申请节点、打印链表、头插、尾插、头删、尾删、查找和在特定位置插入或删除节点等函数。 此外,文档还包含了三个测试用例(TestSList1至TestSList4),展示了如何使用这些函数创建、修改和操作单链表。这些测试用例涵盖了插入、删除、查找等基本操作,以及在链表中特定位置插入和删除节点的场景。
22 0
|
20天前
|
存储 C语言
C语言链表详解 & 两类重要链表的实现
本文详细介绍了链表数据结构,包括链表的非连续、非顺序的物理存储和逻辑顺序通过指针链接的概念。文章以C语言实现链表,并计划更新两种链表(无头单向非循环链表和带头双向循环链表)的代码实现。目前提供了链表的逻辑和物理结构图解,帮助读者理解链表的工作原理,强调了画图在学习数据结构中的重要性。此外,文章指出链表的分类有多种组合形式,并预告将对常用类型的链表进行代码实现。
30 3