“For (;;)” có nhanh hơn “while (TRUE)” không? Nếu không, tại sao mọi người sử dụng nó?

165
Chris Cooper 2010-04-10 12:04.
for (;;) {
    //Something to be done repeatedly
}

Tôi đã thấy loại thứ này được sử dụng rất nhiều, nhưng tôi nghĩ nó khá kỳ lạ ... Sẽ không rõ ràng hơn khi nói while(true), hay một cái gì đó dọc theo những dòng đó?

Tôi đoán rằng (cũng là lý do khiến nhiều lập trình viên phải dùng đến mã khó hiểu), đây là mức lợi nhuận nhanh hơn một chút?

Tại sao, và nó có thực sự đáng giá không? Nếu vậy, tại sao không chỉ định nghĩa nó theo cách này:

#define while(true) for(;;)

Xem thêm: Cái nào nhanh hơn: while (1) hay while (2)?

20 answers

263
Ben Zotto 2010-04-10 12:06.
  1. Nó không nhanh hơn.
  2. Nếu bạn thực sự quan tâm, hãy biên dịch với đầu ra của trình hợp dịch cho nền tảng của bạn và tìm xem.
  3. Nó không quan trọng. Điều này không bao giờ quan trọng. Viết các vòng lặp vô hạn của bạn theo cách bạn muốn.
178
jalf 2010-04-10 13:11.

Tôi thích for(;;)vì hai lý do.

Một là một số trình biên dịch tạo ra cảnh báo về while(true)(một cái gì đó như "điều kiện vòng lặp là không đổi"). Tránh các cảnh báo luôn là điều nên làm.

Khác là tôi nghĩ for(;;)là rõ ràng hơn và nhiều hơn. Tôi muốn một vòng lặp vô hạn. Nó nghĩa là không có điều kiện, nó phụ thuộc vào gì cả. Tôi chỉ muốn nó tiếp tục mãi mãi, cho đến khi tôi làm điều gì đó để thoát khỏi nó.

Trong khi với while(true), thì, sự thật có liên quan gì đến bất cứ điều gì? Tôi không quan tâm đến việc lặp lại cho đến khi true trở thành false, đó là điều mà biểu mẫu này nói theo nghĩa đen (lặp trong khi true là đúng). Tôi chỉ muốn lặp lại.

Và không, hoàn toàn không có sự khác biệt về hiệu suất.

57
ta.speot.is 2010-04-10 12:10.

Cá nhân tôi sử dụng for (;;)vì không có bất kỳ số nào trong đó, nó chỉ là một từ khóa. Tôi thích nó while (true), while (1), while (42), while (!0)vv vv

49
Mark Harrison 2010-04-10 14:26.

Vì Dennis Ritchie

  • Tôi bắt đầu sử dụng for (;;)vì đó là cách Dennis Ritchie làm trong K&R, và khi học một ngôn ngữ mới, tôi luôn cố gắng bắt chước những người thông minh.

  • Đây là C / C ++ thành ngữ. Về lâu dài, có lẽ tốt hơn là bạn nên làm quen với nó nếu bạn có kế hoạch làm nhiều việc trong không gian C / C ++.

  • Của bạn #definesẽ không hoạt động, vì thứ được xác định là # phải trông giống như một mã định danh C.

  • Tất cả các trình biên dịch hiện đại sẽ tạo ra cùng một mã cho hai cấu trúc.

46
Matthew Flaschen 2010-04-10 12:08.

Nó chắc chắn không nhanh hơn trong bất kỳ trình biên dịch lành mạnh nào. Cả hai sẽ được tổng hợp thành các bước nhảy vô điều kiện. Phiên bản for dễ nhập hơn (như Neil đã nói) và sẽ rõ ràng nếu bạn hiểu cú pháp vòng lặp for.

Nếu bạn tò mò, đây là những gì gcc 4.4.1 mang lại cho tôi cho x86. Cả hai đều sử dụng lệnh x86 JMP .

void while_infinite()
{
    while(1)
    {
    puts("while");
    }
}

void for_infinite()
{
    for(;;)
    {
    puts("for");
    }
}

biên dịch thành (một phần):

.LC0:
.string "while"
.text
.globl while_infinite
    .type   while_infinite, @function
while_infinite:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $24, %esp .L2: movl $.LC0, (%esp)
    call    puts
    jmp .L2
    .size   while_infinite, .-while_infinite
    .section    .rodata
.LC1:
    .string "for"
    .text
.globl for_infinite
    .type   for_infinite, @function
for_infinite:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $24, %esp .L5: movl $.LC1, (%esp)
    call    puts
    jmp .L5
    .size   for_infinite, .-for_infinite
43
Boann 2012-08-27 16:26.

Tôi thích for (;;)vì nó nhất quán nhất trong các ngôn ngữ giống C khác nhau.

Trong C ++ while (true)thì tốt, nhưng trong C bạn phụ thuộc vào tiêu đề để xác định true, nhưng đây TRUEcũng là một macro thường được sử dụng. Nếu bạn sử dụng while (1)nó chính xác trong C và C ++ và JavaScript, nhưng không phải Java hoặc C #, yêu cầu điều kiện vòng lặp là boolean, chẳng hạn như while (true)hoặc while (1 == 1). Trong PHP, các từ khóa không phân biệt chữ hoa chữ thường nhưng ngôn ngữ này thích viết hoa hơn TRUE.

Tuy nhiên, for (;;)luôn hoàn toàn chính xác trong tất cả các ngôn ngữ đó.

21
Michael Burr 2010-04-10 13:16.

Cá nhân tôi thích for (;;)thành ngữ hơn (sẽ biên dịch thành mã giống như while (TRUE).

Sử dụng while (TRUE)có thể dễ đọc hơn theo một nghĩa nào đó, tôi quyết định sử dụng for (;;)thành ngữ vì nó nổi bật .

Một cấu trúc vòng lặp vô hạn nên dễ dàng nhận thấy hoặc được gọi ra trong mã và cá nhân tôi nghĩ rằng for (;;)phong cách này tốt hơn một chút so với while (TRUE)hoặc while (1).

Ngoài ra, tôi nhớ lại rằng một số trình biên dịch đưa ra cảnh báo khi biểu thức điều khiển của vòng lặp while là một hằng số. Tôi không nghĩ điều đó xảy ra quá nhiều, nhưng chỉ cần khả năng cảnh báo giả mạo là đủ để tôi muốn tránh nó.

17
rmeador 2010-04-10 12:30.

Tôi đã thấy một số người thích nó hơn vì họ có #define ở đâu đó như thế này:

#define EVER ;;

Điều này cho phép họ viết điều này:

for (EVER)
{
    /* blah */
}
16
bungle 2010-04-10 13:17.

Điều gì về (nếu ngôn ngữ của bạn hỗ trợ):

start:
/* BLAH */
goto start;
12
Jason Williams 2010-04-10 12:18.

Không có sự khác biệt nào về mã máy được tạo.

Tuy nhiên, để chống lại xu hướng, tôi tranh luận rằng biểu mẫu while (TRUE) dễ đọc và trực quan hơn nhiều so với (;;), và tính dễ đọc và rõ ràng là lý do quan trọng hơn nhiều cho các nguyên tắc viết mã hơn bất kỳ lý do nào tôi ' tôi đã nghe nói về phương pháp for (;;) (Tôi thích tự mình dựa trên các nguyên tắc viết mã của mình dựa trên lý luận vững chắc và / hoặc bằng chứng về tính hiệu quả).

11
James McLeod 2010-04-10 12:09.

Không chỉ là một mẫu nổi tiếng mà còn là một thành ngữ tiêu chuẩn trong C (và C ++)

11
Michael 2010-04-10 19:49.
while(true)

tạo cảnh báo với Visual Studio (điều kiện là không đổi). Hầu hết những nơi tôi đã làm việc biên dịch các bản dựng sản xuất với cảnh báo là lỗi. Vì thế

for(;;)

được ưa thích.

11
SylvanBlack 2013-10-02 21:39.

Cả hai phải giống nhau nếu mã của bạn được tối ưu hóa bằng trình biên dịch. Để giải thích ý tôi về việc tối ưu hóa, đây là đoạn mã mẫu được viết bằng MSVC 10:

int x = 0;

while(true) // for(;;)
{
    x +=1;

    printf("%d", x);
}

Nếu bạn xây dựng nó ở chế độ Gỡ lỗi ( không có bất kỳ tối ưu hóa nào (/ Od) ) thì việc tháo gỡ cho thấy sự khác biệt rõ ràng. Có thêm hướng dẫn cho trueđiều kiện bên trong while.

while(true)
00D313A5  mov         eax,1                //extra 
00D313AA  test        eax,eax              //extra
00D313AC  je          main+39h (0D313B9h)  //extra
    {
        x +=1;
00D313AE  mov         eax,dword ptr [x]  
00D313B1  add         eax,1  
00D313B4  mov         dword ptr [x],eax  
    printf("%d", x);
    ...
    }
00D313B7  jmp         main+25h (0D313A5h)  


for(;;)
    {
        x +=1;
00D213A5  mov         eax,dword ptr [x]  
00D213A8  add         eax,1  
00D213AB  mov         dword ptr [x],eax  
    printf("%d", x);
    ...
    }
00D213AE  jmp         main+25h (0D213A5h)  

Tuy nhiên, nếu bạn xây dựng mã của mình ở chế độ Phát hành (với Tốc độ tối đa mặc định (/ O2) ), bạn sẽ nhận được cùng một đầu ra cho cả hai. Cả hai vòng đều được rút gọn thành một lệnh nhảy.

for(;;)
    {
        x +=1;
01291010  inc         esi  

        printf("%d", x);
    ...
    }
0129101C  jmp         main+10h (1291010h)  

    while(true)
    {
        x +=1;
00311010  inc         esi  

        printf("%d", x);
    ...
    }
0031101C  jmp         main+10h (311010h)  

Việc bạn sẽ sử dụng cái nào không quan trọng đối với một trình biên dịch tốt với tính năng tối ưu hóa tốc độ được bật.

10
Mark Rejhon 2010-04-10 12:14.

Đó là vấn đề sở thích cá nhân, cách nào nhanh hơn. Cá nhân tôi là người thích gõ phím và không bao giờ nhìn vào bàn phím của mình, trong khi lập trình - tôi có thể gõ tất cả 104 phím trên bàn phím của mình.

Tôi thấy nếu gõ "while (TRUE)" nhanh hơn.

Tôi nhẩm tính thêm một số phép đo chuyển động của ngón tay và tính tổng. "for (;;)" có khoảng 12 độ rộng phím của các chuyển động quay lại và thứ tư (giữa các phím home và các phím, và giữa các phím home và phím SHIFT) "trong khi (TRUE)" có khoảng 14 độ rộng phím của các chuyển động quay lại và thứ tư.

Tuy nhiên, tôi ít bị lỗi hơn khi gõ phím sau. Tôi nhẩm tính từng từ một, vì vậy tôi thấy gõ những thứ như "nIndex" nhanh hơn so với các từ viết tắt như "nIdx" vì tôi phải thực sự nhẩm ra chữ cái thay vì nói nó trong đầu và để ngón tay tự động -gõ từ (như đi xe đạp)

(Điểm chuẩn TypingTest.com của tôi = 136 WPM)

6
Mike Dunlavey 2010-04-10 14:36.

Tất cả các câu trả lời hay - hành vi phải giống hệt nhau.

TUY NHIÊN - Chỉ cần giả sử nó ĐÃ tạo ra sự khác biệt. Giả sử một trong số họ lấy thêm 3 lệnh cho mỗi lần lặp.

Bạn có nên quan tâm?

CHỈ nếu những gì bạn làm bên trong vòng lặp hầu như không có gì , điều này hầu như không bao giờ xảy ra.

Quan điểm của tôi là, có tối ưu hóa vi mô và tối ưu hóa vĩ mô. Tối ưu hóa vi mô giống như “cắt tóc để giảm cân”.

5
Clifford 2010-04-10 12:34.

Tôi không thể tưởng tượng rằng một trình biên dịch đáng giá sẽ tạo ra bất kỳ mã nào khác. Ngay cả khi nó đã xảy ra, sẽ không có cách nào xác định nếu không thử nghiệm trình biên dịch cụ thể nào hiệu quả hơn.

Tuy nhiên, tôi đề nghị bạn thích for(;;)vì những lý do sau:

  • một số trình biên dịch tôi đã sử dụng sẽ tạo ra cảnh báo biểu thức không đổi trong khi (true) với cài đặt mức cảnh báo thích hợp.

  • trong ví dụ của bạn, macro TRUE có thể không được xác định như bạn mong đợi

  • có rất nhiều biến thể có thể có của sự vô hạn trong khi vòng lặp như while(1), while(true), while(1==1)vv .; vì vậy for(;;)có khả năng dẫn đến tính nhất quán cao hơn.

5
Armada 2013-02-24 12:15.
for(;;Sleep(50))
{
    // Lots of code
}

Rõ ràng hơn:

while(true)
{
    // Lots of code
    Sleep(50);
}

Điều này không áp dụng nếu bạn không sử dụng Sleep().

4
Thomas Matthews 2010-04-10 12:14.

Vòng lặp "mãi mãi" phổ biến trong các hệ thống nhúng như một vòng lặp nền. Một số người thực hiện nó như:

for (; ;)
{
 // Stuff done in background loop
}

Và đôi khi nó được thực hiện như:

while (TRUE /* or use 1 */)
{
 // Stuff done in background loop
}

Và một triển khai khác là:

do
{
 // Stuff done in background loop
} while (1 /* or TRUE */);

Trình biên dịch tối ưu hóa phải tạo mã lắp ráp giống nhau hoặc tương tự cho các phân đoạn này. Một lưu ý quan trọng: thời gian thực hiện cho các vòng lặp không phải là mối quan tâm lớn vì các vòng lặp này diễn ra mãi mãi và nhiều thời gian hơn được dành cho phần xử lý.

3
nik 2010-04-11 05:16.

Tôi giả sử while (true) dễ đọc hơn for (;;) - trông giống như lập trình viên của nó bỏ sót điều gì đó trong vòng lặp for :)

2
Ignacio Cortorreal 2013-07-02 04:54.

Lý do quan trọng nhất để sử dụng "for (;;)" là sợ sử dụng "while (TRUE)" khi bạn lập trình khám phá. Việc kiểm soát số lần lặp lại với "for" dễ dàng hơn và cũng dễ dàng hơn để chuyển vòng lặp "for" thành vô hạn.

Ví dụ: nếu bạn đang xây dựng một hàm đệ quy, bạn có thể giới hạn số lượng lệnh gọi hàm trước khi chuyển đổi thành một vòng lặp vô hạn.

    for(int i=0;i<1000;i++) recursiveFunction(oneParam);

Khi tôi chắc chắn về hàm của mình, sau đó tôi chuyển nó thành một vòng lặp vô hạn:

    for(;;) recursiveFunction(oneParam);

Related questions

MORE COOL STUFF

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett đã bất chấp những lời khuyên hẹn hò điển hình khi cô gặp chồng mình.

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Michael Sheen là một diễn viên phi lợi nhuận nhưng chính xác thì điều đó có nghĩa là gì?

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Ngôi sao của Hallmark Colin Egglesfield chia sẻ về những cuộc gặp gỡ với người hâm mộ ly kỳ tại RomaDrama Live! cộng với chương trình INSPIRE của anh ấy tại đại hội.

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Bạn sẽ phải phủi sạch đầu đĩa Blu-ray hoặc DVD để xem tại sao Northern Exposure trở thành một trong những chương trình nổi tiếng nhất của thập niên 90.

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

8 công dụng tuyệt vời của Baking Soda và Giấm

8 công dụng tuyệt vời của Baking Soda và Giấm

Bạn biết đấy, hai sản phẩm này là nguồn điện để làm sạch, riêng chúng. Nhưng cùng với nhau, chúng có một loạt công dụng hoàn toàn khác.

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Thủy điện rất cần thiết cho lưới điện của Hoa Kỳ, nhưng nó chỉ tạo ra năng lượng khi có nước di chuyển. Bao nhiêu nhà máy thủy điện có thể gặp nguy hiểm khi các hồ và sông cạn kiệt?

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Tóc tỉa từ các tiệm và các khoản quyên góp cá nhân có thể được tái sử dụng như những tấm thảm thấm dầu và giúp bảo vệ môi trường.

Làm thế nào để xây dựng một quả địa cầu từ Scratch

Làm thế nào để xây dựng một quả địa cầu từ Scratch

Thời gian, sự kiên nhẫn, thời gian, sự cống hiến và thời gian chỉ là một vài trong số những thứ mà Peter Bellerby cần để thành lập và sau đó điều hành Bellerby & Co. Globemakers, một trong những công ty duy nhất trên Trái đất vẫn sản xuất các quả địa cầu bằng tay.

Năm giai đoạn đau buồn sau khi mất việc làm

Năm giai đoạn đau buồn sau khi mất việc làm

Đó là một ngày thứ Bảy, máy bay của tôi hạ cánh, và tôi đã sẵn sàng để thư giãn trong một kỳ nghỉ cuối tuần ngắn ngủi, khi một email đến trên điện thoại của tôi. Tôi đã mất việc.

Giữ an toàn cho danh tính của bạn với một cảnh báo đóng băng hoặc gian lận tín dụng

Giữ an toàn cho danh tính của bạn với một cảnh báo đóng băng hoặc gian lận tín dụng

Nếu bạn đã từng bị đánh cắp danh tính của mình, bạn biết đó là một trải nghiệm đáng sợ và căng thẳng. Một cách không phổ biến để ngăn chặn nó? Tín dụng bị đóng băng.

Buổi ra mắt phần 3 của The Good Place có một học sinh mới: Khán giả

Buổi ra mắt phần 3 của The Good Place có một học sinh mới: Khán giả

Eleanor (Kristen Bell) dường như đã tình nguyện cho chúng tôi làm vật tưởng nhớ. NBC's The Good Place là một chương trình thích thử thách tốt.

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Rothschild's luggage got lost, but luckily she has an incredible closet to shop: Sister Paris Hilton's!

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa. Từ Hollywood đến New York và mọi nơi ở giữa, hãy xem các ngôi sao yêu thích của bạn đang làm gì!

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

Các nhà điều tra đang xem xét liệu nhóm và nghi phạm có biết nhau trước vụ tấn công hay không

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Vụ kiện, nêu tên một số học khu, lập luận rằng dự luật "Không nói đồng tính" được ban hành gần đây của Florida "có hiệu quả im lặng và xóa bỏ học sinh và gia đình LGBTQ +"

Đường băng hạ cánh

Đường băng hạ cánh

Cuối hè đầu thu là mùa hoài niệm. Những chiếc đèn đường chiếu ánh sáng của chúng qua những con đường đẫm mưa, và những chiếc lá dưới chân - màu đỏ cam tắt trong bóng chạng vạng - là lời nhắc nhở về những ngày đã qua.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Vào năm 2021, tôi khuyến khích bạn suy nghĩ lại mọi thứ bạn biết về khách hàng mà bạn phục vụ và những câu chuyện bạn kể cho họ. Lùi lại.

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Vào ngày sinh nhật thứ 9 của Felix The Cat, tôi nhớ về một trong những mất mát lớn nhất trong cuộc đời trưởng thành của tôi - Sophie của tôi vào năm 2013. Tôi đã viết bài luận này và chia sẻ nó trên nền tảng này một thời gian ngắn vào năm 2013.

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Tôi ghét từ "tàu đắm". Mọi người cảm thấy thoải mái trong la bàn đạo đức của riêng mình, và khi làm như vậy, họ thấy mình vượt qua sự phán xét.

Language