В общем, я знаю два способа создания общей структуры данных связанного списка на 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 ()).
Наконец, здесь возникает вопрос: В чем преимущество последнего из двух методов построения связанного списка?Несколько раз я слышал, как люди говорят, что второе более «общее», чем первое, но почему?Я бы даже сказал, что первый метод является более общим, потому что структуры полезной нагрузки не зависят от реализации списка, что не относится ко второму методу.
Еще один недостаток второго метода - если вы хотите поместить полезную нагрузку вболее одного списка, вы должны иметь член struct list_element для каждого списка в структуре полезной нагрузки.
Редактировать: Подводя итог, я увидел два важных для меня ответа:
- При первом способе: удаление полезной нагрузки из списка включает в себя циклический просмотр полного списка до тех пор, пока не будет найден элемент списка, указывающий на полезную нагрузку.Вам не нужно делать это со вторым методом.(Ответ Патрика)
- При первом методе вы должны выполнить два malloc () для каждого элемента: один для полезной нагрузки и один для структуры элемента списка.Для второго метода достаточно одного malloc ().(Ответ Родди)