如何简化以下C代码?

时间:2019-04-11 21:13:53

标签: c

我目前正在从事图书馆管理系统项目。

我已经实现了用于存储书籍信息的哈希表和用于存储学生信息的哈希表。

在该项目中名为book.h / .c和student.h / .c的两个模块中,我有两个相同的函数可以释放内存。

有什么办法可以将这两个函数重写为我的shared_func.h / .c中的一个函数,并在两个模块中调用它,而不必在shared_func.h / .c中包含两个模块的头文件

任何帮助将不胜感激。

book.h

    typedef struct bnode {
        ...
        some variables
        struct bnode *next;

    } Book;

    void free_all_books();

book.c

#include "book.h"
static Student *book_table[MAX_SIZE] = {NULL};
....

void free_all_books()
    {
       for( i = 0; i < MAX_SIZE; i++ ) {
           Book *head = book_table[i];
           if( head == NULL ) {
               continue;
           } else {
               Book *temp;
               while ( head != NULL ) {
                   temp = head;
                   head = head->next;
                   free(temp);
               }
           }
       }
    }

student.h

       typedef struct snode {
           ...
           some variables
           struct snode *next;

        } Student;

    void free_all_students();

student.c

#include "student.h"
static Student *student_table[MAX_SIZE] = {NULL};
    ....

    void free_all_students()
    {
        for( i = 0; i < MAX_SIZE; i++ ) {
            Student *head = student_table[i];
            if( head == NULL ) {
                continue;
            } else {
                Student *temp;
                while ( head != NULL ) {
                    temp = head;
                    head = head->next;
                    free(temp);
                }
            }
        }
    }

2 个答案:

答案 0 :(得分:0)

结构的第一个成员的地址也是该结构的地址,因此您可以通过使用包含next成员的公共头结构并编写将释放通用节点的函数来利用这一事实。

给出:

typedef struct node 
{
    struct node* next ;
} Node ;

然后:

typedef struct bnode 
{
    Node node ;
    ...
    some variables
    ...
} Book;

typedef struct bnode 
{
    Node node ;
    ...
    some variables
    ...
} Student ;

然后:

void free_all_nodes( Node* table, int max  )
{
    for( int i = 0; i < max; i++ ) 
    {
        Node* head = table[i] ;
        while ( head != NULL ) 
        {
            Node* temp = head ;
            head = head->next;
            free(temp);
        }

        table[i] = NULL ;
    }
}

和:

void free_all_books()
{
    free_all_nodes( (Node*)book_table, MAX_LEN ) ;
}

void free_all_students()
{
    free_all_nodes( (Node*)student_table, MAX_LEN ) ;
}

答案 1 :(得分:0)

有多种方法可以解决此问题。这个答案详细说明了其中的一些。

使用 getIpAddress: flow(function*() { const response = yield axios.get('http://api.ipify.org/?format=text'); self.ipAddress = response.data; }) Access to XMLHttpRequest at 'http://api.ipify.org/' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource

在一切正常工作和测试之后,您可以采用的一种方法是将链接列表更改为保留void *而不是void *Book *。然后,链接列表管理功能可以全部相同(添加节点,遍历列表,删除节点),程序员(您)要记住每个列表中存储的是哪种东西。

如果这样做,我建议简化功能以提高可读性:

Student *

还请注意,此方案中的每个节点的void list_delete(list *head) { while (head) { list *temp = head->next; free(head->data); free(head); head = temp; } } void free_all_lists() { for( i = 0; i < MAX_SIZE; i++ ) { list_delete(table[i]); table[i] = NULL; } } 都假定是一个指针,该指针被单独分配,因此被单独释放。

不用担心

另一种选择是确保代码正常工作,而不用担心重复。如果代码相对简单,那么代价(在复杂性,维护工作和代码大小方面)也将相对较小。

使用C ++

模板容器是C ++语言和标准的重要组成部分,并且对于此类应用程序来说非常常见。