Как прервать бесконечный цикл 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 существует для предотвращения опасных оптимизаций компилятора, а не для защиты мьютекса / атомарного доступа / барьера памяти и т. Д.)
Другим вариантом может быть использование сигналов (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
вместо.