У меня есть следующий код, который выглядит не очень красиво. Какие методы я мог бы использовать, чтобы сделать его лучше? Представьте, что есть много операторов IF ELSE. В качестве примера, я хотел бы различать, является ли левое меньше или больше, чем правое. Добавляются и другие расстояния. (Речь идет о роботе, который должен обнаруживать препятствия перед собой.)
distance1 = left_LOX.distance();
distance2 = middle_LOX.distance();
distance3 = right_LOX.distance();
if (distance1 < 100 || distance2 < 100 || distance3 < 100)
distance_case = 1;
else if (distance1 < 300 || distance2 < 300 || distance3 < 300)
distance_case = 2;
else
distance_case = 3;
// Abfragen für die Automatik
switch (distance_case)
{
case 1:
target = 0;
robot.Stop();
delay(2000);
break;
case 2:
target = 4000;
robot.Forward();
break;
case 3:
target = 6000;
robot.Forward();
break;
}
Идея о том, как сделать это лучше, была бы хороша.
@ 463035818_is_not_a_number Для меня это не похоже на C.
то, что "хорошо" или "лучше" или то, что вы считаете "выглядеть лучше", является чисто субъективным. Я думаю, что код выглядит нормально
Для 3 переменных это прекрасно. Для большего я бы рассмотрел массив и std::any_of
И для многих я бы рассмотрел возможность сортировки расстояний (или, возможно, объединения в диапазоны расстояний), чтобы было легче быстро определить, находятся ли они в определенных диапазонах.
Не устраняет большую часть «уродливого» кода, но удаляет if-else, если это то, что вы хотите: distance_case=(distance1<300 || distance2<300 || distance3<300) ? ((distance1<100 || distance2<100 || distance3<100) ? 1 : 2) : 3
@Alexsen: if-else все еще существуют в виде ?
и :
, и этот код менее читаем. Так что ты выиграл?
@YvesDaoust Синтаксис вложенности if-else был удален. Даже я упомянул, что уродство не было удалено. Он просто сжат, если-иначе.
@Alexsen: нет, синтаксис вложения все еще существует через скобки.
@Alexsen Это можно упростить (начиная с С++ 11) с помощью дополнительной переменной mindist = std::min({distance1, distance2, distance3}); distance_case = mindist < 300? ((mindist < 100) ? 1 : 2) : 3;
@YvesDaoust может быть личным предпочтением, но я предпочитаю синтаксис ? x : y
пирамидам if-else.
@Peter Питер На самом деле это гораздо лучше, я бы даже подумал над ответом, если хочешь записать это.
Я прошу прощения за неправильное понимание моих тегов. Это esp32. И esp32 поддерживает C и C++, верно?
Здесь именно переключатель кажется излишним. std::min({distance1, distance2, distance3})
может храниться в переменной для упрощения условий.
Вы можете добавить, если это выглядит лучше для вас.
distance_case = (distance1 < 100 || distance2 < 100 || distance3 < 100) +
(distance1 < 300 || distance2 < 300 || distance3 < 300) +
(distance1 >= 300 || distance2 >= 300 || distance3 >= 300);
Вы даже можете пропустить первую часть и использовать 1+(>=100)+(>=300)
вы можете использовать блок if ... else if ... else
напрямую, если distance_case
не используется в течение длительного времени. Он излишне вводит новые переменные, которые не имеют смысла. Или определите enum
, если вы видите, что в долгосрочной перспективе таких случаев будет много. Читатель также может быстро разобраться в значениях.
Это скорее комментарий, а не ответ
Итак, вы решили злоупотребить системой, потому что вам не хватает репутации. Просто пишите больше реальных ответов и получайте репутацию. Это ограничение не просто так. никогда не используйте ответы в качестве комментариев здесь. я
dmin= min(left_LOX.distance(), middle_LOX.distance(), right_LOX.distance());
if (dmin < 100)
{
target = 0;
robot.Stop();
delay(2000);
}
else if (dmin < 300)
{
target = 4000;
robot.Forward();
}
else
{
target = 6000;
robot.Forward();
}
Если у вас много расстояний (сотни, тысячи), то проще сначала сгруппировать все расстояния в контейнер типа вектор, а потом использовать стандартные алгоритмы. Например. что-то вроде этого: Это предполагает, что у вас есть стандартная библиотека С++, доступная на используемой вами платформе/компиляторе esp32 — это должно быть возможно, по крайней мере, до С++ 11 — см., например. https://medium.com/geekculture/modern-c-with-esp32-dcd3918dd978.
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
// Just an example vector initialisation - replace this with the required x_Lox.distance() calls.
std::vector<int> distances = {300, 500, 500, 200, 100 };
const auto min = *std::min_element(distances.begin(), distances.end());
std::cout << "Min distance: " << min;
return 0;
}
Как только у вас будет минимальное расстояние, вы можете просмотреть различные случаи для обработки. Это основано на предположении, что вас интересует только кратчайшее расстояние для выбора действия вашего робота. Если у вас более сложная логика, код также становится более сложным.
Вы разыменовываете std::min
, это опечатка?
@FabiosaysReinstateMonica да, спасибо! - Очевидно, я хотел использовать std::min_element, потому что сравнение итераторов по размеру довольно бесполезно ;-)
Это выглядит хорошо. Вы знаете, может ли esp32 обрабатывать векторы?
Если у вас более сложная логика, код также становится более сложным. К сожалению, я должен это сделать.
@Teebow Чтобы помочь с логикой, которая более сложна, чем основанная на текущем минимальном расстоянии, нам нужно увидеть примеры этой логики. Нет «общего» ответа, например. некоторые из них могут быть основаны на размещении расстояний в ведрах - сколько расстояний меньше 300, сколько дальше 600 и т. д. Похоже, среда программирования esp32 должна обеспечивать доступ к современному C++.
@JorisTimmermans хорошо, я вижу. К сожалению, я пока не могу привести пример более сложных инструкций. Но ваш ответ мне уже очень помог, я думаю. Я посмотрю на это поближе.
@Teebow - в библиотеке std::algorithm может быть много интересного, что вы можете сделать с контейнером расстояний. Или даже контейнер объектов, который включает в себя расстояния и другие вещи, необходимые для вашей логики. Есть минимум и максимум, поиск предикатов, фильтрация, преобразование...
@Teebow, если вы считаете, что этот или любой другой ответ достаточно решил вашу проблему, не могли бы вы принять его?
@JorisTimmermans Извините, я забыл об этом.
С или С++? Выбери один