Форум программистов, компьютерный форум CyberForum.ru

Связные списки - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.73
Dady
2 / 2 / 0
Регистрация: 20.03.2012
Сообщений: 53
23.06.2012, 17:27     Связные списки #1
Друзья, помогите исправить код!!! Программа описывет таблицу о книгах.(Название, автор, стоимость). Почему он поддчеркивает head, next, prev?

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
typedef struct tag_lib { 
char title[100]; 
char author[100]; 
int value; 
} LIB;
 
/*Структура, которая описывает связи между строками таблицы, и представляет собой объект данных.
Здесь *prev и *next – указатели на предыдущую и следующую строки соответственно.*/
/////////////////////////////////////////////////////////
typedef struct tag_obj { 
LIB lib; 
typedef struct tag_obj* prev, *next; 
} OBJ;
 
///////////////////////////////////////////////////////
OBJ* add_obj(char* title, char* author, int value)//функция использует три параметра для ввода данных в структуру LIB.
{                                              
 OBJ* current = (OBJ *)malloc(sizeof(OBJ));//создается новая структура типа OBJ.
 strcpy(current->lib.title, title); //запись информации в структуру LIB
 strcpy(current->lib.author, author); //запись информации в структуру LIB
 current->lib.value = value; //запись информации в структуру LIB
 current->prev = tail;//инициализируются указатель prev добавленного объекта
 //prev указывает на предыдущий объект, т.е. равен указателю tail.
 current->next = NULL;//инициализируются указатель next добавленного объекта 
 //добавление осуществляется в конец списка, то указатель next должен быть равен NULL
 if(tail != NULL) tail->next = current; 
 /*объект, на который указывает указатель tail, становится предпоследним и его 
 указатель next должен указывать на последний объект, т.е. быть равным указателю current.*/
 if(head == NULL) head = current; 
 /*Затем проверяется, является ли добавляемый объект первым (head == NULL), 
 и если это так, то указатель head приравнивается указателю current */
 tail = current;//указатель tail инициализируется на последний объект
 return current;//возвращает указатель на созданный объект
}
 
///////////////////////////////////////////////////////
OBJ* del_obj(OBJ* current)//функция удаления элемента.
{ //del_obj() в качестве аргумента использует указатель на объект, который следует удалить.
 if(current == head) 
//Сначала выполняется проверка для инициализации указателя head, в том случае, 
//если удаляется первый объект, на который он указывает.
if(current->prev != NULL) head = current->prev; 
 else head = current->next; 
 if(current == tail) //Аналогичная проверка осуществляется для tail.
if(current->next != NULL) tail = current->next; 
 else tail = current->prev; 
 if(current->prev != NULL) 
//проверка: если предыдущий объект относительно текущего существует, 
//то его указатель на следующий объект следует переместить.
current->prev->next = current->next; 
 if(current->next != NULL) 
//Аналогичная проверка выполняется и для следующего объекта относительно удаляемого.
current->next->prev = current->prev; 
 free(current);//удаления объекта из памяти 
return head;//возвращается указатель на первый объект.
}
 
////////////////////////////////////////////////////
int main() 
{ 
 OBJ *current = NULL; 
 int value; 
 char title[100], author[100]; 
 do 
 { 
 printf("Введите название книги: "); 
 scanf("%s",title); 
 printf("Введите автора: "); 
 scanf("%s",author); 
 printf("Введите стоимость: "); 
 scanf("%d",&value); 
 current = add_obj(title,author,value);//формирует связанный список на основе введенных данных.
 printf("Для выхода введите 'q'"); 
 } while(scanf("%d",&value) == 1); 
 current = head; //указатель current передвигается на первый объект
 while(current != NULL) 
 { 
 printf("Title: %s, author %s, value = %d\n", 
 current->lib.title, current->author.old, current->lib.value); 
 current = current->next; 
 } 
 while(head != NULL) 
 del_obj(head); 
 return 0; 
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.06.2012, 17:27     Связные списки
Посмотрите здесь:

Связные списки C++
C++ Связные списки
C++ Связные списки
Связные списки C++
C++ Связные списки.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9371 / 5421 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
23.06.2012, 19:13     Связные списки #2
Цитата Сообщение от Dady Посмотреть сообщение
typedef struct tag_obj* prev, *next;
отсюда typedef уберите - ни к чему оно там.
Dady
2 / 2 / 0
Регистрация: 20.03.2012
Сообщений: 53
23.06.2012, 19:43  [ТС]     Связные списки #3
Цитата Сообщение от easybudda Посмотреть сообщение
отсюда typedef уберите - ни к чему оно там.
Спасибо большое, помогло, ошибок меньше стало. Но компилятор ругается на tail и head, что можно сделать? Помогите, пожалуйста!

Добавлено через 4 минуты
Я добавил строчку
C++
1
OBJ* head = NULL, *tail = NULL;
и ошибок меньше стало. НО появилась такая ошибка: error C2228: выражение слева от ".old" должно представлять класс, структуру или объединение Вот в этой строчке:
C++
1
current->lib.title, current->author.old, current->lib.value);
Добавлено через 20 минут
Всё исправил, сейчас всё работает, но как изменить главную часть кода чтобы можно было вводить несколько книг? Вот код:

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
typedef struct tag_lib { 
char title[100]; 
char author[100]; 
int value;
int old;
} LIB;
 
/*Структура, которая описывает связи между строками таблицы, и представляет собой объект данных.
Здесь *prev и *next – указатели на предыдущую и следующую строки соответственно.*/
/////////////////////////////////////////////////////////
typedef struct tag_obj { 
LIB lib; 
struct tag_obj* prev, *next; 
} OBJ;
OBJ* head = NULL, *tail = NULL;
 
///////////////////////////////////////////////////////
OBJ* add_obj(char* title, char* author, int value)//функция использует три параметра для ввода данных в структуру LIB.
{                                              
 OBJ* current = (OBJ *)malloc(sizeof(OBJ));//создается новая структура типа OBJ.
 strcpy(current->lib.title, title); //запись информации в структуру LIB
 strcpy(current->lib.author, author); //запись информации в структуру LIB
 current->lib.value = value; //запись информации в структуру LIB
 current->prev = tail;//инициализируются указатель prev добавленного объекта
 //prev указывает на предыдущий объект, т.е. равен указателю tail.
 current->next = NULL;//инициализируются указатель next добавленного объекта 
 //добавление осуществляется в конец списка, то указатель next должен быть равен NULL
 if(tail != NULL) tail->next = current; 
 /*объект, на который указывает указатель tail, становится предпоследним и его 
 указатель next должен указывать на последний объект, т.е. быть равным указателю current.*/
 if(head == NULL) head = current; 
 /*Затем проверяется, является ли добавляемый объект первым (head == NULL), 
 и если это так, то указатель head приравнивается указателю current */
 tail = current;//указатель tail инициализируется на последний объект
 return current;//возвращает указатель на созданный объект
}
 
///////////////////////////////////////////////////////
OBJ* del_obj(OBJ* current)//функция удаления элемента.
{ //del_obj() в качестве аргумента использует указатель на объект, который следует удалить.
 if(current == head) 
//Сначала выполняется проверка для инициализации указателя head, в том случае, 
//если удаляется первый объект, на который он указывает.
if(current->prev != NULL) head = current->prev; 
 else head = current->next; 
 if(current == tail) //Аналогичная проверка осуществляется для tail.
if(current->next != NULL) tail = current->next; 
 else tail = current->prev; 
 if(current->prev != NULL) 
//проверка: если предыдущий объект относительно текущего существует, 
//то его указатель на следующий объект следует переместить.
current->prev->next = current->next; 
 if(current->next != NULL) 
//Аналогичная проверка выполняется и для следующего объекта относительно удаляемого.
current->next->prev = current->prev; 
 free(current);//удаления объекта из памяти 
return head;//возвращается указатель на первый объект.
}
 
////////////////////////////////////////////////////
int main() 
{ setlocale(LC_ALL,"Russian");
 OBJ *current = NULL; 
 int value; 
 char title[100], author[100]; 
 do 
 { 
 printf("Введите название книги: "); 
 scanf("%s",title); 
 printf("Введите автора: "); 
 scanf("%s",author); 
 printf("Введите стоимость: "); 
 scanf("%d",&value); 
 current = add_obj(title,author,value);//формирует связанный список на основе введенных данных.
 printf("Для выхода введите 'q'"); 
 } while(scanf("%d",&value) == 1); 
 current = head; //указатель current передвигается на первый объект
 while(current != NULL) 
 { 
 printf("Title: %s, author %s, value = %d\n", 
 current->lib.title, current->lib.author, current->lib.value); 
 current = current->next; 
 } 
 while(head != NULL) 
 del_obj(head);
 getchar();
 getchar();
 return 0; 
}
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9371 / 5421 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
23.06.2012, 19:49     Связные списки #4
Цитата Сообщение от Dady Посмотреть сообщение
current->prev = tail;//инициализируются указатель prev добавленного объекта
Это tail вообще откуда должно браться? Компилятор на это строку говорит:
Код
error: 'tail' undeclared (first use in this function)
Тоже относится к head в
Цитата Сообщение от Dady Посмотреть сообщение
if(current == head)
и дальше... Попробую угадать - эти head и tail изначально глобальными переменными были? Что-то я их объявления нигде не разглядел...

Цитата Сообщение от Dady Посмотреть сообщение
current->lib.title, current->author.old, current->lib.value);
Код
'struct tag_obj' has no member named 'author'

Не по теме:

Цитата Сообщение от Dady Посмотреть сообщение
помогло, ошибок меньше стало
"... Он послушал их через трубочку и им стало чуточку легче. Он поставил им градусники и им стало ещё легче. Он дал им по большому яблоку и они совсем выздоровели!" (с)

Dady
2 / 2 / 0
Регистрация: 20.03.2012
Сообщений: 53
23.06.2012, 19:59  [ТС]     Связные списки #5
Всё исправил, сейчас всё работает, но как изменить главную часть кода чтобы можно было вводить несколько книг? Вот код:

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
typedef struct tag_lib { 
char title[100]; 
char author[100]; 
int value;
int old;
} LIB;
 
/*Структура, которая описывает связи между строками таблицы, и представляет собой объект данных.
Здесь *prev и *next – указатели на предыдущую и следующую строки соответственно.*/
/////////////////////////////////////////////////////////
typedef struct tag_obj { 
LIB lib; 
struct tag_obj* prev, *next; 
} OBJ;
OBJ* head = NULL, *tail = NULL;
 
///////////////////////////////////////////////////////
OBJ* add_obj(char* title, char* author, int value)//функция использует три параметра для ввода данных в структуру LIB.
{                                              
 OBJ* current = (OBJ *)malloc(sizeof(OBJ));//создается новая структура типа OBJ.
 strcpy(current->lib.title, title); //запись информации в структуру LIB
 strcpy(current->lib.author, author); //запись информации в структуру LIB
 current->lib.value = value; //запись информации в структуру LIB
 current->prev = tail;//инициализируются указатель prev добавленного объекта
 //prev указывает на предыдущий объект, т.е. равен указателю tail.
 current->next = NULL;//инициализируются указатель next добавленного объекта 
 //добавление осуществляется в конец списка, то указатель next должен быть равен NULL
 if(tail != NULL) tail->next = current; 
 /*объект, на который указывает указатель tail, становится предпоследним и его 
 указатель next должен указывать на последний объект, т.е. быть равным указателю current.*/
 if(head == NULL) head = current; 
 /*Затем проверяется, является ли добавляемый объект первым (head == NULL), 
 и если это так, то указатель head приравнивается указателю current */
 tail = current;//указатель tail инициализируется на последний объект
 return current;//возвращает указатель на созданный объект
}
 
///////////////////////////////////////////////////////
OBJ* del_obj(OBJ* current)//функция удаления элемента.
{ //del_obj() в качестве аргумента использует указатель на объект, который следует удалить.
 if(current == head) 
//Сначала выполняется проверка для инициализации указателя head, в том случае, 
//если удаляется первый объект, на который он указывает.
if(current->prev != NULL) head = current->prev; 
 else head = current->next; 
 if(current == tail) //Аналогичная проверка осуществляется для tail.
if(current->next != NULL) tail = current->next; 
 else tail = current->prev; 
 if(current->prev != NULL) 
//проверка: если предыдущий объект относительно текущего существует, 
//то его указатель на следующий объект следует переместить.
current->prev->next = current->next; 
 if(current->next != NULL) 
//Аналогичная проверка выполняется и для следующего объекта относительно удаляемого.
current->next->prev = current->prev; 
 free(current);//удаления объекта из памяти 
return head;//возвращается указатель на первый объект.
}
 
////////////////////////////////////////////////////
int main() 
{ setlocale(LC_ALL,"Russian");
 OBJ *current = NULL; 
 int value; 
 char title[100], author[100]; 
 do 
 { 
 printf("Введите название книги: "); 
 scanf("%s",title); 
 printf("Введите автора: "); 
 scanf("%s",author); 
 printf("Введите стоимость: "); 
 scanf("%d",&value); 
 current = add_obj(title,author,value);//формирует связанный список на основе введенных данных.
 printf("Для выхода введите 'q'"); 
 } while(scanf("%d",&value) == 1); 
 current = head; //указатель current передвигается на первый объект
 while(current != NULL) 
 { 
 printf("Title: %s, author %s, value = %d\n", 
 current->lib.title, current->lib.author, current->lib.value); 
 current = current->next; 
 } 
 while(head != NULL) 
 del_obj(head);
 system("Pause"); 
 return 0; 
}
Yandex
Объявления
23.06.2012, 19:59     Связные списки
Ответ Создать тему
Опции темы

Текущее время: 12:36. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru