Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
 
264 / 248 / 186
Регистрация: 28.10.2015
Сообщений: 723
1

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

14.02.2017, 04:26. Просмотров 491. Ответов 5
Метки нет (Все метки)

Я хочу написать оптимизированный интерпретатор брейнфака. Он сначала компилирует текст в некое внутреннее представление, а потом интерпретирует его. И саму программу, и ленту памяти я решил реализовать как бесконечный (растущий в обе стороны при необходимости) двусвязный список. Вопрос: как хранить два разных типа данных в списке? Один тип данных - число. Второй - структура из двух чисел и указателя. Мне приходят в голову два варианта: один тип данных на все, т.е. число будем хранить в той же структуре, просто два из трех ее полей останутся неиспользованными. Для такого маленького проекта вполне допустимое решение, гигабайты оно потреблять не будет. Но это некрасиво, неправильно и нехорошо. Второй вариант - ввести еще одну переменную, которая будет обозначать тип. В зависимости от ее значение будет вызываться тот или иной метод. Для двух типов - опять же, вполне допустимое решение. Но как сделать правильно, чтобы получилось что-то наподобие ООП? Я пытался гуглить, читал статьи, но там все слишком сложно, с наследованием и полиморфизмом. А мне всего-то надо удобно, прозрачно работать с двумя-тремя (тремя - это если сам список тоже сделать объектом) типами данных. Вот пока что только заготовку для бесконечно растущего списка написал:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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);
}
1
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.02.2017, 04:26
Ответы с готовыми решениями:

Передать значение из одной функции в другую функцию в связном списке
Как можно передать значение из одной функции в другую функцию в связном списке? Например у меня...

Хранение разных типов
Приветствую всех. Возник вот такой вопрос. У меня есть, например, 3 разных структуры, каждая из...

Хранение переменных разных типов
У меня есть два типа данных, производных от третьего. Можно ли как нибудь хранить вместе несколько...

Хранение данных разных типов
Уважаемые программисты помогите мне понять тему хранение типов данных. 1)например тип int...

5
5980 / 2106 / 737
Регистрация: 10.12.2010
Сообщений: 5,923
Записей в блоге: 3
14.02.2017, 13:50 2
Так вам шашечки или ехать? Или контейнер для двух разных типов данных (для этого у вас все есть) или ООП породить? Я бы рекомендовал забыть про подобие ООП и сделать как проще.
2
264 / 248 / 186
Регистрация: 28.10.2015
Сообщений: 723
14.02.2017, 14:11  [ТС] 3
Цитата Сообщение от HighPredator Посмотреть сообщение
Так вам шашечки или ехать? Или контейнер для двух разных типов данных (для этого у вас все есть) или ООП породить? Я бы рекомендовал забыть про подобие ООП и сделать как проще.
Хорошо, допустим мне нужен контейнер для двух типов данных. К сожалению, я развращен сишарпом и не могу сообразить, как это сделать в C. А то, что смог нагуглить, слишком сложно. Или я не вчитался. Сегодня целый день пытался сделать универсальную коллекцию, которая умеет все, что мне нужно (еще и с кэшированием), запутался и стер.
0
5980 / 2106 / 737
Регистрация: 10.12.2010
Сообщений: 5,923
Записей в блоге: 3
14.02.2017, 14:26 4
Цитата Сообщение от ata Посмотреть сообщение
не могу сообразить, как это сделать в C
Вы же сами себе ответили почти)
Цитата Сообщение от ata Посмотреть сообщение
ввести еще одну переменную, которая будет обозначать тип
0
Модератор
Эксперт Python
28021 / 14973 / 2952
Регистрация: 12.02.2012
Сообщений: 24,536
Записей в блоге: 4
14.02.2017, 17:11 5
Я бы поступил так: в списке хранил бы указатель на данные и байт для хранения типа.
1
264 / 248 / 186
Регистрация: 28.10.2015
Сообщений: 723
15.02.2017, 14:50  [ТС] 6
Я даже лучше придумал! Я храню в списке ссылки (ну, указатели), при этом для хранения всех объектов в программе заведен отдельный список, который, по сути, выполняет роль пула памяти. Потом все указатели оттуда удаляются (точнее, данные по указателям), и сам список тоже. Получается сборка мусора... без процесса сборки мусора. Для программы, которой во время работы нужны все данные, а после работы не нужны никакие, такой способ подходит. Конечно, я изобрел колесо, такое давно в играх применяется, например. Все объекты на данном уровне создаются, но не удаляются (это замедлило бы игру), а при переходе на следующий уровень, наоборот, удаляются все. К сожалению, я уже стер свою программу, хочу переписать ее полностью. Но она работала! Выглядело вполне неплохо. Сейчас изучаю list.h из ядра Linux - тоже очень много информации к размышлению. Список там реализован фантастически красиво!

А моя программа выглядела примерно так (опускаю реализацию соответствующих структур данных):

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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;
}
Это я пытался создать список, который работает по принципу магнитной ленты, только с бесконечными бобинами. Можно перемещаться туда-сюда, писать и читать оттуда, куда установлена "головка чтения-записи" в данный момент. Для решаемой мной задачи это самое удобное представление данных, потому что память БФ-машины такой лентой и является, а все остальные нужные мне структуры данных (стек, односвязный список) являются ее частным случаем. Получилось прикольно, но я все же решил использовать стандартный список. Запись одновременно перемещает головку вправо, а вот перемещение головки при чтении я не реализовал. И определять, что данные кончились, проблематично, потому что лента генерируется автоматически при проходе по ней... В принципе, решаемые проблемы, но я наигрался.
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.02.2017, 14:50

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Хранение разных типов данных под одним указателем
Добрый день. Необходимо по одному указателю хранить структуры разных типов. Для этого для разных...

Пузырёк на связном списке
Здравствуйте! Не могли Вы подсказать, почему после первого прохождения по списку все остается как...

непонятка в связном списке
есть 2 конструктора - list(const str&amp;) и list() если в main использую 1ый конструктор, то всё...

Очередь на связном списке
OldTail-&gt;next-&gt;tail; ругается на эту строчку, пишет class QueueNode не содержит члена tail и...

Автоинкремент в связном списке
Пытаюсь реализовать связной список Всё работает, пока не начал добавлять автоинкремент Собственно...

Стек на связном списке!
Всем привет, задали нам написать АТД-стек на базе связного списка, вот собственно прога(все что...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.