Fazer uma execução única (uma vez) em loop eterno ou loop vazio?

Dec 12 2020

Eu quero fazer uma vez ou uma sintaxe de execução dentro do loop para sempre (loop void) para qualquer linguagem de programa.

O que eu encontrei a solução é tornar a nova variável boolean "executada" e definida como verdadeira após executada.

Tudo bem, mas e se eu quiser fazer uma vez a execução para outra sintaxe? Devo tornar a nova variável booleana novamente? Não será eficiente. Imagine que haja muitas sintaxes, mas devo fazer uma nova execução de bool para cada sintaxe.

A solução é função, eu acho

Por exemplo

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

ISTO SERÁ IMPRIMIDO PARA SEMPRE Desejo que funcione assim

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

então "uma vez" é uma função com string de parâmetro que é para comando / sintaxe.

uma vez ("comando")

Respostas

1 Paul Dec 12 2020 at 13:28

Várias maneiras de abordar isso

A seguir está uma maneira muito comum de como essa operação é feita normalmente. Como você já sugeriu, com um booleano global :

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

Faça algo apenas uma vez após um tempo específico :

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");
  }
}

E graças a este tópico, com a saída do loop (pode não ser o que você está procurando):

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

Mas suponho que você esteja tentando fazer algum tipo de interface, onde uma resposta específica é impressa em relação à entrada do usuário (provavelmente muitas possibilidades) ?! Nesse caso, depende de quais informações você está recebendo:

No caso de inteiros :

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
  }
}

No caso de Stings / chars , você precisa ir com um "loop if" em todas as entradas possíveis (ou com uma matriz de 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
  }
}

Uma função que você está procurando, em que uma resposta específica só é impressa UMA VEZ em relação a uma entrada, pode ser arquivada por loops if / else . Se uma String deve ser impressa apenas uma vez na inicialização, imprima-a no construtor "setup ()". Caso contrário, apenas com booleanos globais algo assim é possível.

Observe que essas são apenas minhas sugestões com base em minha experiência, mas isso não significa necessariamente que outras soluções não estejam disponíveis. Espero que ainda ajude :)

1 AyxanHaqverdili Dec 12 2020 at 13:12

Aqui está uma maneira de fazer isso:

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

Você tem a garantia de que essa variável é inicializada uma vez.

Se quiser a oncesintaxe em sua pergunta, você pode conseguir algo semelhante com uma macro:

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


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

Em C ++, existe std::call_oncemesmo multi_thread, então você pode fazer isso genericamente:

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

Como lambda tem um tipo único, você tem um sinalizador por lambda:

Demo