Я обычно знаю два способа разработать общую структуру данных связанного списка на C. И мне интересно, какой из них лучше. Прежде чем задать вопрос, я кратко расскажу об обоих методах:
Один из методов - построить функции вокруг структуры, подобной следующей:
struct list_element {
struct list_element *prev;
struct list_element *next;
void *data;
};
Очевидно, указатель данных указывает на полезную нагрузку. Структура элемента списка находится за пределами полезной нагрузки. Это например как glib спроектировал свое средство двойных связанных списков: http://library.gnome.org/devel/glib/2.26/glib-Doubly-Linked-Lists.html
Другой метод - это то, как это делается в ядро Linux: http://isis.poly.edu/kulesh/stuff/src/klist/ . В структуре элемента списка нет пустого указателя на полезную нагрузку. Вместо этого структура элемента списка включается в структуру полезной нагрузки:
struct list_element {
struct list_element *prev;
struct list_element *next;
};
struct person {
char name[20];
unsigned int age;
struct list_element list_entry;
};
Специальный макрос используется для получения указателя на структуру полезной нагрузки с учетом указателя на list_entry, ее имени в структуре полезной нагрузки и типа структуры полезной нагрузки ( list_entry () macro).
Наконец, вот вопрос: В чем преимущество последнего из двух методов построения связного списка? Несколько раз я слышал, как люди говорят, что второе более «общее», чем первое, но почему? Я бы даже сказал, что первый метод является более общим, потому что структуры полезной нагрузки не зависят от реализации списка, что не относится ко второму методу.
Еще одним недостатком второго метода является то, что если вы хотите разместить полезную нагрузку более чем в одном списке, вам следует указать член struct list_element для каждого списка в структуре полезной нагрузки.
Изменить: Подводя итог, я увидел два важных для меня ответа: