2009-11-24 28 views

Trả lời

28

Ví dụ của bạn sẽ thoát ra khỏi vòng lặp bên trong nhất. Tuy nhiên, sử dụng tuyên bố labeled break, bạn có thể thực hiện việc này:

outer: 
    for(..) 
    for(..) 
     for(..){ 
     break outer; //this will break out from all three loops 
     } 
+6

Tôi không thích nhãn: ( – ufukgun

+4

@ufukgun: đây là cách duy nhất bạn có thể thoát ra khỏi tất cả các vòng cho dù bạn thích hay không :) –

+1

@Raskesh bạn có thể trở về từ một hàm hoặc ném một ngoại lệ để thoát khỏi vòng lặp . – TimW

3

Từ vòng lặp bên trong hầu hết :)

int i,j,k; 
    for(i = 0; i < 2; i++) 
      for(j = 0; j < 2; j++) 
        for(k = 0; k < 2; k++) 
        { 
          printf("%d %d %d\n", i, j, k); 
          break; 
        } 

Sẽ tạo ra:

0 0 0 
0 1 0 
1 0 0 
1 1 0 
11

Điều này sẽ chỉ thoát ra khỏi vòng lặp bên trong. Bạn cũng có thể xác định phạm vi thoát ra. Thêm từ các language specs:

Lệnh break không có nhãn nỗ lực để chuyển điều khiển đến đoạn trong cùng kèm theo chuyển đổi, thời gian, làm, hoặc cho tuyên bố của phương pháp hoặc khởi tạo ngay kèm theo khối; tuyên bố này, được gọi là mục tiêu ngắt , sau đó ngay lập tức hoàn tất bình thường.

+1

+1 để tra cứu tài liệu. – Heinzi

-2

nó sẽ breake từ hầu hết các vòng lặp bên trong,

nếu bạn muốn phá vỡ từ tất cả, bạn có thể giữ một biến và thay đổi giá trị của nó khi bạn muốn phá vỡ, sau đó kiểm soát nó ở đầu mỗi cho loop

+1

quản lý biến, mặc dù nhiều người dường như không thích lables, là lộn xộn hơn và hiển thị một sự hiểu lầm chung về các cấu trúc có sẵn – pstanton

7

suy nghĩ một chút về những câu hỏi này, có lẽ cách này bạn sẽ học được nhiều hơn một mình từ nhận được câu trả lời (mà đã được đăng bởi bây giờ, tôi chắc chắn):

  • nếu bạn đã một mình, bạn sẽ quyết định như thế nào? Tạo nên một trường hợp thử nghiệm, nơi nó được hiển nhiên.
  • nếu bạn phát minh ra ngôn ngữ và thêm cấu trúc ngắt, cách hoạt động? Hành vi nào hữu ích hơn? Người nào sẽ là người được mong chờ nhất?
  • làm cách nào bạn giải quyết được việc thoát khỏi lồng nhau cho các vòng lặp trong Java? Trong C hoặc C++? Trong một ngôn ngữ không có bất kỳ nhãn nào?

Bạn sẽ ngạc nhiên về mức độ bạn có thể học được từ các bài tập tự tạo đơn giản này.

+0

+1! Suy nghĩ nhiều hơn, ít làm phiền người khác trên internet! – Bombe

+0

+1: nhiều hơn cả hai. :-) –

3

Có, không có nhãn, nó sẽ chỉ phá vỡ vòng lặp bên trong nhất.
Thay vì sử dụng các nhãn, bạn có thể đặt các vòng lặp của bạn trong một chức năng tách biệt và trở về từ hàm.

class Loop { 
    public void loopForXx() { 
     untilXx(); 
    } 

    private void untilXx() { 
     for() 
      for() 
       for() 
        if(xx) 
         return; 
    } 
} 
+1

Có, xin vui lòng, không phá vỡ hoặc thậm chí nhãn! –

0

Nhiều người ở đây không thích nhãn và phá vỡ. Kỹ thuật này có thể được so sánh với việc sử dụng câu lệnh 'goto', một câu lệnh điều khiển luồng cho phép nhảy ra khỏi một khối mã theo cách không chuẩn, thu hút sử dụng các điều kiện trước và sau. Edsger Dijkstra đã xuất bản một bài báo nổi tiếng trong Truyền thông ACM, tháng 3 năm 1968, 'Tuyên bố Goto được coi là có hại' (đó là một bài đọc ngắn).

Sử dụng cùng một lý do được trình bày trong bài viết, trả về từ bên trong một lần lặp như đề xuất của TimW cũng là thực hành không tốt. Nếu một là nghiêm ngặt, để tạo mã có thể đọc được, với các điểm vào và ra có thể dự đoán được, ta nên khởi tạo biến sẽ giữ giá trị trả về (nếu có) ở đầu phương thức và chỉ trả về ở cuối mehod.

Điều này đặt ra thách thức khi sử dụng lặp lại để thực hiện tra cứu. Để tránh sử dụng phá vỡ hoặc trả lại một chắc chắn kết thúc với một vòng lặp while với một điều kiện dừng thường xuyên và một số biến boolean để chỉ ra rằng việc tra cứu đã thành công:

boolean targetFound = false; 
int i = 0; 
while (i < values.size() && ! targetFound) { 

    if (values.get(i).equals(targetValue)) { 
     targetFound = true; 
    } 
} 
if (!targetFound) { 
    // handle lookup failure 
} 

Ok, hoạt động này, nhưng có vẻ như một chút vụng về với tôi. Trước hết tôi phải giới thiệu một boolean để phát hiện thành công tra cứu. Thứ hai, tôi phải kiểm tra rõ ràng targetFound sau vòng lặp để xử lý lỗi tra cứu.

đôi khi tôi sử dụng giải pháp này, mà tôi nghĩ là ngắn gọn hơn và dễ đọc:

lookup: { 

    for(Value value : values) { 

     if (value.equals(targetValue)) { 
      break lookup; 
     } 
    } 
    // handle lookup failure here 
} 

Tôi nghĩ rằng phá vỡ (không ý định chơi chữ) các quy tắc ở đây kết quả trong mã tốt hơn.

+0

Bạn có thể chỉnh sửa ví dụ đầu tiên sao cho cả hai giải pháp đều sử dụng vòng lặp cải tiến? Điều này sẽ giúp so sánh, giải pháp nào dễ hiểu hơn (dễ đọc). Bây giờ nó là một cuộc cạnh tranh không lành mạnh. –

+0

Không, tôi không thể. Đó là loại quan điểm của tôi. Nếu không có các câu lệnh break hoặc return (hoặc gọi System.exit(), vv) một vòng lặp for luôn luôn hoàn thành và tôi giả định rằng không ai sẽ chấp nhận chi phí cho phép lặp lại hoàn tất sau khi kết quả được tìm thấy. Vì vậy, hoặc là bạn làm việc xung quanh các ngắt và trả về bằng cách sử dụng một vòng lặp while và một biến phụ, hoặc bạn chấp nhận bằng cách sử dụng một câu lệnh break kết hợp với một vòng lặp for và nhận được mã ngắn hơn nhiều. –

1

như thường được đề cập đến, tôi không thích phá vỡ nhãn eather. như vậy trong khi trong một vòng lặp for phần lớn thời gian tôi thêm một varible boolean để thoát đơn giản vòng lặp .. (chỉ khi tôi muốn phá vỡ nó nguyên nhân;))

boolean exit = false; 
for (int i = 0; i < 10 && !exit; i++) { 
    for (int j = 0; j < 10 && !exit; j++) { 
     exit = true; 
    } 
} 

đây là theo ý kiến ​​của tôi nhiều hơn thanh lịch hơn giờ nghỉ ..