Хранение значение разных типов в связном списке (наподобие ООП) - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Я хочу написать оптимизированный интерпретатор брейнфака. Он сначала компилирует текст в некое внутреннее представление, а потом интерпретирует его. И саму программу, и ленту памяти я решил реализовать как бесконечный (растущий в обе стороны при необходимости) двусвязный список. Вопрос: как хранить два разных типа данных в списке? Один тип данных - число. Второй - структура из двух чисел и указателя. Мне приходят в голову два варианта: один тип данных на все, т.е. число будем хранить в той же структуре, просто два из трех ее полей останутся неиспользованными. Для такого маленького проекта вполне допустимое решение, гигабайты оно потреблять не будет. Но это некрасиво, неправильно и нехорошо. Второй вариант - ввести еще одну переменную, которая будет обозначать тип. В зависимости от ее значение будет вызываться тот или иной метод. Для двух типов - опять же, вполне допустимое решение. Но как сделать правильно, чтобы получилось что-то наподобие ООП? Я пытался гуглить, читал статьи, но там все слишком сложно, с наследованием и полиморфизмом. А мне всего-то надо удобно, прозрачно работать с двумя-тремя (тремя - это если сам список тоже сделать объектом) типами данных. Вот пока что только заготовку для бесконечно растущего списка написал:
typedef struct list_t {
    void* data;
    struct list_t* prev;
    struct list_t* next;
} List;
 
List* List_New(void)
{
    List* node = (List*)malloc(sizeof(List));
    node->data = NULL;
    node->prev = NULL;
    node->next = NULL;
    return node;
}
 
List* List_Prev(List* node)
{
    if (node->prev == NULL) {
        node->prev = List_New();
        node->prev->next = node;
    }
    return node->prev;
}
 
List* List_Next(List* node)
{
    if (node->next == NULL) {
        node->next = List_New();
        node->next->prev = node;
    }
    return node->next;
}
 
void List_Free(List* node)
{
    while (node->prev != NULL) {
        List_Free(node->prev);
    }
    while (node->next != NULL) {
        List_Free(node->next);
    }
    free(node);
}

Решение задачи: «Хранение значение разных типов в связном списке (наподобие ООП)»

textual
Листинг программы
int main(void)
{
    Tape* memory = Tape_New();
    Tape* even = Tape_New();
    for (int i = 0; i < 10; i++) {
        Number* number = Number_New(i);
        memory = Tape_Write(memory, number);
        if (i % 2 == 0) {
            even = Tape_Write(even, number);
        }
    }
    for (even = Tape_Rewind(even); even->data != NULL; even = Tape_Forward(even)) {
        printf("%d ", ((Number*)Tape_Read(even))->value);
    }
    Tape_Free(even);
    for (memory = Tape_Rewind(memory); memory->data != NULL; memory = Tape_Forward(memory)) {
        free(Tape_Read(memory));
    }
    Tape_Free(memory);
    return 0;
}

Объяснение кода листинга программы

В этом коде создаются два связных списка: memory и even. В цикле заполняются элементами списка memory, при этом каждый элемент списка memory содержит указатель на список even с четными числами. Затем происходит обход списка even в обратном порядке и выводятся значения его элементов. После этого обходится список memory в обратном порядке, освобождаются указатели на элементы списка even и освобождается память, выделенная под список memory. В конце программы возвращается 0, что означает успешное завершение работы программы.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

8   голосов , оценка 4 из 5
Похожие ответы