2012-02-13 14 views
10

Ho un infinito vitale per il ciclo che consente a un sensore di continuare ad aggiornare i suoi valori. Tuttavia vorrei rompere quello per ciclo quando un altro sensore introduce nuovi valori. Come posso passare da un ciclo infinito a un altro?Come rompere un infinito per il ciclo (;;) in C?

codice attuale:

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

    } 

Quello che vorrei aggiungere:

Se Sensor2 restituisce una lettura (ad esempio Sensor2 > 20), allora voglio spezzare il ciclo e goto un'altra infinita ciclo for per iniziare una nuova funzione.

+1

Si prega di non chiudere questa domanda, gente. E, in futuro, se hai di nuovo questo tipo di situazione, segnala l'attenzione del moderatore. Preferiamo cercare di salvare una situazione piuttosto che riproporre le domande. – Will

risposta

27

Se cercate "commutazione tra 2 cicli infiniti" potrebbe essere "avvolto" di terzo ciclo e questa "commutazione" potrebbe essere effettuata con il semplice break.

Ma dal momento che si desidera che il programma per smettere un giorno, questo ciclo potrebbe essere collocato all'interno della funzione e si potrebbe utilizzare return; per porvi fine:

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

E da qualche parte basta chiamare:

myMagicLoop(); 

Spero che questo aiuti.

+0

Puoi per favore espandere l'idea alla base del reso per questo esempio? Puoi implementare un codice di esempio rapido ?? Non riesco a farlo funzionare. – NLed

+0

@Fendi: ho aggiornato la mia risposta. Dovrebbe essere perfettamente chiaro ora. – LihO

+0

Grazie! L'istruzione 'dovrei smettere 'se l'istruzione restituisse un valore, questo valore può essere usato per terminare il ciclo o usato in altre istruzioni if? – NLed

4

Il comando "interruzione" dovrebbe fare ciò che ti serve?

5

È possibile utilizzare break; per interrompere un loop e passare il controllo oltre la parentesi di chiusura. Ad esempio

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

per passare da una spira A e B. ciclo

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

    } 

    // Loop B 
    for (;;) 
    { 

     if WANT_TO_SWITCH 
     { 
      break; 
     } 

    } 
} 
4

In alternativa, è possibile prendere in considerazione la possibilità di riscriverlo con un approccio basato sugli eventi. Ciò dipenderà ovviamente da cosa è capace il tuo hardware, ma per lo meno dovresti essere in grado di produrre alcuni eventi del timer.

Quindi il codice sarebbe andato qualcosa di simile:

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

(Prima di commentare le variabili volatili, prega nota che volatile è quello di evitare che le ottimizzazioni del compilatore pericolosi e non per servire come alcuni mutex barriera di protezione/accesso atomico/memoria ecc)

+0

Questo è utile grazie :) Mi piace come è stata usata la funzione case qui – NLed

+0

upvote per un approccio diverso dall'interruzione;) – Beatles1692

2

il modo migliore per farlo è quello di modificare l'istruzione for a qualcosa di simile:

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

In alternativa si può cambiare da un for ad una dichiarazione while:

while (Sensor2 <= 20) { 
... 

Se questo non mai stato così facile si può sempre usare un break invece.

2

Un'altra opzione potrebbe essere l'uso di segnali (SIGUSR1, SIGUSR2) per passare da un loop all'altro. Qualcosa di questo tipo:

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); 
    ... 
} 
+0

È simile all'utilizzo di un semaforo? – NLed

Problemi correlati