Выполнить однократное (однократное) выполнение в бесконечном цикле или пустом цикле?

Dec 12 2020

Я хочу создать синтаксис однократного или однократного выполнения внутри цикла forever (цикл void) для любых языков программирования.

Я нашел решение, сделав новую логическую переменную «выполненной» и установив значение true после выполнения.

Это нормально, но что, если я хочу выполнить однократное выполнение с другим синтаксисом? Должен ли я снова сделать новую переменную логической? Это будет неэффективно. Представьте, что существует много синтаксиса, но я должен создать новый bool executiin для каждого синтаксиса.

Решение - это функция, я думаю

Например

void loop()
{
lcd.print("OK");
}

ЭТО БУДЕТ ПЕЧАТАТЬ НАВСЕГДА Я хочу, чтобы они работали так

void loop()
{
once(lcd.print("OK"));
}

так что "once" - это функция со строкой параметров, которая используется для команды / синтаксиса.

один раз ("команда")

Ответы

1 Paul Dec 12 2020 at 13:28

Несколько способов подойти к этому

Ниже приводится очень распространенный способ выполнения такой операции. Как вы уже предположили, с глобальным логическим значением :

bool once = true; // global variable
void loop() {
  if (once) { // being called only once
    lcd.print("OK");
    once = false;
  }
}

Сделайте что-нибудь только один раз через определенное время :

void loop() {
  // millis() is the time in milliseconds after the startup 
  //if you want to print something once after a specific amount of time
  //this also includes a little "wait time" of 100 milliseconds as the statement might be asked with a delay
  if (mills() >= 1000 && mills() <= 1100) {// time in milliseconds
    lcd.print("OK");
  }
}

И благодаря этому потоку при выходе из цикла (возможно, это не то, что вы ищете):

void loop() {
  lcd.print("OK");
  exit(0);  //The 0 is required to prevent compile error.
}

Но я полагаю, вы пытаетесь создать какой-то интерфейс, в котором печатается конкретный ответ относительно пользовательского ввода (возможно, много возможностей) ?! В этом случае это зависит от того, какие входные данные вы получаете:

В случае целых чисел :

void loop() {
  switch (input) { //input must be an integer
    case 0:
      lcd.print("OK"); //prints "ok" if input is 0
    case 1:
      lcd.print("Hello"); //prints "Hello" if input is 1
  }
}

В случае Stings / chars вам нужно использовать цикл if для каждого возможного ввода (или с массивом Strings / chars):

void loop() {
  lcd.print("Turn off?"); //asks if it should do something
  if (input == "yes") { //String input
    lcd.print("OK, shut down!");
    //do something
  }
  else if (input == 'n' || input == 'N') { //char input
    lcd.print("OK, no shut down!");
    //do something
  }
}

Функция, которую вы ищете, где конкретный ответ печатает только ОДИН РАЗ относительно ввода, может быть просто заархивирована циклами if / else . Если строка должна быть напечатана только один раз при запуске, распечатайте ее в конструкторе «setup ()». В противном случае просто с глобальными логическими значениями возможно что-то подобное.

Обратите внимание, что это только мои предложения, основанные на моем опыте, но это не обязательно означает, что другие решения недоступны. Надеюсь, что это еще поможет :)

1 AyxanHaqverdili Dec 12 2020 at 13:12

Вот один из способов сделать это:

void loop()
{
    { // execute once. Can put this in a separate function also
        static bool executed = (lcd.print("OK"), true);
    }
}

Вам гарантируется, что эта переменная инициализируется один раз.

Если вам нужен onceсинтаксис в вашем вопросе, вы можете добиться чего-то подобного с помощью макроса:

#define ONCE(...) \
{\
 static bool executed = ([&]{__VA_ARGS__;}(), true); \
}


void loop()
{
    ONCE(lcd.print("OK"))
}
1 Jarod42 Dec 12 2020 at 15:32

В С ++ есть std::call_onceдаже multi_thread, тогда вы можете сделать это в общем случае:

template <typename F>
void simple_do_once(F f)
{
    static std::once_flag flag;
    std::call_once(flag, f);
}

Поскольку лямбда имеет уникальный тип, у вас есть один флаг по лямбде:

Демо