Как прервать бесконечный цикл for(;;) в C?

У меня есть жизненно важный бесконечный цикл, который позволяет датчику постоянно обновлять свои значения. Однако я хотел бы прервать этот цикл, когда другой датчик вводит новые значения. Как я могу переключиться с одного бесконечного цикла на другой?

Текущий код:

for(;;){

    SON_Start();
    // Wait 65ms for max range time
    delay10ms(7);
    // Read Range
    i = SON_Read(SON_ADDRESSES[sonarReading]);
    // pause
    delayMs(100);
        if(i<15)
        drive(200, RadCW);

    }

Что я хотел бы добавить:

Если Sensor2 возвращает чтение (например, Sensor2 > 20), затем я хочу разорвать цикл и перейти к другому бесконечному циклу for, чтобы начать новую функцию.

7 ответов

Решение

Если вы ищете "переключение между 2 бесконечными циклами", его можно "обернуть" третьим циклом, а это "переключение" можно сделать простым break,

Но так как вы хотите, чтобы ваша программа когда-нибудь остановилась, этот цикл можно поместить в функцию, и вы можете использовать return; для прекращения этого:

void myMagicLoop()
{
    for(;;)
    {
        for(;;)
        {
            if ( I should stop )
                return;

            if ( I should switch to second loop )
                break;
        }
        for(;;)
        {
            if ( I should stop )
                return;

            if ( I should switch back to first loop)
                break;
        }
    }
}

И где-то вы просто позвоните:

myMagicLoop();

Надеюсь это поможет.

Это переключит между петлей A и B.

for (;;)
{
    // Loop  A
    for (;;)
    {
        if WANT_TO_SWITCH
        {
            break;
        }

    }

    // Loop  B
    for (;;)
    {

        if WANT_TO_SWITCH
        {
            break;
        }

    }
}

Ты используешь break; разорвать петлю и передать контроль за ее закрывающей скобкой. Например

for(;;) {
   if( whatever ) {
      break;
   }
}
//break gets you here

В качестве альтернативы вы могли бы рассмотреть возможность переписать это с помощью подхода, управляемого событиями. Это, конечно, будет зависеть от того, на что способно ваше оборудование, но, по крайней мере, вы должны быть в состоянии генерировать некоторые события таймера.

Тогда код будет выглядеть примерно так:

static volatile bool sensor_1_ready;
static volatile bool sensor_2_ready;

for(;;)
{
  switch(state_machine)
  {
    case READING_SENSOR_1:
      if(sensor_2_ready)
      {
        state_machine = READING_SENSOR_2;
      }
      else if(sensor_1_ready)
      {
        process sensor 1
      }
      break;

    case READING_SENSOR_2:

      if(!sensor_2_ready && some_timeout_etc)
      {
        state_machine = READING_SENSOR_1;
      }
      else if(sensor_2_ready)
      {
        process sensor 2
      }
      break;
  }
}

void callback_sensor_1 (void)  // some sort of interrupt or callback function
{
  sensor_1_ready = true;
}

void callback_sensor_2 (void)  // some sort of interrupt or callback function
{
  sensor_2_ready = true;
}

(Прежде чем комментировать переменные volatile, обратите внимание, что volatile существует для предотвращения опасных оптимизаций компилятора, а не для защиты мьютекса / атомарного доступа / барьера памяти и т. Д.)

Команда "break" должна делать то, что вам нужно?

Другим вариантом может быть использование сигналов (SIGUSR1,SIGUSR2) для переключения с одной петли на другую. Что-то в этом роде:

void sensor2(int signum)
{
   for (; ;)
      ...
      /* Need to process sensor 1 now */
      kill(pid, SIGUSR1);
}

void sensor1(int signum)
{
    for (; ;)
      ...
      /* Need to process sensor 2 now */
      kill(pid, SIGUSR2);
}


int main()
{
   /* register the signal handlers */
   signal(SIGUSR1,  sensor1);
   signal(SIGUSR2,  sensor2);
   ...
}

Лучший способ сделать это - изменить for Скажите что-то вроде:

for (; Sensor2 <= 20;) {
...

В качестве альтернативы вы можете изменить его с for к while заявление:

while (Sensor2 <= 20) {
...

Если это не соответствует вашим потребностям, вы всегда можете использовать break вместо.

Другие вопросы по тегам