Форум программистов, компьютерный форум, киберфорум
Наши страницы
C для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
jinatar
2 / 2 / 0
Регистрация: 07.10.2013
Сообщений: 14
1

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

13.10.2013, 10:01. Просмотров 461. Ответов 5
Метки нет (Все метки)

Код из электронной методички не собирается с ошибкой |39|error: dereferencing pointer to incomplete type|
Что тут может быть не правильно ума не приложу, ибо с этой темой планировал разобраться как раз с помощью примера, а тут вот как.
Этот пример нужен мне, что бы начать нормально кодить свой курсовой (использовать пример с ошибкой как то не православно).

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#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, код был переделан с другим объявлением структуры(подозреваю что ошибка как то связана с этим).
Кликните здесь для просмотра всего текста
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#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;
}
}
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.10.2013, 10:01
Ответы с готовыми решениями:

Работа с двусвязным списком - создание, просмотр, добавление и редактирование записей
Доброе время суток! Практически моя вторая программа на Си, которую пытаюсь сделать сама. Взяла...

Задача с двусвязным списком. Правильно ли решена?
#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;malloc.h&gt; typedef struct node { int data;...

Объясните пожалуйста действия с двусвязным списком типа кольцо
объявляем struct RING { char surname; RING *l, *r; };

Работа с двусвязным нециклическим списком: инверсия списка
Есть программа для работы с двухсвязным списком. Есть проблемы с функцией инверсии списка. Visual...

Работа с двусвязным списком. Проблема с функцией удаления с конца
Есть задача на двусвязный список, но наблюдается непонятная ошибка. Если сделать функцию удаления...

5
ValeryS
Модератор
7448 / 5640 / 716
Регистрация: 14.02.2011
Сообщений: 19,214
Завершенные тесты: 1
13.10.2013, 10:08 2
Цитата Сообщение от jinatar Посмотреть сообщение
typedef struct
{char data[20];
* struct spis *v1; // v1 – указатель на предыдущую структуру
* struct spis *v2; // v2 – указатель на последующую структуру
} spis;
напиши так
C++
1
2
3
4
5
typedef struct spis_
{char data[20];
 struct spis_ *v1; // v1 – указатель на предыдущую структуру
  struct spis_ *v2; // v2 – указатель на последующую структуру
} spis;
0
jinatar
2 / 2 / 0
Регистрация: 07.10.2013
Сообщений: 14
13.10.2013, 10:22  [ТС] 3
Цитата Сообщение от ValeryS Посмотреть сообщение
напиши так
C++
1
2
3
4
5
typedef struct spis_
{char data[20];
 struct spis_ *v1; // v1 – указатель на предыдущую структуру
  struct spis_ *v2; // v2 – указатель на последующую структуру
} spis;
Ошибка та же.
0
ValeryS
Модератор
7448 / 5640 / 716
Регистрация: 14.02.2011
Сообщений: 19,214
Завершенные тесты: 1
13.10.2013, 10:47 4
Цитата Сообщение от jinatar Посмотреть сообщение
Ошибка та же.
попробуй вот так
C
1
2
3
4
5
typedef struct spis_
{char data[20];
 spis_ *v1; // v1 – указатель на предыдущую структуру
 spis_ *v2; // v2 – указатель на последующую структуру
} spis;
у меня нет под рукой Си шного компилятора
только плюсовый
и какой компилятор используешь ты?
все дело в том что Си и плюсы по разному видят структуры
для плюсов нужно писать так
C++
1
2
3
4
5
 struct spis
{char data[20];
 spis *v1; // v1 – указатель на предыдущую структуру
 spis *v2; // v2 – указатель на последующую структуру
};
и в какой строке он дает ошибку?
все дело в том что ошибка звучит так
ошибка: разыменования указателя на неполный тип
может дело не в объявлении а в приведении
0
jinatar
2 / 2 / 0
Регистрация: 07.10.2013
Сообщений: 14
13.10.2013, 11:23  [ТС] 5
пишу в Codeblocks компилю GNU GCC Compiler
ошибка в строке 39 tail->v2=NULL;

Цитата Сообщение от ValeryS Посмотреть сообщение
typedef struct spis_
{char data[20];
spis_ *v1; // v1 – указатель на предыдущую структуру
spis_ *v2; // v2 – указатель на последующую структуру
} spis;
так тоже нечего хорошего, не объявляет.

Цитата Сообщение от ValeryS Посмотреть сообщение
может дело не в объявлении а в приведении
если не в объявление дело...тогда как?
0
VEINHORN
543 / 92 / 49
Регистрация: 16.12.2011
Сообщений: 317
13.10.2013, 18:51 6
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#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;
}
}
0
13.10.2013, 18:51
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.10.2013, 18:51

Работа с двусвязным списком, поиск и перемена местами двух элементов в списке
Здравствуйте! Есть список List http://pastebin.com/tNSztz50 Не могу разобраться, как найти...

Нужны задачки для упражнения в работе со списком, стеком, очередью и двусвязным списком
Недавно научился строить список, стек, очередь, двусвязный список в С++, что бы закрепить навыки...

Программа с двусвязным списком крашится
Здравствуйте! написал код для двусвязного списка, проблема следующая: все компилируется,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru