Двусвязный список
- Войдите на сайт для отправки комментариев
Пнд, 21/03/2022 - 00:00
Скажу сразу я с С или С++ не знаком. Вот код, я тут пытался сделать менюшку через двусвязный список
// пины энкодера #define CLK 4 // s2 #define DT 3 // s1 #define SW 2 // key #include "GyverEncoder.h" Encoder enc1(CLK, DT, SW); // для работы c кнопкой class MenuItem { public: void (*handler)(); String _name; MenuItem* sub; MenuItem* parent; MenuItem* back; MenuItem* next; MenuItem(String Name, void (*Handler)()) { handler = Handler; _name = Name; sub = NULL; parent = NULL; back = NULL; next = NULL; } void Invoke() { (*handler)(); } }; class MenuManager { private: // MenuItem* first; public: MenuItem* current; MenuManager() { current = NULL; } void Append(MenuItem* item) { if (current != NULL) { Serial.println("1. "+ item->_name + " "+ current->_name); current->next = item; } item->back = current; current = item; Serial.println("3. "+ item->_name + " "+ current->_name); } void AddSub(MenuItem* item) { if (current != NULL) { current->parent = item; } current->sub = item; current = item; }; MenuItem* Next() { if (current->next != NULL) { current = current->next; } return current; }; MenuItem* Back() { if (current->back != NULL) { current = current->back; } return current; }; }; MenuManager mm; void setup() { Serial.begin(9600); enc1.setType(TYPE1); mm = MenuManager(); mm.Append(&MenuItem("First", &test)); Serial.println("2. "+mm.current->_name); mm.Append(&MenuItem("Second", &test2)); } void loop() { enc1.tick(); MenuItem* item = NULL; // if (enc1.isRight()) { // Serial.println("isRigh"); // item = mm.Next(); // } // if (enc1.isLeft()) { // Serial.println("isLeft"); // item = mm.Back(); // } // // if (item != NULL) { // Serial.println(mm.current->_name); // } // // if (item != ) { // // //Serial.println(item->_name); // // item->Invoke(); // } else { // Serial.println("fdfdfdfdfffffffffffff"); // } } // Обработчики void test() { Serial.println("test"); } void test2() { Serial.println("test2"); }
вот результат из консоли
3. First First
2. PSI R
1. Second Second
3. Second Second
какая-то чушь.
Я ожидал увидеть вот такой результат
3. First First
2. First
1. First First
3. Second Second
как под пунктом 1 может в current быть Second если этот принт выводится до переприсваевания current и что за 2. PSI R такое?
Не усложняй себе жизнь. Массива тут хватит за глаза.
не хватит, я хочу ветвистое меню. Ну и потом тут уже интерес разыгрался
Списки это для создания объектов с изначально не известным количеством в КУЧЕ.
Вы же делаете что то невнятное с очевидным результатом !
как под пунктом 1 может в current быть Second если этот принт выводится до переприсваевания current
044 строка - условие проверьте ! Код выполняется всегда так как вы его написали !!!
Скажу сразу я с С или С++ не знаком
Не с того вы начали знакомство с С или С++ !!!
Было дело, мастырил заготовку меню, да так и не применил. Использовал библиотеку Qlist, чтобы не заморачиваться с динамическими массивами вручную, в расчете в промышленной версии переделать по уму. Публикую в расчете на конструктивную критику.
Без PROGMEM накладных расходов много.
нет у меня цели изучать С или С++, мне нужно скетч написать, я бы рад его не писать на С или С++.
"Списки это для создания объектов с изначально не известным количеством в КУЧЕ."
Тут вы не правы
нет, оно не всегда выполняется, обратите внимание на конструктор и на пример вывода который я предоставил
"Списки это для создания объектов с изначально не известным количеством в КУЧЕ."
Тут вы не правы
А в чем он не прав? Что количество неизвестно? Или что в КУЧЕ?
Без PROGMEM накладных расходов много.
PROGMEM я планировал использовать, пока я хочу сделать навигацию по меню
нет у меня цели изучать С или С++, мне нужно скетч написать, я бы рад его не писать на С или С++.
тогда вам в платный раздел - там пишут для всех. и для тех кто не знает С++ - тоже.
если же пишете сами - без изучения языка ничего не выйдет.
"Списки это для создания объектов с изначально не известным количеством в КУЧЕ."
Тут вы не правы
А в чем он не прав? Что количество неизвестно? Или что в КУЧЕ?
я так понял что он пишет якобы списки тут неуместны, с этим я не согласен. Да и про кучу не совсем понял речь про кучу как структура данных, если так то и в куче кол-во объектов никто не регламентирует, там так же может быть неизвестное количество
А с PROGMEM уже прожект MicroMenu имеется. Можно его взять за основу.
тогда вам в платный раздел - там пишут для всех. и для тех кто не знает С++ - тоже.
если же пишете сами - без изучения языка ничего не выйдет.
у меня конкретный вопрос, зачем не по теме разводить холивар. Вопрос я задал в первом сообщении. Возможно есть особенности какие-то, вот я про них и хочу узнать
Без PROGMEM накладных расходов много.
Если это мне, то да, я это понимаю. В финальном варианте будет оптимизация. Правда с у четом того, что я использую ЕСП-шки нужно будет в каждом конкретном проекте смотреть, что нужно оптимизировать - ПЗУ или ОЗУ.
Вопрос я задал в первом сообщении.
Я не вижу там конкретного вопроса. Потому и ответы такие.
Было дело, мастырил заготовку меню, да так и не применил. Использовал библиотеку Qlist, чтобы не заморачиваться с динамическими массивами вручную, в расчете в промышленной версии переделать по уму. Публикую в расчете на конструктивную критику.
спасибо за код. Попробую.
Вопрос я задал в первом сообщении.
Я не вижу там конкретного вопроса. Потому и ответы такие.
конкретный вопрос таков:
почему вывод отличается от ожидаемого, что я делаю не так
delete
ArtemLaz ну так пройди свой код по шагам и поймешь почему 1 second
после выхода из setup - элементы MenuItem гарантированно существуют только в вашем больном воображении !!! Изучите время жизни переменных.
Смысла обсуждать полный бреда код не вижу !
ArtemLaz ну так пройди свой код по шагам и поймешь почему 1 second
после выхода из setup - элементы MenuItem гарантированно существуют только в вашем больном воображении !!!
Я не понимаю, я вас чем-то обидел? Что значит "в вашем больном воображении", общайтесь пожалуйста достойно. Так же прошу внимательнее ознакомиться со скетчем, вы второй раз отвечаете не впопад. Там есть глобальная переменная
Смысла обсуждать полный бреда код не вижу !
не обсуждайте, тем более у вас не выходит
Там есть глобальная переменная
глобальная переменная - это указатель на класс. Она никуда не девается, да. А сам класс, созданный в setup() - после выхода из сетапа не существует.
Попытки написать что-либо сложнее блинк, не читая учебник по С++ - имхо, обречены на провал.
mm глобальная, а MenuItem ? Чему равны MenuItem после выхода из setup ? Вы уверены что эта область памяти по прежнему принадлежит MenuItem ?
В первом проходе Append - current равен NULL и сразу попадаем на 49 50 52 вывод 3 ...
delete
mm глобальная, а MenuItem ? Чему равны MenuItem после выхода из setup ? Вы уверены что эта область памяти по прежнему принадлежит MenuItem ?
В первом проходе current равен NULL и сразу попадаем на вывод 3 ...
mm глобальная переменная, я ожидал, что в ней будет сохранена ссылка (в current) на тот объект который я передал, или это не так работает?
смотрите, строка 84, добавил item, 85 строка уже выдает ерунду, почему? Я ожидал что там будет "First"
что бы объект гарантированно существовал его надо создать в КУЧЕ через new - тогда он будет существовать пока вы его сами не удалите через delete
с порядком вывода - так и не дошло что ли ? я на чукотском не умею доносить !
смотрите, строка 84, добавил item, 85 строка уже выдает ерунду, почему? Я ожидал что там будет "First"
84 - пройдите по шагам переход в Append !!! (именно в Append ошибка)
что бы объект гарантированно существовал его надо создать в КУЧЕ через new - тогда он будет существовать пока вы его сами не удалите через delete
с порядком вывода - так и не дошло что ли ? я на чукотском не умею доносить !
мммм, вот уже дельные советы пошли
смотрите, строка 84, добавил item, 85 строка уже выдает ерунду, почему? Я ожидал что там будет "First"
84 - пройдите по шагам переход в Append !!! (именно в Append ошибка)
не понимаю в чем ошибка, ну ткните носом, не вижу я где ошибка. в 50й строке item присваевается current в 51й строке корректно выводится корректно, а в 85 уже не корректно.
ПС
насчет "по шагам" ну в ардуинке нет отладчика
смотрите, строка 84, добавил item, 85 строка уже выдает ерунду, почему? Я ожидал что там будет "First"
84 - пройдите по шагам переход в Append !!! (именно в Append ошибка)
вот в том то и дело, что вы думаете что MenuItem("First") существует - он создался для вызова Append и после выхода из Append - эта память уже используется для вызова следующей функции и что эта функция туда положила никому не известно - вот вы и видите ХЗ что в выводе - хорошо вообще serial.print не подвис ...
блиин с new все заработало, Komandir вот за это спасибо. С аппендом все ок
все, можно закрывать тему, работает и навигация как я и ожидал. И да, ребят будьте добрее, ответ мог быть таков "ты не верно создал экземпляр класса, надо использовать new", а вы тут развели непонятно что.
А вот теперь расскажите нам зачем на Arduino динамическое меню ?
Вангую следующий холивар из-за нехватки памяти и/или пересечения кучи со стеком !!!
С аппендом все ок
это временно. Чуть побольше напишешь - аппенд так же посыпется. как до того меню
Вангую следующий холивар из-за нехватки памяти и/или пересечения кучи со стеком !!!
однозначно. В классе с динамическими переменными обязательно должен быть явный деструктор. иначе будет утечка памяти. А так как это пишет ТС - с неявным созданием экземпляров в вызове Апппенд и тому подобное - утечка у него будет колоссальная
b707 явный деструктор - для того кому не нужно знание C и С++ это же как корове седло
не хватит, я хочу ветвистое меню.
вообще никак не связано
Не усложняй себе жизнь. Массива тут хватит за глаза.
С ветвистостью которой каждый Алень позавидует.
...думал, что про ветвистость и Аленя только я анекдот знаю, наивный был )))
не хватит, я хочу ветвистое меню.
вообще никак не связано
тут можно подискутировать что из этого есть "усложнение жизни", связанные списки (односвязные/двусвязные) прекрасно ложатся на эту задачу. Вот как изящно создаются пункты меню
не думаю что с массивами так же было бы
Вот как изящно создаются пункты меню
не думаю что с массивами так же было бы
лучше покажите. как вы их так же изящно удаляете по окончании работы...
Вот как изящно создаются пункты меню
не думаю что с массивами так же было бы
лучше покажите. как вы их так же изящно удаляете по окончании работы...
что удаляю?
Строка в 147 символов
"изящно"
уж не позорился бы
Строка в 147 символов
"изящно"
уж не позорился бы
Ну представь на суд свое решение с массивом, только без хардкода, что б ккол-во уровней меню можно было удобно задавать, спорю что не выйдет. Насчет 147 символов, никто не мешает написать разными строками, в этом и есть изящность.
Это изящно для больших машин, где ОЗУ дохера . А здесь ОЗУ маловато, и есть много флеш, которое не ОЗУ.
Ну это как подогреватель сиденья у автомобиля. Но если этот подогреватель зафигачить на седушку велика, то будет уже не очень. На велике и так жопа в мыле, не зачем там подогреватель.
пс:#298
Вот как изящно создаются пункты меню
лучше покажите. как вы их так же изящно удаляете по окончании работы...
что удаляю?
пункты меню. Каждая команда new должна сопровождаться соответвующим delete, программа этого сама не делает. А так, как вы пишете - будут утечки на каждой строчке. Так даже на ПК с его гигами памяти непозволительно писать, что уж говорить о ардуине. где озу жалкие крохи.