Czy jednorazowe (jednorazowe) wykonanie w pętli wiecznej lub pustej pętli?

Dec 12 2020

Chcę, aby składnia wykonania raz lub raz wewnątrz pętli wiecznej (pętla pusta) dla dowolnego języka programu.

To, co znalazłem rozwiązaniem, to make new zmienna boolean "wykonana" i ustawiona na true po wykonaniu.

W porządku, ale co jeśli chcę zrobić raz wykonanie do innej składni? Czy powinienem ponownie utworzyć nową zmienną jako wartość logiczną? To nie będzie skuteczne. Wyobraź sobie, że istnieje wiele składni, ale dla każdej składni muszę utworzyć nowe polecenie bool.

Myślę, że rozwiązaniem jest funkcja

Na przykład

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

TO BĘDZIE DRUKOWANE NA ZAWSZE. Chciałbym, żeby działały w ten sposób

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

więc „raz” jest funkcją z łańcuchem parametrów, który służy do polecenia / składni.

raz („polecenie”)

Odpowiedzi

1 Paul Dec 12 2020 at 13:28

Kilka sposobów rozwiązania tego problemu

Poniżej przedstawiono bardzo powszechny sposób wykonywania takiej operacji. Jak już zasugerowałeś, z globalną wartością logiczną :

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

Zrób coś tylko raz po określonym czasie :

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

A dzięki temu wątkowi, z wyjściem z pętli (może nie być tym, czego szukasz):

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

Ale przypuszczam, że próbujesz stworzyć jakiś interfejs, w którym wypisywana jest konkretna odpowiedź dotycząca danych wejściowych użytkownika (prawdopodobnie wiele możliwości) ?! W takim przypadku zależy to od tego, jakie dane wejściowe otrzymujesz:

W przypadku liczb całkowitych :

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

W przypadku Stings / chars , musisz przejść z "if loop" przez każde możliwe wejście (lub z tablicą 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
  }
}

Funkcja, której szukasz, w której konkretna odpowiedź jest drukowana tylko RAZ w odniesieniu do wejścia, może być po prostu zarchiwizowana przez pętle if / else . Jeśli String powinien być wydrukowany tylko raz przy starcie, wypisz go w konstruktorze "setup ()". W przeciwnym razie tylko z globalnymi wartościami logicznymi coś takiego jest możliwe.

Zwróć uwagę, że są to tylko moje sugestie oparte na moim doświadczeniu, ale niekoniecznie oznacza to, że inne rozwiązania nie są dostępne. Mam nadzieję, że to nadal pomaga :)

1 AyxanHaqverdili Dec 12 2020 at 13:12

Oto jeden sposób, w jaki możesz to zrobić:

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

Masz gwarancję, że ta zmienna zostanie zainicjowana raz.

Jeśli chcesz mieć onceskładnię w swoim pytaniu, możesz osiągnąć coś podobnego za pomocą makra:

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


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

W C ++ std::call_oncejest nawet multi_thread, możesz to zrobić ogólnie:

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

Ponieważ lambda ma unikalny typ, masz jedną flagę według lambda:

Próbny