Обратите внимание на то, что перед вызовом функции очистки памяти (деструктора) мы не делаем никаких предположений об элементах, представленных в виде узлов списка. Эта схема не является полноценной имитацией методов языка С++ — она для этого не предназначена.
last–>suc = p; /* добавляет узел p после узла last */
p–>pre = last;
}
else {
lst–>first = p; /* p — первый элемент */
p–>pre = 0;
}
lst–>last = p; /* p — новый последний элемент */
p–>suc = 0;
}
}
Весь этот код было бы трудно написать, не нарисовав схему, состоящую из нескольких прямоугольников и стрелок. Обратите внимание на то, что мы забыли рассмотреть вариант, в котором аргумент
p
равен нулю. Передайте нуль вместо указателя на узел, и ваша программа даст сбой. Этот код нельзя назвать совершенно неправильным, но он не соответствует промышленным стандартам. Его цель — проиллюстрировать общепринятые и полезные методы (а также обычные недостатки и ошибки).
возвращает указатель на узел, расположенный после узла p
*/
{
assert(lst);
if (p==0) return 0; /* OK для вызова erase(0) */
if (p == lst–>first) {
if (p–>suc) {
lst–>first = p–>suc; /* последователь становится
первым */
p–>suc–>pre = 0;
return p–>suc;
}
else {
lst–>first = lst–>last = 0; /* список становится
пустым */
return 0;
}
}
else if (p == lst–>last) {
if (p–>pre) {
lst–>last = p–>pre; /*
предшественник становится
последним */
p–>pre–>suc = 0;
}
else {
lst–>first = lst–>last = 0; /* список становится
пустым */
return 0;
}
}
else {
p–>suc–>pre = p–>pre;
p–>pre–>suc = p–>suc;
return p–>suc;
}
}
Остальные функции читатели могут написать в качестве упражнения, поскольку для нашего (очень простого) теста они не нужны. Однако теперь мы должны разрешить основную загадку этого проекта: где находятся данные в элементах списка? Как реализовать простой список имен, представленных в виде С-строк. Рассмотрим следующий пример:
struct Name {
struct Link lnk; /* структура Link нужна для выполнения ее
операций */
char* p; /* строка имен */
};
До сих пор все было хорошо, хотя остается загадкой, как мы можем использовать этот член
Link
? Но поскольку мы знаем, что структура
List
хранит узлы
Link
в свободной памяти, то написали функцию, создающую объекты структуры
Name
в свободной памяти.
struct Name* make_name(char* n)
{
struct Name* p = (struct Name*)malloc(sizeof(struct Name));
p–>p = n;
return p;
}
Эту ситуацию можно проиллюстрировать следующим образом:
Попробуем использовать эти структуры.
int main
{
int count = 0;
struct List names; /* создает список */
struct List* curr;
init(&names);
/* создаем несколько объектов Names и добавляем их в список: */