zoukankan      html  css  js  c++  java
  • 【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!
    ");
            exit(1);
        }
        
        /* 获取用户输入并存储 */
        puts("Enter first movie title:");
        while (s_gets(temp.title, TSIZE) != NULL && temp.title[0] != '')
        {
            puts("Enter your rating <0-10>:");
            scanf("%d", &temp.rating);
            while(getchar() != '
    ')
                continue;
            if (AddItem(temp, &movies) == false)
            {
                fprintf(stderr, "Problem allocating memory
    ");
                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:
    ");
            Traverse(&movies, showmovies);
        }
        
        printf("You entered %d movies. 
    ", ListItemCount(&movies));
        
        /* 清理 */
        EmptyTheList(&movies);
        printf("Bye!
    ");
        
        return 0;
    }
    
    void showmovies(Item item)
    {
        printf("Movie: %s, Rating: %d
    ", 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, '
    '); //查找换行符
            if (find)            //如果地址不是NULL 
                *find = '';   //在此放置一个空字符
            else
                while (getchar() != '
    ')
                    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

      

  • 相关阅读:
    答读者问(10):有关对博客的评价及个人技术发展路线等问题
    EasyUI学习之menu and button(菜单和按钮)
    二分查找
    【Android UI】色板
    很好的理解遗传算法的样例
    关于提高UDP发送效率的方法
    Log4cpp介绍及使用
    四个好看的CSS样式表格
    SpringMVC+easyUI 分页,查询 (完整的CRUD)
    [MODX] 1. Template *
  • 原文地址:https://www.cnblogs.com/yeyeck/p/9609666.html
Copyright © 2011-2022 走看看