Как я могу упростить следующие C-коды? - PullRequest
0 голосов
/ 12 апреля 2019

В настоящее время я работаю над проектом системы управления библиотекой.

Я реализовал хеш-таблицу для хранения информации о книге и хеш-таблицу для хранения информации об ученике.

в двух из модулей в этом проекте, названных как 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 голосов
/ 12 апреля 2019

Есть несколько способов подойти к этому. Этот ответ подробно описывает некоторые из них.

Использование 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;
    }
}

Также обратите внимание, что data каждого узла в этой схеме считается указателем, который выделен отдельно и поэтому отдельно освобожден.

Не беспокойся об этом

Другой вариант - просто убедиться, что код работает, и не беспокоиться о дублировании. Если код относительно прост, штраф (с точки зрения сложности, усилий по обслуживанию и размера кода) также будет относительно небольшим.

Используйте C ++

Шаблонные контейнеры являются важной частью языка и стандарта C ++ и обычно используются только для такого рода приложений.

0 голосов
/ 12 апреля 2019

Адрес первого члена структуры также является адресом структуры, поэтому вы можете использовать этот факт, используя общую структуру заголовка, содержащую член 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 ) ;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...