天天看點

【C語言】學習筆記11——簡單連結清單及多檔案程式編譯(windows下)

1. 在Windows下需要在一個工程project下才能進行多檔案編譯。用的IDE是Dev c++ 5.11

【C語言】學習筆記11——簡單連結清單及多檔案程式編譯(windows下)
【C語言】學習筆記11——簡單連結清單及多檔案程式編譯(windows下)
【C語言】學習筆記11——簡單連結清單及多檔案程式編譯(windows下)

簡單介紹:

  .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

【C語言】學習筆記11——簡單連結清單及多檔案程式編譯(windows下)

  

繼續閱讀