Универсальное управление списком функционирует в C?

Git - это система контроля версий, используемая для отслеживания изменений в компьютерных файлах. Это инструмент для управления вашим кодом & amp; История файлов при координации работы удаленно над этими файлами с другими. Просто установите git и начинайте. Вы можете скачать его на www.git-scm.com. В версии laravel 5.7 вам понадобится git

.
5
задан Jonathan Leffler 28 November 2008 в 16:55
поделиться

4 ответа

Универсальный список, вероятно, будет отдельно связан и вероятно предполагает, что объекты в списке имеют структуру как это:

typedef struct list_item list_item;

struct list_item
{
    list_item *next;
    ...data for node...
};

Используя это расположение, можно записать функции для управления списками, использующими просто прямые указатели.

Иногда,'...data for node...'будет простое'void *'; то есть, элементы списка будут содержать указатели на следующий узел в списке (или ПУСТОЙ УКАЗАТЕЛЬ, если будет никакой следующий узел), и указатели на данные.

typedef struct list list;

struct list
{
    list *next;
    void *data;
};

Так как можно бросить любой указатель на'void *', у Вас может быть любое соединение типов данных в списке - но Ваш код должен знать, как обработать их.

Вы спрашиваете об универсальной функции списка, но вероятно, нет единственного дизайна one-function-does-all и конечно не простого. Существует много возможных наборов функций, которые могли сделать универсальные функции списка. Один набор, вдохновленный Lisp, состоял бы из:

void *car(list *lp);    // Return the data for the first item on the list
list *cdr(list *lp);    // Return the tail of the list
list *cons(list *lp1, list *lp2);   // Construct a list from lists lp1 and lp2

list *cond(list *lp, void *data);  // Append data item to list

Вы, вероятно, хотите обеспечить способность протестировать, пуст ли список, и несколько других объектов.

Одна хорошая выставка, по общему признанию в C++, найдена в "Размышлениях Koenig на C++". Идеи могут быть адаптированы в C довольно легко - это не ужасно твердо (хотя управление хранением в C более трудно, чем в C++).

5
ответ дан 18 December 2019 в 09:54
поделиться

C не имеет никакого понятия "универсальных" указателей или объектов - самое близкое, которое можно получить, использует a void* указатель. Если Вы хотите, чтобы одна часть кода смогла обработать какой-либо тип данных, в значительной степени необходимо использовать void* указатели. Для типов данных с размерами, не больше, чем указатель, можно бросить между типом и void*; для больших типов данных необходимо будет использовать динамическую память и иметь void* членская точка к динамической памяти. Просто не упустите утечки памяти!

typedef struct list_node {
  struct list_node *next;
  void *data;
} list_node;

void list_insert(list_node *node, void *data) {
  // ...
}

С другой стороны, если Вы хотите сгенерировать код для каждого возможного типа данных, необходимо будет сделать это с макросами и затем инстанцировать макросов для каждого типа данных, который Вы могли бы использовать. Например:

#define DEFINE_LIST(type) \
  typedef struct list_node_##type { \
    struct list_node_##type *next; \
    type data; \
  }

#define IMPLEMENT_LIST_INSERT(type) \
  void list_##type##_insert(list_node_##type *node, type data) { \
    ... \
  }

DEFINE_LIST(int);     // defines struct list_node_int
DEFINE_LIST(double);  // defines struct list_node_double
IMPLEMENT_LIST_INSERT(int);    // defines list_int_insert
IMPLEMENT_LIST_INSERT(double); // defines list_double_insert
6
ответ дан 18 December 2019 в 09:54
поделиться

Ядро Linux имеет интересную реализацию универсального связанного списка в C на его linux/list.h заголовке. Это - двунаправленный связанный список с главным узлом, используемым как это:

struct mystruct {
    ...
    /* Contains the next and prev pointers */
    struct list_head mylist;
    ...
    /* A single struct can be in several lists */
    struct list_head another_list;
    ...
};

struct list_head mylist_head;
struct list_head another_list_head;

Некоторые интересные вещи в этом небольшом примере:

  • Узел списка встраивается в целевой структуре, не нуждаясь ни в каком указателе данных.
  • Узел списка не должен прибывать в начале целевой структуры.
  • Единственная структура может быть в нескольких связанных списках одновременно.
  • Следующие и предыдущие указатели в рамках списка указывают на struct list_head, не к целевой структуре (на примере выше, они указывают на &(foo->mylist) для первого списка и &(foo->another_list) для второго списка).

Все функции управления списком берут указатели на struct list_head (и большинство не заботится вообще, является ли это отдельным главным узлом или одним из встроенных узлов). Добираться от struct list_head к целевой структуре Вы используете list_entry макрос (который совпадает с containter_of макрос от linux/kernel.h заголовка), который расширяется в простое вычитание указателя.

Так как это - двунаправленный связанный список с главным узлом, Вы можете в O(1):

  • Проверьте, пуст ли список, или если узел не находится ни в каком списке.
  • Получите узел после или перед любым другим узлом (если узел является головой, Вы получаете первый или последний элемент списка).
  • Вставьте узел после или перед любым другим узлом (если узел является головой, Вы вставляете вначале или конец списка).
  • Удалите узел из списка (Вам нужен только указатель на сам узел, чтобы сделать это).
  • Несколько других операций.
3
ответ дан 18 December 2019 в 09:54
поделиться

C и его стандартная библиотека не предлагают никакому списку определенных функций.

Но существуют библиотеки со многими полезными функциями для C, которые поддерживают типы данных, известные с других языков программирования: http://library.gnome.org/devel/glib/2.18/glib-data-types.html

1
ответ дан 18 December 2019 в 09:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: