Проверить, возвращает ли какая-либо из внутренностей цикла 1, и удерживать ее, пока весь цикл снова не станет 0.

array loop

Я новичок в этом, поэтому, пожалуйста, не ругайте меня.

У меня есть функция, которая проверяет, находится ли запись в многоуровневом массиве в определенном диапазоне. Используя цикл FOR, я проверяю весь массив с помощью этой функции, которая дает мне значение true/false для каждой записи.

А теперь проблема: Мне нужно проверить, возвращает ли ЛЮБАЯ запись в этом цикле значение true, и удерживать его до тех пор, пока каждый результат этого цикла снова не станет ложным.

Есть советы?

Большое спасибо.

Это мой цикл for:

  for(int i = 0; i < arrayTop; i++){
for(int j = 0; j < arrayDay; j++){
  for(int k = 0; k < arrayTime; k++){
    timeCompare(timeArray[i][j][k][0], timeArray[i][j][k][1], timeArray[i][j][k][2], timeArray[i][j][k][3], timeArray[i][j][k][4], timeArray[i][j][k][5], timeArray[i][j][k][6]);

    //Serial.print(i);Serial.print(j);Serial.print(k);Serial.print(" ");
    Serial.println(compareVar);
    
    if(i == 0){
      

      //установить переключатель воды
      if(compareVar == 1){
        waterOn = 1;
        Serial.println("Water ON");
        
        goto bailout;
      }
      else {
        waterOn = 0;
        Serial.println("water OFF");
      }
    }
    else if(i == 1){

      // устанавливаем выключатель света
      if(compareVar == 1){
        lightOn = 1;
        Serial.println("Light ON");
        goto bailout;
      }
      else {
        lightOn = 0;
        Serial.println("light OFF");            
      }
    }
  }
} 

} спасение:

и это вызываемая функция:

//time compare with ON/OFF switch
int timeCompare(int hrOn, int minOn, int secOn, int hrOff, int minOff, int secOff, int timerSwitch){
  unsigned long int onTime = (hrOn*10000UL) + (minOn*100UL) + secOn;
  unsigned long int offTime = (hrOff*10000UL) + (minOff*100UL) + secOff;
  unsigned long int currentTime = (dt.hour*10000UL) + (dt.minute*100UL) + dt.second;




  if(timerSwitch == 1){
    if(onTime < currentTime && offTime > currentTime){
      compareVar = 1;
    }
    else {
      compareVar = 0;
    }
  }
 else if(timerSwitch == 0) {
    compareVar = 0;
  }
  

  //Serial.print("compare: "); Serial.println(compareVar);



  
}

, 👍1

Обсуждение

Я не понимаю, что именно ты пытаешься сделать. Я думаю, было бы полезно, если бы вы показали нам код, который у вас уже есть. Что значит "держать"?, @chrisl

Извините, я знаю, что это сбивает с толку :-) Я добавил соответствующие части кода, так как все это уже довольно длинно. Под удержанием я подразумеваю, что мне нужно знать, есть ли 1 где-либо в цикле, но пока он просто сообщает мне, есть ли 1 в одной записи, а затем устанавливает ее в 0 со следующей записью. Мне нужно сохранить 1, пока есть 1 где-нибудь в полном цикле., @Martin Keller II.


1 ответ


Лучший ответ:

0

Во-первых, не следует использовать глобальную переменную для получения результата функции сравнения. Это только путаница и ненужный сложный код. Для этого у нас есть возвращаемые значения. Поэтому вместо того, чтобы устанавливать переменную compareVar внутри функции timeCompare(), вы должны просто вернуть соответствующее значение. В функции timeCompare() заменить

compareVar = 1;

с

return 1;

и

compareVar = 0;

с

return 0;

Тогда в вашем основном коде: как я понял, вам нужен только compareVar в циклах for, чтобы вы могли удалить глобально определенный compareVar и объявить его непосредственно перед для циклов:

int compareVar = 0;

Теперь мы можем проделать фокус. Мы хотим пройти через наши циклы for и получить результат 1, если для любого из элементов timeCompare() возвращает 1. Для этого мы просто выполняем операцию ИЛИ:

compareVar = compareVar || timeCompare(timeArray[i][j][k][0], timeArray[i][j][k][1], timeArray[i][j][k][2], timeArray[i][j][k][3], timeArray[i][j][k][4], timeArray[i][j][k][5], timeArray[i][j][k][6]);

Это логическое ИЛИ ||. В C++ ноль рассматривается как false, а любое другое число рассматривается как true. Мы начинаем с compareVar с нуля. Когда timeCompare() для элемента также возвращает ноль, он остается нулевым. Если он возвращает 1, compareVar станет равным 1. Если он снова вернет 1, он останется единицей. Если он возвращает ноль, он останется нулевым.

Теперь вы можете проверить compareVar после цикла for. Будет 1, если какой-либо из элементов дал вам 1.

Аналогичным образом вы можете проверить, все ли элементы возвращают 1, если вы замените OR || операцией AND &&.


Наконец, я настоятельно рекомендую вам не использовать goto. Он игнорирует некоторые важные принципы, и с его помощью можно легко создать очень плохой код. Обратитесь к таким вопросам, как этот, чтобы узнать больше об этом. Я бы сказал, что в каждом случае у вас есть лучшие способы, чем goto. Здесь кажется, что вы просто хотите выйти из обеих петель. Я бы упаковал эти циклы в функцию, чтобы вы могли просто использовать оператор return, чтобы выйти из них.

,

С другой стороны: я использую goto именно в этой (и *только*) ситуации - вырваться из гнезда циклов. Я просто делаю супер очевидным, что я это делаю, зачем и где. В частности, у меня всегда есть (хотя он мне редко нужен) #define PUNT goto punt, а ярлык punt: легко заметить...., @JRobert

... Это выполняет две вещи: мой код на самом деле не говорит "goto" (поэтому пуристов не так легко обидеть, хотя я сочувствую их аргументам); и во-вторых, если бы я попытался прыгать в своем коде, используя это, или создать еще один вложенный цикл с выходом, мои метки конфликтовали бы (несколько определений) и предотвращали бы это. В любом случае, это дает мне понять, что мне нужно переосмыслить свою структуру кодирования и найти лучший способ., @JRobert