2010-05-07 58 views
8

Tôi vừa mới bắt đầu sử dụng C++ nhưng có một số kiến ​​thức trước đó về các ngôn ngữ khác (vb một thời gian trở lại không may), nhưng có một tình huống khó khăn kỳ lạ. Tôi không thích sử dụng rất nhiều câu lệnh IF và muốn sử dụng các chuyển đổi/trường hợp vì nó có vẻ sạch sẽ hơn, và tôi muốn được tập luyện .. Nhưng ..Lệnh chuyển đổi nâng cao trong vòng lặp while?

Cho phép nói rằng tôi có kịch bản sau đây (mã lý thuyết):

while(1) { 

    //Loop can be conditional or 1, I use it alot, for example in my game 
    char something; 
    std::cout << "Enter something\n -->"; 
    std::cin >> something; 

    //Switch to read "something" 
    switch(something) { 
    case 'a': 
     cout << "You entered A, which is correct"; 
     break; 
    case 'b': 
     cout << "..."; 
     break; 
    } 
} 

Và đó là vấn đề của tôi. Cho phép nói rằng tôi muốn thoát khỏi vòng lặp WHILE, Nó sẽ yêu cầu hai câu lệnh ngắt?

Điều này rõ ràng trông sai:

case 'a': 
    cout << "You entered A, which is correct"; 
    break; 
    break; 

Vì vậy, tôi chỉ có thể làm một tuyên bố NẾU trên 'a' để sử dụng phá vỡ ;? Tôi có thiếu một cái gì đó thực sự đơn giản?

Điều này sẽ giải quyết được nhiều vấn đề của tôi hiện tại của tôi.

+3

Dựa trên tiêu đề, tôi nghĩ đây có thể là câu hỏi về Thiết bị của Duff. Không. Có một thẻ 'nhàm chán' cho điều đó không? –

+0

Vui mừng khi câu hỏi của bạn được giải quyết, những điều này không phải là thú vị nhất. –

Trả lời

13

Bạn có thể chỉ cần kiểm tra vòng lặp while để biết giá trị bool được đặt trong một trong các báo cáo trường hợp của bạn.

+1

Tôi muốn nói câu trả lời này phần nào là tối ưu (nhưng không phải theo bất kỳ cách nào sai). Nếu mã được thêm vào dưới câu lệnh chuyển, nó sẽ được chạy ngay cả khi vấn đề là thoát trực tiếp vòng ngoài. Tôi đã sử dụng Dimas nếu (thực hiện) nghỉ; phương pháp, hoặc một goto. –

+0

Yea là một cạm bẫy của giải pháp này, mã đang được thực hiện theo chuyển đổi đó. Đồng ý ở đó. – Robb

+0

funny Tôi luôn luôn sử dụng trong khi (chạy) – kenny

5

Có, C và C++ không có cách nào để nói "thoát nhiều khối có thể ngắt" (trong đó "khối có thể ngắt" là bất kỳ vòng lặp hoặc nút chuyển nào). Cách giải quyết bao gồm goto s và sử dụng các biến boolean để ghi lại liệu một "khối có thể phá vỡ" bên ngoài cũng nên phá vỡ (không thanh lịch, nhưng, đó là cuộc sống).

5

Hai báo cáo break sẽ không giúp bạn thoát khỏi vòng lặp while. Đầu tiên break chỉ giúp bạn thoát khỏi tuyên bố switch và tuyên bố thứ hai không bao giờ đạt được.

Điều bạn cần là làm cho điều kiện của vòng lặp while false, giả sử không có gì trong vòng lặp sau câu lệnh switch. Nếu có mã khác sau khi chuyển đổi, bạn nên kiểm tra điều kiện sau switchbreak ở đó.

 

bool done = false; 

while(! done) 
{ 
    // do stuff 
    switch(something) 
    { 
    case 'a': 
    done = true; // exit the loop 
    break; 
    } 

    // do this if you have other code besides the switch 
    if(done) 
    break; // gets you out of the while loop 

    // do whatever needs to be done after the switch 

} 
 
+0

tại sao không chỉ làm trong khi (đúng) nếu bạn đang đi để kiểm tra nếu (thực hiện). Điều này là thừa. –

+0

nó phụ thuộc ... Bạn có thể hoặc không muốn phá vỡ ngay lập tức sau khi chuyển đổi. – Dima

1

Bạn cũng có thể đóng gói vòng lặp vào một hàm và gọi lại trong trường hợp, trong trường hợp cờ phá vỡ thời gian không đủ. Nó không phải là một thực hành lập trình tốt cho một số người nhưng nếu bạn giữ chức năng đơn giản tôi không thấy tại sao không.

0

Bạn có thể thay đổi công tắc của mình thành hệ thống if. Nó sẽ được biên dịch cho cùng một điều anyway.

+0

Đối số tốt, tôi không quan tâm đến mã quá cấu trúc nếu nó không quan trọng. : P – Nullw0rm

+0

Đảm bảo thêm nhận xét giải thích lý do bạn sử dụng 'if/else-if', để bạn (hoặc người khác) không nhìn thấy nó sau và thay đổi thành câu lệnh chuyển rõ ràng hơn, do đó vi phạm mọi điều. Không có ý định chơi chữ. –

+0

Nếu ai đó refactors mã của bạn và không nhận thấy rằng họ đã thay đổi hành vi cơ bản của phương pháp, tôi không chắc chắn tôi sẽ tin tưởng họ để đọc các bình luận ở nơi đầu tiên. –

3

Bạn có thể thử:

  • Sử dụng Flags
  • Sử dụng Chuyển
  • Có khối Nội vỡ thành một chức năng
  • Sử dụng Exceptions
  • Sử dụng longjump và setjmp

Một chủ đề rất giống với câu hỏi này

http://www.gamedev.net/community/forums/topic.asp?topic_id=385116

+0

Cờ và gói khối thành công việc chức năng. Goto là xấu. Và ngoại lệ không hoàn toàn phù hợp ở đây. Thoát khỏi vòng lặp không phải là lỗi. – Dima

+5

Goto không tệ. Tôi nghĩ rằng goto là thích hợp để sử dụng trong trường hợp này, như là cờ. –

+0

Trong mã ví dụ tôi muốn sử dụng goto, nó sẽ giữ cho nó gọn gàng nếu có mã sau câu lệnh switch. – mikek3332002

32

Tôi sẽ chuyển đổi séc thành một hàm khác.

bool is_correct_answer(char input) 
{ 
    switch(input) 
    { 
    case 'a': 
     cout << "You entered A, which is correct"; 
     return true; 
    case 'b': 
     cout << "..."; 
     return false; 
    } 
    return false; 
} 

int main() 
{ 
    char input; 
    do 
    { 
     std::cout << "Enter something\n -->"; 
     std::cin >> input; 
    } while (!is_correct_answer(input)); 
} 
+0

Điều này thực sự là khá và xứng đáng hơn upvotes. – Thomas

+0

Đây phải là câu trả lời. –

+0

Một trong các chức năng cần được sửa đổi để tính toán các lựa chọn chữ hoa hoặc chữ thường. –

0

Bạn có thể thay thế công tắc với một giải pháp OO nhẹ so với chế ...

#include <iostream> 
#include <map> 
#include <set> 

class input_responder 
{ 
    std::set<char> correct_inputs; 
    std::map<char, const char*> wrong_inputs; 

public: 

    input_responder() 
    { 
     correct_inputs.insert('a'); 
     wrong_inputs['b'] = "..."; 
    } 

    bool respond(char input) const 
    { 
     if (correct_inputs.find(input) != correct_inputs.end()) 
     { 
      std::cout << "You entered " << input << ", which is correct\n"; 
      return true; 
     } 
     else 
     { 
      std::map<char, const char*>::const_iterator it = wrong_inputs.find(input); 
      if (it != wrong_inputs.end()) 
      { 
       std::cout << it->second << '\n'; 
      } 
      else 
      { 
       std::cout << "You entered " << input << ", which is wrong\n"; 
      } 
      return false; 
     } 
    } 
}; 

int main() 
{ 
    const input_responder responder; 
    char input; 
    do 
    { 
     std::cout << "Enter something\n -->"; 
     std::cin >> input; 
    } while (responder.respond(input) == false); 
} 
1

Bạn có thể quan tâm đến các named loop idiom trong C++.

#define named(blockname) goto blockname; \ 
         blockname##_skip: if (0) \ 
         blockname: 

#define break(blockname) goto blockname##_skip; 

named(outer) 
while(1) { 

    //Loop can be conditional or 1, I use it alot, for example in my game 
    char something; 
    std::cout << "Enter something\n -->"; 
    std::cin >> something; 

    //Switch to read "something" 
    switch(something) { 
    case 'a': 
     cout << "You entered A, which is correct"; 
     break(outer); 
    case 'b': 
     cout << "..."; 
     break(outer); 
    } 
} 
Các vấn đề liên quan