2012-02-13 28 views
10

我有一個重要的無限循環,允許傳感器不斷更新其值。然而,當另一個傳感器帶來新的價值時,我想打破這個循環。我如何從一個無限循環切換到另一個循環?如何在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),那麼我想打破循環和GOTO另一無限的循環開始一個新的功能。

+1

請不要關閉這個問題,鄉親們。而且,如果你將來再次出現這種情況,請注意主持人。我們寧願試圖挽救一個情況,而不是轉發問題。 – Will 2012-02-13 13:45:40

回答

27

之間切換這個「切換」可以通過簡單的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(); 

希望這有助於。

+0

您能否擴展這個例子的return後面的想法?你可以實現一個簡單的示例代碼?我只是無法得到它的工作。 – NLed 2012-02-13 11:37:37

+0

@Fendi:我已經更新了我的答案。現在應該很清楚了。 – LihO 2012-02-13 11:42:03

+0

謝謝! '我應該停止'如果語句會返回一個值,這個值可以用來終止循環或用在其他if語句中? – NLed 2012-02-13 11:45:17

5

您使用break;來打破一個循環並將控制權傳遞到其大括號之外。例如

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

如果您正在尋找「2個無限循環切換」它可以被「包裝」的第三循環,這將環路A和B.循環

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

    } 

    // Loop B 
    for (;;) 
    { 

     if WANT_TO_SWITCH 
     { 
      break; 
     } 

    } 
} 
4

或者你可以考慮用事件驅動的方法來重寫。這當然取決於你的硬件的能力,但至少你應該能夠產生一些計時器事件。

然後代碼會去是這樣的:

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變量之前,注意,揮發,以防止有危險的編譯器優化和擔任一些互斥後衛/原子訪問/內存屏障等)

+0

多數民衆贊成有幫助謝謝:)我喜歡這裏使用的情況下功能如何 – NLed 2012-02-13 16:46:44

+0

upvote for一個不同的方法比休息;) – Beatles1692 2012-02-18 23:00:27

2

要做到這一點,最好的辦法是將for聲明更改爲類似:

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

或者您可以將其從for更改爲while聲明:

while (Sensor2 <= 20) { 
... 

如果不適合你的需求,你可以隨時使用break代替。

2

另一種選擇是使用信號(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); 
    ... 
} 
+0

這是類似於使用信號量? – NLed 2012-02-18 23:38:05