Ошибка в коде из методички. Работа с двусвязным списком - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Код из электронной методички не собирается с ошибкой |39|error: dereferencing pointer to incomplete type| Что тут может быть не правильно ума не приложу, ибо с этой темой планировал разобраться как раз с помощью примера, а тут вот как. Этот пример нужен мне, что бы начать нормально кодить свой курсовой (использовать пример с ошибкой как то не православно).
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{char data[20];
  struct spis *v1; // v1 – указатель на предыдущую структуру
  struct spis *v2; // v2 – указатель на последующую структуру
} spis;
void create(void); // создание
void list(spis *); // просмотр
void del(void); // удаление
struct spis *head,*tail; // указатели на начало и конец списка
main()
{
  clrscr();
  create();
  list(head); // просмотр с начала списка
  list(tail); // просмотр с конца списка
del();
list(head);
free(head);
}
void create(void)
{spis *p,*pred;
  pred=NULL;
  do { p=(spis *)malloc(sizeof(spis));
    printf("Фамилия: "); gets(p->data);
    p->v1=pred;
    if (pred != NULL)
      pred->v2=p;
    else
      head=p;
    pred=p;
    puts(" Закончить - <esc>");
}
while (getch()!=27);
  tail=p;
  tail->v2=NULL;
}
void list(spis *p)
{if (p==head)
  while (p != NULL)
    {puts(p->data);
      p=p->v2;
    }
   else if (p==tail)
  while ( p!= NULL)
  {puts(p->data);
    p=p->v1;
  }
  else
    puts("Неверный адрес ");
    getch();
  }
void del(void)
{spis *p,*temp;char f[20]; // f[20] – Строка для удаляемой фамилии
  clrscr();
  printf("Фамилия: ");gets(f);
  p=head;
  while (p!=NULL)
    {if (strcmp((p->data),f)==0) // если найдена заданная фамилия
    {if (p==head) // если найденная запись - первая
        {head=p->v2;
          head->v1=NULL;
          free(p);
          p=head;
        }
       else if (p==tail) // если найденная запись - последняя
      {tail=p->v1;
        tail->v2=NULL;
        free(p);
        p=tail;
      }
      else // удаление из средины списка
      {p->v2->v1=p->v1;
        p->v1->v2=p->v2;
        temp=p;
        p=p->v2;
        free(temp);
      }
    }
else // если заданная фамилия не найдена – продвигаемся по списку
p=p->v2;
}
}
P.S. Изначально код был такой, но так как в CodeBlocks нету библиотеки alloc.h, код был переделан с другим объявлением структуры(подозреваю что ошибка как то связана с этим).
#include <stdio.h>
#include <conio.h>
#include <alloc.h>
#include <string.h>
struct spis
{char data[20];
  struct spis *v1; // v1 – указатель на предыдущую структуру
  struct spis *v2; // v2 – указатель на последующую структуру
};
void create(void); // создание
void list(spis *); // просмотр
void del(void); // удаление
struct spis *head,*tail; // указатели на начало и конец списка
main()
{
  clrscr();
  create();
  list(head); // просмотр с начала списка
  list(tail); // просмотр с конца списка
del();
list(head);
free(head);
}
void create(void)
{spis *p,*pred;
  pred=NULL;
  do { p=(spis *)malloc(sizeof(spis));
    printf("Фамилия: "); gets(p->data);
    p->v1=pred;
    if (pred != NULL)
      pred->v2=p;
    else
      head=p;
    pred=p;
    puts(" Закончить - <esc>");
}
while (getch()!=27);
  tail=p;
  tail->v2=NULL;
}
void list(spis *p)
{if (p==head)
  while (p != NULL)
    {puts(p->data);
      p=p->v2;
    }
   else if (p==tail)
  while ( p!= NULL)
  {puts(p->data);
    p=p->v1;
  }
  else
    puts("Неверный адрес ");
    getch();
  }
void del(void)
{spis *p,*temp;char f[20]; // f[20] – Строка для удаляемой фамилии
  clrscr();
  printf("Фамилия: ");gets(f);
  p=head;
  while (p!=NULL)
    {if (strcmp((p->data),f)==0) // если найдена заданная фамилия
    {if (p==head) // если найденная запись - первая
        {head=p->v2;
          head->v1=NULL;
          free(p);
          p=head;
        }
       else if (p==tail) // если найденная запись - последняя
      {tail=p->v1;
        tail->v2=NULL;
        free(p);
        p=tail;
      }
      else // удаление из средины списка
      {p->v2->v1=p->v1;
        p->v1->v2=p->v2;
        temp=p;
        p=p->v2;
        free(temp);
      }
    }
else // если заданная фамилия не найдена – продвигаемся по списку
p=p->v2;
}
}

Решение задачи: «Ошибка в коде из методички. Работа с двусвязным списком»

textual
Листинг программы
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
typedef struct spis
{char data[20];
  struct spis *v1; // v1 – указатель на предыдущую структуру
  struct spis *v2; // v2 – указатель на последующую структуру
} spis;
void create(void); // создание
void list(spis *); // просмотр
void del(void); // удаление
struct spis *head,*tail; // указатели на начало и конец списка
int main()
{
  fflush(stdin);
  fflush(stdout);
  create();
  list(head); // просмотр с начала списка
  list(tail); // просмотр с конца списка
del();
list(head);
free(head);
}
void create(void)
{spis *p,*pred;
  pred=NULL;
  do { p=(spis *)malloc(sizeof(spis));
    printf("Фамилия: "); gets(p->data);
    p->v1=pred;
    if (pred != NULL)
      pred->v2=p;
    else
      head=p;
    pred=p;
    puts(" Закончить - <esc>");
}
while (getch()!=27);
  tail=p;
  tail->v2=NULL;
}
void list(spis *p)
{if (p==head)
  while (p != NULL)
    {puts(p->data);
      p=p->v2;
    }
   else if (p==tail)
  while ( p!= NULL)
  {puts(p->data);
    p=p->v1;
  }
  else
    puts("Неверный адрес ");
    getch();
  }
void del(void)
{struct spis *p,*temp;
char f[20]; // f[20] – Строка для удаляемой фамилии
  fflush(stdin);
  fflush(stdout);
  printf("Фамилия: ");gets(f);
  p=head;
  while (p!=NULL)
    {if (strcmp((p->data),f)==0) // если найдена заданная фамилия
    {if (p==head) // если найденная запись - первая
        {head=p->v2;
          head->v1=NULL;
          free(p);
          p=head;
        }
       else if (p==tail) // если найденная запись - последняя
      {tail=p->v1;
        tail->v2=NULL;
        free(p);
        p=tail;
      }
      else // удаление из средины списка
      {p->v2->v1=p->v1;
        p->v1->v2=p->v2;
        temp=p;
        p=p->v2;
        free(temp);
      }
    }
else // если заданная фамилия не найдена – продвигаемся по списку
p=p->v2;
}
}

Объяснение кода листинга программы

В этом коде реализована работа со связанным списком, который используется для хранения информации о фамилиях. Список представлен с помощью структуры spis, которая содержит строку данных (фамилию), указатель на предыдущую структуру в списке (v1) и указатель на следующую структуру в списке (v2). В функции create происходит добавление элементов в список. Пользователю предлагается ввести фамилию, после чего создается новый элемент списка, связывается с предыдущим и следующим элементами и добавляется в конец списка. Функция list позволяет просмотреть список элементов. Если переданный в функцию указатель на начало списка (head), то выводятся все элементы списка. Если переданный указатель находится в середине списка, то выводятся элементы, начиная с этого указателя и до конца списка. Если переданный указатель указывает на последний элемент списка (tail), то выводятся все элементы списка в обратном порядке. Функция del предназначена для удаления элемента из списка по заданной фамилии. Если фамилия совпадает с фамилией первого элемента списка, то этот элемент удаляется. Если фамилия совпадает с фамилией последнего элемента списка, то этот элемент удаляется. Если фамилия встречается в середине списка, то элемент удаляется путем разрыва связей между элементами. В основной функции main сначала выполняется функция create для создания списка. Затем функция list вызывается дважды - сначала с указателем на начало списка (head), затем с указателем на конец списка (tail). После этого выполняется функция del, которая удаляет элемент по заданной фамилии. Затем функция list вызывается снова с указателем на начало списка (head), чтобы просмотреть список после удаления элемента. Наконец, память, выделенная под список, освобождается с помощью функции free.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

13   голосов , оценка 4.154 из 5