Форум Микро-Чип
Поиск и заказ электронных компонентов
 

Вернуться   Форум Микро-Чип > Вопросы начинающих

Вопросы начинающих Прежде чем задать вопрос, стоит воспользоваться поиском

Ответ
 
Опции темы Опции просмотра
Старый 22.11.2016, 09:44   #1
Pridnya
Senior Member
 
Регистрация: 21.01.2009
Адрес: Russia, Orel
Возраст: 39
Сообщений: 4,501
Вес репутации: 4370/124
Pridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond repute
По умолчанию Связный список

Здравствуйте!
Потребовалось восполнить пробелы в знаниях - изучить связные списки, они довольно частот используются в относительно сложных программах(LwIP-стек, древовидные меню для символьных дисплеев...).
Есть структура, из таких структур составляем связной список (выделяем память, заполняем поля), затем выводим элементы на печать дважды:
1) печать элементов через массив указателей на элементы (все выводится).
2) печать элементов через обход списка (выводятся все кроме последнего элемента).
Вопрос: как при обходе связного списка перейти на последний элемент?
Код:
typedef struct pbuf{
  struct pbuf *prev;
  struct pbuf *curr;
  struct pbuf *next;
  int a;
}pbuf;

pbuf *bufx;

int main(int argc, char** argv) {
printf("cLinkedList01:\n");

pbuf *buf1 = malloc(sizeof(pbuf));
pbuf *buf2 = malloc(sizeof(pbuf));
pbuf *buf3 = malloc(sizeof(pbuf));

buf1->a = 'A'; buf1->prev = NULL; buf1->curr = buf1; buf1->next = buf2;
buf2->a = 'B'; buf2->prev = buf1; buf2->curr = buf2; buf2->next = buf3;
buf3->a = 'C'; buf3->prev = buf2; buf3->curr = buf3; buf3->next = NULL;    

pbuf *b[]={buf1, buf2, buf3};

printf("\nfor(i=0;i<(sizeof(b)/sizeof(b[0]));i++)\n"); // Выводим на печать.
for(int i=0;i<(sizeof(b)/sizeof(b[0]));i++)
{
    printf("buf->a = %c\n",b[i]->a);
    printf("buf->prev = %x\n",b[i]->prev);
    printf("buf->curr = %x\n",b[i]->curr);
    printf("buf->next = %x\n",b[i]->next);
}

printf("\nfor(bufx=buf1;bufx->next!=NULL;bufx=bufx->next)\n"); // Выводим на печать.
// Обход элементов связного списка.
for(bufx=buf1;bufx->next!=NULL;bufx=bufx->next)
{        
    printf("bufx->a = %c\n",bufx->a);
    printf("bufx->prev = %x\n",bufx->prev);
    printf("bufx->curr = %x\n",bufx->curr);
    printf("bufx->next = %x\n",bufx->next);
}

free(buf1); buf1 = NULL;    
free(buf2); buf2 = NULL;
free(buf3); buf3 = NULL;

return (EXIT_SUCCESS);
}
/*
Результат:
cLinkedList01:

for(i=0;i<(sizeof(b)/sizeof(b[0]));i++)
buf->a = A
buf->prev = 0
buf->curr = 3e2c60
buf->next = 3e2c78
buf->a = B
buf->prev = 3e2c60
buf->curr = 3e2c78
buf->next = 3e2c90
buf->a = C
buf->prev = 3e2c78
buf->curr = 3e2c90
buf->next = 0

for(bufx=buf1;bufx->next!=NULL;bufx=bufx->next)
bufx->a = A
bufx->prev = 0
bufx->curr = 3e2c60
bufx->next = 3e2c78
bufx->a = B
bufx->prev = 3e2c60
bufx->curr = 3e2c78
bufx->next = 3e2c90
*/
__________________
Прогресс неизбежен.
Pridnya вне форума   Ответить с цитированием
Старый 22.11.2016, 09:59   #2
Vanizma
Senior Member
 
Аватар для Vanizma
 
Регистрация: 30.04.2008
Адрес: Pskov
Сообщений: 4,140
Вес репутации: 4450/124
Vanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond repute
Отправить сообщение для Vanizma с помощью ICQ
По умолчанию Re: Связный список

Цитата:
Сообщение от Pridnya Посмотреть сообщение
Здравствуйте!
Потребовалось восполнить пробелы в знаниях - изучить связные списки, они довольно частот используются в относительно сложных программах(LwIP-стек, древовидные меню для символьных дисплеев...).
Есть структура, из таких структур составляем связной список (выделяем память, заполняем поля), затем выводим элементы на печать дважды:
1) печать элементов через массив указателей на элементы (все выводится).
2) печать элементов через обход списка (выводятся все кроме последнего элемента).
Вопрос: как при обходе связного списка перейти на последний элемент?
Код:
typedef struct pbuf{
  struct pbuf *prev;
  struct pbuf *curr;
  struct pbuf *next;
  int a;
}pbuf;

pbuf *bufx;

int main(int argc, char** argv) {
printf("cLinkedList01:\n");

pbuf *buf1 = malloc(sizeof(pbuf));
pbuf *buf2 = malloc(sizeof(pbuf));
pbuf *buf3 = malloc(sizeof(pbuf));

buf1->a = 'A'; buf1->prev = NULL; buf1->curr = buf1; buf1->next = buf2;
buf2->a = 'B'; buf2->prev = buf1; buf2->curr = buf2; buf2->next = buf3;
buf3->a = 'C'; buf3->prev = buf2; buf3->curr = buf3; buf3->next = NULL;    

pbuf *b[]={buf1, buf2, buf3};

printf("\nfor(i=0;i<(sizeof(b)/sizeof(b[0]));i++)\n"); // Выводим на печать.
for(int i=0;i<(sizeof(b)/sizeof(b[0]));i++)
{
    printf("buf->a = %c\n",b[i]->a);
    printf("buf->prev = %x\n",b[i]->prev);
    printf("buf->curr = %x\n",b[i]->curr);
    printf("buf->next = %x\n",b[i]->next);
}

printf("\nfor(bufx=buf1;bufx->next!=NULL;bufx=bufx->next)\n"); // Выводим на печать.
// Обход элементов связного списка.
for(bufx=buf1;bufx->next!=NULL;bufx=bufx->next)
{        
    printf("bufx->a = %c\n",bufx->a);
    printf("bufx->prev = %x\n",bufx->prev);
    printf("bufx->curr = %x\n",bufx->curr);
    printf("bufx->next = %x\n",bufx->next);
}

free(buf1); buf1 = NULL;    
free(buf2); buf2 = NULL;
free(buf3); buf3 = NULL;

return (EXIT_SUCCESS);
}
/*
Результат:
cLinkedList01:

for(i=0;i<(sizeof(b)/sizeof(b[0]));i++)
buf->a = A
buf->prev = 0
buf->curr = 3e2c60
buf->next = 3e2c78
buf->a = B
buf->prev = 3e2c60
buf->curr = 3e2c78
buf->next = 3e2c90
buf->a = C
buf->prev = 3e2c78
buf->curr = 3e2c90
buf->next = 0

for(bufx=buf1;bufx->next!=NULL;bufx=bufx->next)
bufx->a = A
bufx->prev = 0
bufx->curr = 3e2c60
bufx->next = 3e2c78
bufx->a = B
bufx->prev = 3e2c60
bufx->curr = 3e2c78
bufx->next = 3e2c90
*/
может
Код:
for(bufx=buf1;bufx->next!=NULL;bufx=bufx->next)
заменить на curr?
А то получается, в цикле - проверяешь что next не равно NULL, выводишь curr, после чего bufx = next. И снова проверяешь следующий next, а не curr

или я чего-то не понял во всей этой каше
__________________

Vanizma вне форума   Ответить с цитированием
Старый 22.11.2016, 10:06   #3
Pridnya
Senior Member
 
Регистрация: 21.01.2009
Адрес: Russia, Orel
Возраст: 39
Сообщений: 4,501
Вес репутации: 4370/124
Pridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond repute
По умолчанию Re: Связный список

Цитата:
Сообщение от Vanizma Посмотреть сообщение
может
Код:
for(bufx=buf1;bufx->next!=NULL;bufx=bufx->next)
заменить на curr?
А то получается, в цикле - проверяешь что next не равно NULL, выводишь curr, после чего bufx = next. И снова проверяешь следующий next, а не curr

или я чего-то не понял во всей этой каше
Нет, так при запуске программы появляется ошибка от системы.
Кому "каша", а кому "высокий уровень абстрактного мышления".
Цитаты принято сокращать. Это даже в правилах форума написано.
Уже хорошо, значит я не один такой. Давайте, товарищи, подключайтесь, тема интересная.
Код для консольного приложения на Си (у меня IDE NetBeans 8.02, компилятор MinGW)
Миниатюры
Ошибка.PNG  
__________________
Прогресс неизбежен.
Pridnya вне форума   Ответить с цитированием
Старый 22.11.2016, 10:12   #4
Vanizma
Senior Member
 
Аватар для Vanizma
 
Регистрация: 30.04.2008
Адрес: Pskov
Сообщений: 4,140
Вес репутации: 4450/124
Vanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond repute
Отправить сообщение для Vanizma с помощью ICQ
По умолчанию Re: Связный список

Цитата:
Сообщение от Pridnya Посмотреть сообщение
Нет, так при запуске программы появляется ошибка от системы.
Кому "каша", а кому "высокий уровень абстрактного мышления".
Цитаты принято сокращать. Это даже в правилах форума написано.
Уже хорошо, значит я не один такой. Давайте, товарищи, подключайтесь, тема интересная.
Код для консольного приложения на Си (у меня IDE NetBeans 8.02, компилятор MinGW)
если ты просто заменил, то и будет исключение вылетать, т.к. в цикле
Код:
for(bufx=buf1;bufx->next!=NULL;bufx=bufx->next)
{        
    printf("bufx->a = %c\n",bufx->a);
    printf("bufx->prev = %x\n",bufx->prev);
    printf("bufx->curr = %x\n",bufx->curr);
    printf("bufx->next = %x\n",bufx->next);
}
в последнем проходе bufx->next == NULL, а ты его пытаешься вывести.
надо внутри проверку для next на !=NULL еще вводить, если используется

..хотя prev выводится и NULL...
Но цикл должен работать как я написал, в принципе. Присвоение нового bufx в конце, а вначале проверка. И когда 3-й присвоит в конце второго, то условие bufx->next!=NULL будет ложь и из цикла выкинет

ps каша - потому что и код и результат в одном коде вывел - сразу и не поймешь, то ли скобок нет, то ли еще чего-то
__________________


Последний раз редактировалось Vanizma; 22.11.2016 в 10:18.
Vanizma вне форума   Ответить с цитированием
Старый 22.11.2016, 10:14   #5
Рак
Senior Member
 
Регистрация: 02.04.2008
Адрес: Кременчуг
Возраст: 32
Сообщений: 1,320
Вес репутации: 2246/74
Рак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond repute
По умолчанию Re: Связный список

Дима, а так как есть не работает?
Вроде все правильно в цикле написано.

Вкурил что спрашивал.

в цикле условие проверки должно быть bufx != NULL .
и поле curr из структуры можно выкинуть.

Последний раз редактировалось Рак; 22.11.2016 в 10:22.
Рак вне форума   Ответить с цитированием
Старый 22.11.2016, 11:12   #6
Pridnya
Senior Member
 
Регистрация: 21.01.2009
Адрес: Russia, Orel
Возраст: 39
Сообщений: 4,501
Вес репутации: 4370/124
Pridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond reputePridnya has a reputation beyond repute
По умолчанию Re: Связный список

Цитата:
Сообщение от Vanizma Посмотреть сообщение
ps каша - потому что и код и результат в одном коде вывел - сразу и не поймешь, то ли скобок нет, то ли еще чего-то
Копируем код в Notepad++ и сохраняем как файл на языке Си, там и комментарии цветные и подсветка синтаксиса есть. В браузере не удобно. Согласен.
Цитата:
Сообщение от Рак Посмотреть сообщение
в цикле условие проверки должно быть bufx != NULL .
и поле curr из структуры можно выкинуть.
Попрошу не выражаться (про вкурил), великий и могучий русский язык не для того создан.
Да, так правильно. bufx != NULL Спасибо! A поле curr я добавил для контроля (для себя).
Код:
for(bufx=buf1;bufx!=NULL;bufx=bufx->next)
{        
    printf("bufx->a = %c\n",bufx->a);
    printf("bufx->prev = %x\n",bufx->prev);
    printf("bufx->curr = %x\n",bufx->curr);
    printf("bufx->next = %x\n",bufx->next);
}
/*
bufx->a = A
bufx->prev = 0
bufx->curr = 3e2c60
bufx->next = 3e2c78
bufx->a = B
bufx->prev = 3e2c60
bufx->curr = 3e2c78
bufx->next = 3e2c90
bufx->a = C
bufx->prev = 3e2c78
bufx->curr = 3e2c90
bufx->next = 0
*/
__________________
Прогресс неизбежен.

Последний раз редактировалось Pridnya; 22.11.2016 в 11:18.
Pridnya вне форума   Ответить с цитированием
Старый 22.11.2016, 11:21   #7
pal1222@yandex.ru
Senior Member
 
Регистрация: 30.09.2008
Сообщений: 1,465
Вес репутации: 2482/75
pal1222@yandex.ru has a reputation beyond reputepal1222@yandex.ru has a reputation beyond reputepal1222@yandex.ru has a reputation beyond reputepal1222@yandex.ru has a reputation beyond reputepal1222@yandex.ru has a reputation beyond reputepal1222@yandex.ru has a reputation beyond reputepal1222@yandex.ru has a reputation beyond reputepal1222@yandex.ru has a reputation beyond reputepal1222@yandex.ru has a reputation beyond reputepal1222@yandex.ru has a reputation beyond reputepal1222@yandex.ru has a reputation beyond repute
По умолчанию Re: Связный список

Цитата:
Сообщение от Pridnya Посмотреть сообщение
Копируем код в Notepad++ и сохраняем как файл на языке Си, там и комментарии цветные и подсветка синтаксиса есть. В браузере не удобно. Согласен.

Попрошу не выражаться (про вкурил), великий и могучий русский язык не для того создан.
Да, так правильно. bufx != NULL Спасибо! A поле curr я добавил для контроля (для себя).
Код:
for(bufx=buf1;bufx!=NULL;bufx=bufx->next)
{        
    printf("bufx->a = %c\n",bufx->a);
    printf("bufx->prev = %x\n",bufx->prev);
    printf("bufx->curr = %x\n",bufx->curr);
    printf("bufx->next = %x\n",bufx->next);
}
/*
bufx->a = A
bufx->prev = 0
bufx->curr = 3e2c60
bufx->next = 3e2c78
bufx->a = B
bufx->prev = 3e2c60
bufx->curr = 3e2c78
bufx->next = 3e2c90
bufx->a = C
bufx->prev = 3e2c78
bufx->curr = 3e2c90
bufx->next = 0
*/
А ещё имея "curr", free() может оказаться проще вызывать...
pal1222@yandex.ru вне форума   Ответить с цитированием
Старый 22.11.2016, 12:21   #8
Рак
Senior Member
 
Регистрация: 02.04.2008
Адрес: Кременчуг
Возраст: 32
Сообщений: 1,320
Вес репутации: 2246/74
Рак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond repute
По умолчанию Re: Связный список

Цитата:
Сообщение от pal1222@yandex.ru Посмотреть сообщение
А ещё имея "curr", free() может оказаться проще вызывать...
Согласен, но быстро удалить получится ценой лишнего поля в структуре и его обслуживания. Кому что...
Рак вне форума   Ответить с цитированием
Старый 22.11.2016, 14:08   #9
IceS
Super Moderator
 
Регистрация: 01.03.2007
Адрес: St. Petersburg
Возраст: 39
Сообщений: 3,251
Вес репутации: 3684/111
IceS has a reputation beyond reputeIceS has a reputation beyond reputeIceS has a reputation beyond reputeIceS has a reputation beyond reputeIceS has a reputation beyond reputeIceS has a reputation beyond reputeIceS has a reputation beyond reputeIceS has a reputation beyond reputeIceS has a reputation beyond reputeIceS has a reputation beyond reputeIceS has a reputation beyond repute
Отправить сообщение для IceS с помощью ICQ
По умолчанию Re: Связный список

Цитата:
Сообщение от Pridnya Посмотреть сообщение
Вопрос: как при обходе связного списка перейти на последний элемент?
Самый простой вариант - перебором, начиная с первого элемента.
Второй сложнее:
1. заводим переменную где храним указатель на последний элемент.
2. заводим 2 функции - добавление элемента в список и удаление элемента из списка. Все действия по удалению/добавлению проводим только через них (иначе пойдут глюки). А они уже следят за целостностью списка и подставляют/удаляют указатели на первый и последний элементы списка.

PS 2й пункт удобно реализуется через классы :-).
__________________
- Готово, мастер !!!
- Что готово ???
- Сломал ...
IceS вне форума   Ответить с цитированием
Старый 22.11.2016, 15:06   #10
Рак
Senior Member
 
Регистрация: 02.04.2008
Адрес: Кременчуг
Возраст: 32
Сообщений: 1,320
Вес репутации: 2246/74
Рак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond repute
По умолчанию Re: Связный список

Цитата:
Сообщение от IceS Посмотреть сообщение
Самый простой вариант - перебором, начиная с первого элемента.
Второй сложнее:
1. заводим переменную где храним указатель на последний элемент.
2. заводим 2 функции - добавление элемента в список и удаление элемента из списка. Все действия по удалению/добавлению проводим только через них (иначе пойдут глюки). А они уже следят за целостностью списка и подставляют/удаляют указатели на первый и последний элементы списка.

PS 2й пункт удобно реализуется через классы :-).
У него немного другая ситуация, из цикла вываливался раньше, чем доходил до последнего элемента.
Рак вне форума   Ответить с цитированием
Ответ


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Четырехсвязный список, ХС8: как бороться с варнингами и иже lisergin Вопросы начинающих 5 15.03.2015 11:44
Список идентификаторов в шине CAN у Ford'a Sergey K Вопросы начинающих 4 26.02.2015 23:52
Список PIC чипов pickit2 + mplab picpicpic Продукция MICROCHIP 16 01.03.2013 23:27
древовидный список функций в MPLAB InDepth Вопросы начинающих 4 21.12.2011 10:50
Может у кого-нибудь есть список команд PIC16F877 zuze Вопросы начинающих 5 25.09.2008 11:05


Часовой пояс GMT +3, время: 16:05.


Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd. Перевод: zCarot