2012-02-13 41 views
10

Tôi có vòng lặp vô hạn quan trọng cho phép cảm biến tiếp tục cập nhật các giá trị của nó. Tuy nhiên tôi muốn phá vỡ vòng lặp đó khi một cảm biến khác mang lại các giá trị mới. Làm thế nào tôi có thể chuyển từ một vô hạn cho vòng lặp khác?Làm thế nào để phá vỡ một vòng lặp vô hạn cho (;;) trong C?

đang hiện tại:

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

    } 

Những gì tôi muốn nói thêm:

Nếu Sensor2 trả về một đọc (ví dụ Sensor2 > 20), sau đó tôi muốn phá vỡ các vòng lặp và goto khác vô hạn vòng lặp for để bắt đầu một chức năng mới.

+1

Vui lòng không đóng câu hỏi này, mọi người. Và, trong tương lai, nếu bạn có loại tình huống này một lần nữa, hãy gắn cờ cho sự chú ý của người điều tiết. Chúng tôi muốn thử và cứu vãn một tình huống hơn là trả lời các câu hỏi. – Will

Trả lời

27

Nếu bạn đang tìm kiếm "chuyển đổi giữa 2 vòng lặp vô hạn" nó có thể được "bao bọc" bởi vòng lặp thứ ba và "chuyển đổi" này có thể được thực hiện bằng cách đơn giản break.

Nhưng kể từ khi bạn muốn chương trình của bạn để ngăn chặn một ngày nào đó, vòng lặp này có thể được đặt trong các chức năng và bạn có thể sử dụng return; cho kết thúc nó:

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

Và ở đâu đó bạn chỉ cần gọi:

myMagicLoop(); 

Hy vọng điều này sẽ hữu ích.

+0

Bạn có thể mở rộng ý tưởng đằng sau lợi nhuận cho ví dụ này không? Bạn có thể triển khai mã ví dụ nhanh không ?? Tôi không thể làm cho nó hoạt động được. – NLed

+0

@Fendi: Tôi đã cập nhật câu trả lời của mình. Nên hoàn toàn rõ ràng ngay bây giờ. – LihO

+0

Cảm ơn bạn! Câu lệnh 'Tôi nên dừng' nếu trả về một giá trị, giá trị này có thể được sử dụng để chấm dứt vòng lặp hoặc được sử dụng trong các câu lệnh if khác? – NLed

4

Lệnh "ngắt" phải làm những gì bạn cần?

5

Bạn sử dụng break; để ngắt vòng lặp và vượt qua kiểm soát ngoài cú đúp đóng của nó. Ví dụ

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

này sẽ chuyển đổi giữa các vòng A và vòng lặp B.

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

    } 

    // Loop B 
    for (;;) 
    { 

     if WANT_TO_SWITCH 
     { 
      break; 
     } 

    } 
} 
4

Hoặc bạn có thể cân nhắc viết lại điều này bằng cách tiếp cận theo hướng sự kiện. Điều này tất nhiên sẽ phụ thuộc vào những gì phần cứng của bạn có khả năng, nhưng ít nhất bạn sẽ có thể sản xuất một số sự kiện hẹn giờ.

Sau đó, mã sẽ đi một cái gì đó như thế này:

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

(Trước khi cho ý kiến ​​về các biến không ổn định, xin lưu ý rằng không ổn định ở đó để ngăn chặn tối ưu hóa trình biên dịch nguy hiểm và không để phục vụ như một số mutex bảo vệ/truy cập nguyên tử/rào cản bộ nhớ, vv)

+0

Thats hữu ích cảm ơn bạn :) Tôi thích cách chức năng trường hợp được sử dụng ở đây – NLed

+0

upvote cho một cách tiếp cận khác hơn là phá vỡ;) – Beatles1692

2

Cách tốt nhất để làm điều đó là thay đổi tuyên bố for thành một cái gì đó như:

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

Hoặc bạn có thể thay đổi nó từ một for một tuyên bố while:

while (Sensor2 <= 20) { 
... 

Nếu điều đó không phù hợp với nhu cầu của bạn, bạn luôn có thể sử dụng một break để thay thế.

2

Một tùy chọn khác có thể là sử dụng tín hiệu (SIGUSR1, SIGUSR2) để chuyển từ vòng lặp này sang vòng lặp khác. Thứ gì đó thuộc loại này:

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

Điều này tương tự như sử dụng một semaphore? – NLed

Các vấn đề liên quan