Tại sao tôi thấy rất nhiều cho các cấu trúc (;;)? [đóng cửa]


14

Theo cách nghĩ của tôi, một vòng lặp for được sử dụng để lặp lại trong một phạm vi đã biết hoặc có thể xác định.

String[] names = //something;
for ( int i = 0; i < names.length; i++ ) { //do stuff }

tương đương (phạm vi của tôi sang một bên) với:

String[] names = //something;
int i = 0;
while (i < names.length )
{
   // do stuff
   i++;
}

Nói cách khác, forvòng lặp chỉ đơn giản là một đường cú pháp (rất hữu ích) cho một cấu trúc thường được sử dụng while.

Tuy nhiên, tôi thấy rất nhiều for(;;)cấu trúc trên web có chức năng tương đương vớiwhile(true)

Lý do cho điều này là gì? Tại sao vòng lặp vô hạn sẽ được ưa thích hơn vòng lặp vô hạn?

// Tôi thậm chí đã thấy một cuốn sách giáo khoa java không sử dụng trong khi các vòng lặp! Dẫn đến các cấu trúc quái dị như:

String input = getInput();
for( ; !inputIsValid(input) ; )
{
   //redo;
}

Lý do chính là ưu tiên. Khả năng đọc nên được sử dụng khi đưa ra lựa chọn tuy nhiên YMMV.
Aaron McIver

Tại sao mọi người sẽ thích các công trình khó xử?
Chris Cudmore

10
Bạn có thể trao đổi whileforở đây và câu hỏi sẽ không thay đổi. while(true)for(;;)có nghĩa là điều tương tự. Bạn rõ ràng có một ưu tiên mạnh mẽ cho while, những người khác có thể có một ưu tiên mạnh mẽ như nhau cho for. Không thể nói rằng cái này đúng hơn cái kia.
Caleb

3
@chris, tôi không thấy for(;;)khó hiểu chút nào. Đó là một thành ngữ C tiêu chuẩn, một thành ngữ mà bạn sẽ ghi lại trong phần 3.5 của K & R (2e). Tôi hiểu rằng bạn không thích nó; bạn nên hiểu rằng những người khác rõ ràng thích nó (nếu không bạn sẽ không bao giờ nhìn thấy nó). Nó có thể ít nhiều được chấp nhận trong các ngôn ngữ khác ngoài C; bạn đã gắn thẻ ngôn ngữ bất khả tri này chỉ làm giảm khả năng trả lời dứt khoát. Một lần nữa, tôi đã bỏ phiếu để đóng vì Q không mang tính xây dựng; nếu tôi bị xúc phạm tôi sẽ bị gắn cờ là tấn công thay vì hoặc ngoài việc đóng cửa. Đó là tất cả.
Caleb

1
Cá nhân tôi nghĩ rằng có một cơ hội thực sự ở đây để có một cú pháp khác hoàn toàn cho các vòng lặp vô hạn: một cái gì đó giống nhưwheeeeeeee { ... }
gièm pha

Câu trả lời:


33

Đó là sự kìm hãm từ các thực tiễn lập trình cũ trên PDP-11 (vâng, tôi đã nói ). Nó được sử dụng để lưu một lệnh đơn, rất hữu ích để làm cho các vòng lặp chạy nhanh hơn.

Xem phần sau để biết thêm thông tin: http://www.flounder.com/exceptions.htmlm


3
Đó chính xác là những gì tôi đang tìm kiếm. Có một lý do thực sự, hợp pháp, nhưng nó không còn hiệu lực.
Chris Cudmore

1
@chris Nnnope, trình biên dịch hiện đại đôi khi sẽ phàn nàn về việc sử dụng hằng số trong điều kiện của một vòng lặp. Nó không hoàn toàn là một sự nắm giữ.
Izkata

Có nhiều điều hơn thế. Tôi có thể nhớ việc viết C vào đầu những năm 1990 trên các hệ thống unix và trong khi (true) {} không phải là một lựa chọn. Không có loại boolean tiêu chuẩn, nhưng một số hệ thống unix đã xác định riêng của chúng trong các tệp tiêu đề C. Từ bộ nhớ, ít nhất một nhà cung cấp unix đã xác định TRUE là số 0 một cách giả định để hỗ trợ xử lý trả về hàm vì quy ước là trả về 0 khi thành công và các số dương là thất bại. Điều này có nghĩa là trong khi (TRUE) {} không khả dụng.
Michael Shaw

1
Tôi không thể tìm thấy nó ngay bây giờ, nhưng tôi có thể thề rằng vài năm trước Dennis Ritchie đã viết một bài đăng trên Usenet nói rằng điều này đơn giản là sai và anh ấy / họ sử dụng for(;;)cú pháp như (theo ý kiến ​​của họ) một tuyên bố trực tiếp hơn về ý định rằng không có tiêu chí nào được nêu để thoát khỏi vòng lặp.
Jerry Coffin

@Ptolemy: Vâng, bạn chắc chắn có thể đã viết while(1) { }.
Ed S.

10

một số trình biên dịch sẽ đưa ra cảnh báo (một cái gì đó giống như biểu thức điều kiện là không đổi ) khi sử dụng while( 1 )nhưng for( ; ; )không có gì để cảnh báo. Các lập trình viên muốn mã mà không có cảnh báo, vì vậy họ sử dụng biến thể.


Tuy nhiên, một số điều mà trình biên dịch cảnh báo là hoàn toàn hợp lệ, và thậm chí (trong một số trường hợp đặc biệt) không thể tránh khỏi. Vì vậy, một số người trong chúng ta coi các cảnh báo là tốt, cảnh báo. Nếu bạn phớt lờ chúng, tất nhiên bạn có thể bị ngập trong những thứ đáng nguyền rủa và không nhìn thấy những thứ quan trọng - nhưng có những pragma và tùy chọn để vô hiệu hóa cảnh báo, cục bộ hoặc toàn cầu. Về cơ bản, vâng, tốt hơn là không có cảnh báo, nhưng tôi thường cần một lý do mạnh mẽ hơn đó là áp dụng kiểu mã xấu hơn. Ở đây, nó không tệ hơn chỉ khác nhau, nhưng các vòng lặp "vô hạn" rất hiếm (hoặc kiểu khác rất xấu).
Steve314

5

Đó là một thói quen có được từ lập trình C khi không có kiểu boolean. Mặc dù (1) sẽ có khả năng tương đương nhưng For (;;) thường được sử dụng vì nó hiển thị trong K & R nếu tôi nhớ chính xác. Tôi nghi ngờ rằng có một lý do phần cứng trong đó ở đâu đó là tốt.


4
... nghi ngờ có một lý do phần cứng ...
Aaron McIver

2
Như Edward Robertson đã đề cập, lý do là vì trình biên dịch C trên PDP-11 không nhận ra rằng "trong (true)" là hằng số thời gian biên dịch và sẽ thêm một lệnh bổ sung (so sánh) khi tạo lắp ráp. Do các tài nguyên hạn chế có sẵn trên PDP-11, các lập trình viên đã sử dụng vòng lặp for để tối ưu hóa một lệnh bổ sung ngoài chương trình.
Jetti

3

for (;;) có thể được đọc là "mãi mãi" mà một số người thấy tự nhiên hơn "trong khi sự thật".


Mặc dù đây không phải là lý do ban đầu, nhưng đó là lý do thứ yếu khiến sở thích bị mắc kẹt lâu sau khi lý do ban đầu trở nên lỗi thời. Tuy nhiên, rất khó để đưa ra bất kỳ bằng chứng nào để hỗ trợ điều này, ngoài việc yêu cầu các lập trình viên có kinh nghiệm lâu năm.
DarenW

-2

Tất cả các lập trình viên có kinh nghiệm tôi đã hỏi có thể nhận ra for(;;)nhanh hơn while(true)hoặc while(1).


2
Bất kỳ lập trình viên nào đáng giá đều có thể nhận ra cả ba ngay lập tức. Cả ba đều đủ phổ biến để bất cứ ai dành hơn 5 phút để đọc mã đã thấy mỗi người trong số họ rất nhiều lần.
cHao

1
Các nghiên cứu đã chỉ ra rằng các lập trình viên có kinh nghiệm có thể hiểu for(;;)nhanh hơn 14ms so với while(1):-)
kevin cline
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.