Bài viết được liên kết chắc chắn hiểu đúng về Vòng lặp N + 1/2 của Donald Knuth . Thể hiện bằng C / C ++ / Java:
for (;;) {
get next element;
if (at the end) break;
process the element;
}
Điều này hữu ích để đọc các dòng hoặc ký tự từ một tệp, kiểm tra xem bạn đã đạt EOF chưa, và sau đó xử lý nó. Tôi đã quá quen với việc nhìn thấy mô hình for(;;)..if(..)break;xuất hiện rằng nó là thành ngữ đối với tôi. (Trước khi tôi đọc bài báo Knuth, được in lại trong cuốn sách Lập trình văn học , bài này đã từng là "wtf?".)
Knuth đề xuất các từ khóa loop/while/repeat:
loop:
S;
while C:
T;
repeat
Trường hợp Svà Tlà chủ sở hữu vị trí cho một loạt các câu lệnh bằng 0 hoặc nhiều hơn và Clà một điều kiện boolean. Nếu không có Scâu lệnh thì đó sẽ là một vòng lặp while và nếu không có Tcâu lệnh thì đó sẽ là một vòng lặp do.
Bản thân cấu trúc này có thể được khái quát bằng cách cho phép không hoặc nhiều while Cmệnh đề, làm cho nó hoàn hảo để thể hiện các vòng lặp vô hạn và sau đó một số điều kiện hiếm hơn sẽ cần hai kiểm tra.
Trong cùng một bài viết, Knuth đã đề xuất một cơ chế báo hiệu sẽ là một phiên bản cục bộ của các trường hợp ném / bắt ngoại lệ (như là một cách thay thế cho việc sử dụng goto).
Cho tôi? Tôi muốn Java hỗ trợ tối ưu hóa cuộc gọi đuôi, để tôi có thể diễn đạt bất kỳ cấu trúc điều khiển chung nào khi cần.
Cập nhật: Tôi quên đề cập rằng nhiều lập trình viên C / C ++ / Java đã khắc phục điều này bằng cách sử dụng một bài tập được nhúng trong điều kiện while:
while ((c = getc(f)) != -1) {
T;
}
Sử dụng các thuật ngữ từ cấu trúc của Knuth, điều này được phép khi Svà Ccó thể được kết hợp thành một biểu thức. Một số người ghét nhìn thấy bài tập được nhúng ở trên, trong khi những người khác ghét nhìn thấy phần breakở for (;;)trên. Nhưng khi Svà Ckhông thể được kết hợp, chẳng hạn như khi Scó nhiều câu lệnh, thì câu lệnh for (;;)thay thế duy nhất mà không lặp lại mã. Cách khác là đơn giản là sao chép Smã:
S;
while (C) {
T;
S;
}
Sự loop/while/repeatthay thế của Knuth có vẻ tốt hơn nhiều.