Có phải là người dùng cho (;;)) nhanh hơn so với khi còn (TRUE) không? Nếu không, tại sao mọi người sử dụng nó?


164
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á lạ ... Sẽ không rõ ràng hơn khi nói while(true), hoặc một cái gì đó dọc theo những dòng đó?

Tôi đoán rằng (đó là lý do để nhiều nhà lập trình sử dụng mã hóa) đây là một biên độ nhỏ nhanh hơn?

Tại sao, và nó thực sự có giá trị nó? 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)?


51
Là gì TRUE???
AnT

20
@Steven Sudit: Phải TRUElàm gì với C? Macro tiêu chuẩn cho kết quả boolen thực trong C99 vẫn còn true. Nơi nào đã TRUEđến từ đâu?
AnT

31
Macro đó không hoạt động, #define EVER ;;đã được sử dụng trong IOCCC mặc dù .. :)

18
Không phải là macro để #define while(TRUE)khai báo một macro có một đối số được gọi TRUElà không bao giờ được sử dụng, do đó chuyển từng vòng lặp while trong chương trình của bạn thành một vòng lặp vô hạn?
AshleyBrain

9
@Steven Sudit: Không. Không có "macro tiêu chuẩn trong VS 6.0". Macro TRUEđến từ các tệp tiêu đề được liên kết với API Windows. Nó không liên quan đến VS 6.0 dưới bất kỳ hình thức nào. Và, như tôi đã nói trước đây, nó không liên quan gì đến C hay C ++. Trong C ++, nghĩa đen "thực sự" chỉ là true(trong VS 6.0), trong C89 / 90 không có thứ gì như vậy cả, và trong C99, nó là vĩ mô true. Điều này áp dụng cho tất cả các trình biên dịch C / C ++.
AnT

Câu trả lời:


262
  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 biên dịch cho nền tảng của bạn và xem để xem.
  3. Nó không thành vấn đề. Đ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.

227
Theo trực giác, tối ưu hóa một vòng lặp vô hạn cung cấp tiềm năng tăng tốc vô hạn. Điều tốt là chúng ta không lập trình về trực giác. :-)
Steven Sudit

5
Tôi cho rằng bạn nói đúng. Tôi nghĩ rằng tôi đã bị cuốn vào các cuộc tranh luận "tôn giáo" về những điều nhỏ nhặt. Cảm ơn đã lay chuyển lương tâm của tôi. : D
Chris Cooper

6
@Steven LOL, thật thú vị, nhưng sau đó hãy xem xét rằng kịch bản duy nhất mà bạn thực sự đạt được tiềm năng tăng tốc vô hạn đó là khi vòng lặp không bao giờ bị hỏng và thực sự chạy vô hạn, có khả năng là một lỗi, hoặc nếu có ý định, sẽ là một sự chờ đợi vô hạn trước khi nó đạt được tiềm năng đó.
AaronLS

7
@Chris. Trong lập trình cũng như trong cuộc sống, các cuộc tranh luận tôn giáo chỉ đáng giá thời gian của bạn cho những điều thực sự quan trọng. Đây không phải là một trong những điều đó. Như bạn có thể thấy, mọi người đều có cách thú cưng để viết một vòng lặp không có hồi kết. Chọn cho mình bất cứ điều gì làm cho bạn hạnh phúc nhất cho những điều nhỏ nhặt, và sau đó chạy trình hồ sơ của bạn về mã quan trọng. :)
Ben Zotto

3
Nó đã thành vấn đề, vì một số trình biên dịch ban đầu trên một số nền tảng đã tải một hằng số và thực hiện một bước nhảy có điều kiện của nó. Mà vào những ngày đó phần cứng, đã làm vấn đề.
peterchen

176

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ác cảnh báo trên while(true)(đại loại như "điều kiện vòng lặp là không đổi"). Tránh cảnh báo luôn là một việc nên làm.

Một điều nữa là tôi nghĩ for(;;)rõ ràng hơn và nói 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 một cái gì đó để thoát ra khỏi nó.

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

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


73
+1 để tránh cảnh báo. Nhưng như để rõ ràng, tôi thấy trong khi rõ ràng hơn trong bối cảnh này. Tôi đoán rằng khía cạnh đó chỉ đến sở thích cá nhân.
Tim

14
Đúng, ưa thích và thói quen. Nếu bạn không quen nhìn for(;;), rõ ràng nó sẽ trông lạ. Nhưng tôi khuyên bạn nên cố gắng làm quen với nó bởi vì đó một thành ngữ phổ biến và bạn sẽ lại gặp phải nó. ;)
jalf

7
bình luận của jalf về nó là thành ngữ thực sự là câu trả lời ở đây. Nó thường được sử dụng cho "vòng lặp vô hạn" đơn giản vì đó cách thường được sử dụng để viết "vòng lặp vô hạn" trong C. Không cần phải có một lý do chính đáng cho một thành ngữ - đó chỉ là một quy ước tự củng cố.
phê

7
@Steve: Tôi không thấy lý do tại sao tôi từng sử dụng for(;condition;). Đó là những gì một vòng lặp while là dành cho . Nhưng như tôi đã nói, với một vòng lặp vô hạn, tôi không thực sự muốn trình biên dịch so sánh bất kỳ điều kiện nào . Rõ ràng , với một whilevòng lặp, nó sẽ phải kiểm tra truemọi lần lặp (rõ ràng, ngay cả trình biên dịch ngu ngốc nhất cũng sẽ làm điều đó, nhưng đó là nguyên tắc làm phiền tôi. Nó gây ấn tượng với tôi khi nói quá mã của bạn), trong khi với for(;;)bạn thì bạn đang nói theo nghĩa đen "không có điều kiện để kiểm tra. Chỉ cần lặp". Tôi thấy nó gần tương đương với tưởng tượng của bạnloop {...}
jalf

32
Trình biên dịch của bạn hút nếu while(true)đưa ra một cảnh báo.
Albert

56

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


38
0, 1 và vô hạn là những con số ma thuật có thể chấp nhận được, kéo dài 0 và 1 thành sai và đúng không phải là một mất mát. truekhông nhiều hơn một con số ma thuật hơn forlà một từ khóa ma thuật hoặc for(;;)sử dụng một phép thuật vô hạn ngụ ý. ( while (42)thực sự là một sự gớm ghiếc.)

38
Tiếp tuyến: một trong những giáo sư CS của tôi đã nói "chỉ có ba số trong lập trình: 0, 1 và n. Mọi thứ khác được gọi là số ma thuật."
Ben Zotto

21
while (42) là tuyệt nhất, không tạo ra kết quả khác với while (1) hoặc while (true) hoặc while (! 0) và có ý nghĩa triết học . Tôi cho rằng for(;;)dù sao cũng được phân tích cú pháp nhanh hơn những người khác
ShinTakezou

2
@ShinTakezou tốt hơn nhiều để #define LIFE 42 while (LIFE):)
mr5

1
cũng while(true)không chứa bất kỳ số nào quá. và cho (;;) không phải là một từ khóa
Rịa

49

Vì Dennis Ritchie

  • Tôi bắt đầu sử dụng for (;;)vì đó là cách Dennis Ritchie thực hiện 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 kẻ thông minh.

  • Đây là C / C ++ thành ngữ. Về lâu dài có lẽ sẽ quen với nó hơn nếu bạn dự định làm nhiều việc trong không gian C / C ++.

  • Bạn #definesẽ không làm việc, vì thứ được xác định là phải giống như định danh C.

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


10
Vâng, đây là cách bạn biết rằng ai đó đã học C từ K & R, cách nó nên được học. Bất cứ khi nào tôi nhìn thấy while(TRUE), tôi nghi ngờ lập trình viên là một người mới C, hoặc đã học C từ một cuốn sách For Dummies.
Kristopher Johnson

13
Tôi nghe những người mới sử dụng phong cách định nghĩa chức năng mới .
Justin

46

Nó chắc chắn không nhanh hơn trong bất kỳ trình biên dịch lành mạnh. Cả hai sẽ được biên soạn 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.

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

Tôi nghi ngờ nó nhanh hơn ngay cả trong chế độ gỡ lỗi.
Steven Sudit

106
for_infinitenhanh hơn; 2 ký tự ít hơn puts.
Dave Jarvis

43

tôi thích for (;;) bởi vì nó phù hợp nhất trong các ngôn ngữ giống như C khác nhau.

Trong C ++ while (true)là tốt, nhưng trong C bạn phụ thuộc vào một tiêu đề để xác định true, nhưng đó 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 phải là boolean, chẳng hạn như while (true)hoặc while (1 == 1). Trong PHP, từ khóa không phân biệt chữ hoa chữ thường nhưng ngôn ngữ thích viết hoa hơnTRUE .

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


9
Cảm ơn câu trả lời của bạn! Tôi nghĩ rằng đây thực sự là câu trả lời đầu tiên cho thấy một cách khách quanfor (;;) tốt hơn.
Chris Cooper

8
Tôi không nghĩ rằng mình đã bao giờ cần phải viết mã đúng bằng C, C ++, JavaScript, Java và C #. Chúng là những ngôn ngữ khác nhau.
Keith Thompson

6
@KeithThndry không phải là viết mã mà đúng trong nhiều ngôn ngữ; Tôi nghĩ rằng đó là về việc tránh giải thích sai giữa các nhà phát triển với các nền tảng khác nhau.
Mauro Sampietro

6
@sam: Cả hai while (1)for (;;)đều là thành ngữ phổ biến cho các vòng lặp vô hạn trong C. Bất kỳ ai đọc chương trình C gặp khó khăn đều có thể gặp rắc rối với phần còn lại của mã. Không đáng để viết mã C có thể dễ dàng đọc được bởi một người không biết C.
Keith Thompson

6
@KeithThndry Trong khi một người đọc có thẩm quyền của C chắc chắn phải quen thuộc với cả hai thành ngữ, điều này cũng có thể hữu ích nếu người viết là một lập trình viên đa âm. Ở công việc cuối cùng của tôi, tôi đã làm việc trong JS, ActionScript và PHP hàng ngày và thống nhất cách viết mã (theo cách hợp lý để làm như vậy) có thể giúp lập trình nhanh hơn và bảo trì dễ dàng hơn.
Ionoclast Brigham

21

Cá nhân tôi thích for (;;)thành ngữ này (sẽ biên dịch thành cùng mã với while (TRUE).

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

Một vòng lặp vô hạn xây dựng nên được một cách dễ dàng nhận thấy hoặc gọi trong mã, và cá nhân tôi nghĩ rằng for (;;)phong cách thực hiện điều này một chút tốt hơn while (TRUE)hay 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 kiểm soát 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ó khả năng cảnh báo giả là đủ để tôi muốn tránh nó.


17

Tôi đã thấy một số người thích nó bởi 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 */
}

24
Tôi cũng đã thấy điều đó; nhưng nó không phải là một lý do tốt để thích nó Là người bảo trì, bạn vẫn phải kiểm tra định nghĩa vĩ mô để chắc chắn rằng nó đã làm những gì bạn mong đợi, trong khi mã ban đầu đủ rõ ràng. RTOS VxWorks có một macro FOREVERđược xác định for(;;), nhưng điều đó không tốt hơn. Các macro IMO không nên được sử dụng để 'phát minh' một ngôn ngữ mới.
Clifford

8
Trên thực tế, mục đích của macro trong một số ngôn ngữ là phát minh ra cú pháp mới. Nhưng bất kể 'for (EVER)' trong C / C ++ là khủng khiếp.
Dan Olson

15
Một số người làm những điều buồn cười, như nếu họ thích Pascal họ nói #define BEGIN {#define END }. Tôi thậm chí đã nhìn thấy #define DONKEYS_FLY (0)để họ có thể nói if DONKEYS_FLY .... Ai nói phần mềm là ngu si đần độn?
Mike Dunlavey

11
Ở California, tôi tin rằng bạn phải #define cho (;;) THÍCH_FOREVER
Martin Beckett

1
Tôi không thể cưỡng lại: #define never while(0)#define always
alfC

16

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

start:
/* BLAH */
goto start;

... sẽ tạo ra đầu ra giống hệt nhau trong tay của bất kỳ trình biên dịch hợp lý nào.
Ben Zotto

9
+1! Nó không cải thiện gotonhiều nhược điểm, nhưng, nếu thuật toán bạn đang cố gắng thực hiện đến từ biểu đồ dòng chảy, thì đây là bản dịch trực tiếp nhất.
Edmund

4
Cá nhân tôi có một cái nhìn thực dụng về goto. Không có raptors. Những kẻ săn lùng là người. Và đó là những người bắt đầu sử dụng goto để tạo mã spaghetti. Ngoài ra, đầu ra lắp ráp cho một vòng lặp trông khá giống như thế này. Các bộ hướng dẫn cho máy tính không có khái niệm "cho" hoặc "trong khi", chỉ "nhảy".
josaphatv

không bao giờ sử dụnggoto
Edward Karak

Điều thực sự tốt đẹp gotolà bạn không phải lo lắng về việc ai đó thêm vào breakđể làm cho vòng lặp của bạn bớt vô hạn. (trừ khi bạn đã ở trong một vòng lặp khác whilehoặc fortất nhiên ...)

12

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

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


6
Điều đó phụ thuộc vào ngôn ngữ của bạn. for(;;)là cách truyền thống để làm điều này trong C và C ++. while(true)dường như là quy ước trong C # và Java và các ngôn ngữ khác. Số dặm của bạn có thể thay đổi.
Billy ONeal

9
Có, và ai đó không quen thuộc với C hoặc C ++ có thể thấy STRING_SCAN_FORMATTED dễ đọc hơn sscanf, nhưng bạn không thấy ai đặt #define STRING_SCAN_FORMATTED sscanf ở đầu mã của họ.
ta.speot.is

4
Tôi muốn nói rằng cách làm thành ngữ đó tốt hơn là dễ đọc nhất đối với nhà phát triển của bạn. Nếu không, bạn thực sự cần các nhà phát triển tốt hơn.
jalf

5
@despart: Nếu ai đó không đủ quen thuộc với C ++ để nhận ra thành ngữ đó cho nó là gì, thì họ cần phải tránh xa cơ sở mã của tôi.
Billy ONeal

4
Tôi đồng ý rằng cách thành ngữ nên dễ đọc nhất. Đó là lý do tại sao các cách thành ngữ luôn cần phải được thách thức và thay đổi khi ngôn ngữ và thực tiễn phát triển. Phải mất nhiều năm để phong cách mã hóa "thành ngữ" K & R khủng khiếp được thay thế bằng phong cách hiện đại, dễ đọc hơn, nhưng nó vẫn xảy ra.
Jason Williams

11

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


3
Vâng, và tôi nghĩ rằng một số trình biên dịch cảnh báo while (true)cho cùng một lý do họ làm if (true).
Steven Sudit

11
while(true)

tạo cảnh báo với Visual Studio (điều kiện không đổi). Hầu hết các 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ác cảnh báo là lỗi. Vì thế

for(;;)

được ưa thích.


7
bạn đang sử dụng phiên bản nào của studio hình ảnh? Với năm 2008, tôi không nhận được cảnh báo này, ngay cả ở mức cảnh báo 4.
Jörgen Sigvardsson

11

Cả hai nên giống nhau nếu mã của bạn được tối ưu hóa bởi trình biên dịch. Để giải thích ý của tôi khi tối ưu hóa, đây là 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ỳ sự tối ưu hóa (/ Od ) nào thì việc tháo gỡ sẽ cho thấy sự khác biệt rõ ràng. Có hướng dẫn thêm cho truetình trạng 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 hóa mặc định (/ O2) ), bạn sẽ nhận được cùng một đầu ra cho cả hai. Cả hai vòng được giảm xuống 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)  

Bất cứ điều gì bạn sẽ sử dụng không quan trọng đối với một trình biên dịch tốt với tối ưu hóa tốc độ được bật.


Đây thực sự là một điểm rất tốt! Không có tối ưu hóa ngay cả các trình biên dịch hiện đại sẽ khác nhau bởi một số hướng dẫn.

9

Đó 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 cảm ứng và không bao giờ nhìn vào bàn phím của mình, trong quá trình lập trình - tôi có thể chạm vào tất cả 104 phím trên bàn phím.

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

Tôi tinh thần thêm một số phép đo chuyển động ngón tay và tổng cộng chúng lên. "for (;;)" có khoảng 12 độ rộng phím di chuyển trở lại và thứ tư (giữa phím home và phím và giữa phím home và phím SHIFT) "trong khi (TRUE)" có khoảng 14 độ rộng phím di chuyển trở lại và thứ tư.

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

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


3
Tôi tin rằng OP đã đề cập đến tốc độ thời gian chạy, không phải tốc độ gõ.

Tôi biết. Chỉ cần phải bao gồm cơ sở đó, quá.
Đánh dấu Rejhon

7
s / sở thích cá nhân / thói quen cá nhân /
SamB

@SamB: Nhận xét bình chọn cho s ///. xD Và vâng, mặc dù tôi đề nghị có thể là do tốc độ thời gian chạy, tôi không biết câu trả lời thực sự. Nếu đây là nó, tôi sẽ có được hạnh phúc.
Chris Cooper

Chạy time head -10 >/dev/null, gõ mỗi lần 10 lần và đo kết quả. Tôi cá là bạn sẽ nhanh hơn for(;;)trừ khi bạn gian lận. Tôi đã được khoảng 14%.
PSkocik

6

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

TUY NHIÊN - Chỉ cần giả sử nó DID tạo ra sự khác biệt. Giả sử một trong số họ mất thêm 3 hướng dẫn 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 trong vòng lặp hầu như không có gì , gần 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".


3
Làm thế nào thường xuyên bạn thấy mọi người nói để thích ++ihơn i++?
Dennis Zickefoose

7
@Dennis Zickefoose: Sự khác biệt giữa ++ii++có khả năng có thể có ý nghĩa nếu ilà một thể hiện của một lớp chứ không phải là một trình biên dịch tích hợp và trình biên dịch không áp dụng tối ưu hóa tầm thường. Lời khuyên là hãy tập thói quen để nó không khiến bạn bị loại khi đếm.
Clifford

5
Vấn đề của ++ivs i++là nó không làm bạn tốn kém gì khi thực hiện "tối ưu hóa". Đúng, trong hầu hết các trường hợp, nó hoàn toàn không có sự khác biệt, nhưng chúng dễ gõ như nhau, vậy tại sao không thích hiệu quả nhất theo mặc định? Và tôi cho rằng điều tương tự áp dụng ở đây. Nếu cái này nhanh hơn cái kia một chút, tại sao không đi cho cái nhanh hơn? Chúng ta sẽ mất gì khi làm điều đó? Cả hai đều khá dễ đọc và gõ.
jalf

2
@Dennis Zickefoose: Bạn nói đúng. Tôi thấy rằng rất nhiều về SO, và nhận xét của Clifford là đúng. Ngoài ra, có một thứ tôi không thấy nhiều trên SO, và đó là cách thực hiện tối ưu hóa vĩ mô, như tăng tốc 43x: stackoverflow.com/questions/926266/ . Vì vậy, tôi tự hỏi về các ưu tiên của chúng tôi.
Mike Dunlavey

2
@Mike: Vâng, nhưng đó là một so sánh táo với cam. Cắt tóc mất thời gian thực tế, và thậm chí có thể là tiền. Tôi đồng ý rằng đó là một sự vi mô hóa đến mức nó không thực sự quan trọng. Nhưng nó cũng không tốn bất cứ thứ gì. Nếu tôi có thể chọn đi sang trái hoặc phải và khoảng cách là như nhau, địa hình là như nhau, mọi thứ đều giống nhau, ngoại trừ đường bên trái có một số lợi ích hiển vi cận biên, tại sao không đi bên trái? Bạn nói đúng, đó không phải là một cuộc tranh luận ấn tượng. Nhưng khi chi phí theo nghĩa đen bằng không, tôi thấy không có lý do gì để thích con đường ít tối ưu hơn.
jalf

5

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 nhau. Ngay cả nếu có, sẽ không có cách nào xác định nếu không kiểm tra trình biên dịch cụ thể 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 mà tôi đã sử dụng sẽ tạo ra một cảnh báo biểu thức không đổi trong khi (true) với các cài đặt mức cảnh báo phù 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 .; do đó for(;;)có khả năng dẫn đến tính nhất quán cao hơn.


TRUE có thể không phải là #define TRUE 1, nhưng bất kỳ cơ sở mã nào trong đó while(TRUE)đánh giá while(0)là không có khả năng được hưởng lợi for(;;).
Justin

@Justin: Tôi đồng ý, nó sẽ thực sự đồi trụy và nó không phải là đối số mạnh nhất trong ba đối số, nhưng Bjarne Stoustrup sử dụng một đối số tương tự để tránh macro NULL trong C ++. while(true)nên được ưu tiên trong mọi trường hợp. Trong C ++ boolđược bảo lưu và trong C được định nghĩa trong C stdbool.h (làm cho nó kém an toàn hơn trong C). for(;;)xóa bỏ mọi nghi ngờ.
Clifford

5
for(;;Sleep(50))
{
    // Lots of code
}

Là rõ ràng hơn:

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

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


1
Đó là mã xấu chết tiệt, nên sử dụng bộ đếm thời gian thay vì ngủ, vì vậy đây là ví dụ tồi
ST3

12
@ ST3 - Vâng, bạn đúng. Mã của tôi là khủng khiếp. Tôi nên cố gắng hơn nữa vào lần tới khi tôi thực hiện một vòng lặp vô hạn.
Armada

1
@Frammo - phụ thuộc vào hệ điều hành của bạn, nhưng thường là như thếtimerService.scheduleRepeating (50, [] () { /* lots of code */ });
Periata Breatta

2
Không có gì rõ ràng khi gọi một chức năng như ngủ bên trong một vòng lặp for như thế
Greg

1
OMG, timerService.scheduleRepeat (50, [] () {}) chỉ đơn giản là dễ dàng hơn nhiều để gõ và hiểu sau đó ngủ (50).
Cool Javelin

4

Vòng lặp "mãi mãi" phổ biến trong các hệ thống nhúng dưới dạng 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 */);

Một trình biên dịch tối ưu hóa sẽ tạo ra mã lắp ráp tương tự hoặc tương tự cho các đ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 cứ kéo dài mãi mãi và dành nhiều thời gian hơn cho phần xử lý.


8
Nếu một trình biên dịch tạo mã khác nhau cho các mã đó, đã đến lúc bỏ trình biên dịch và lấy một mã từ hai thập kỷ qua.
GManNickG

5
"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 cứ kéo dài mãi mãi" - điều đó nghe có vẻ không ổn với tôi ..
Blindy

3
@Blindy - bởi vì nó sai, điều đáng quan tâm là phần thời gian chạy dành cho xử lý logic vòng lặp hoặc số lượng logic vòng lặp trên mỗi đơn vị công việc hữu ích, không được trợ giúp bởi vòng lặp là vô hạn
Ben Voigt

3

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


Tôi quan tâm đến tốc độ. Đặc biệt là nếu có một tối ưu hóa sẽ ảnh hưởng đến mã của tôi vô hạn.
Cửu Long

2

Lý do quan trọng nhất để sử dụng "for (;;)" là nỗi sợ sử dụng "while (TRUE)" khi bạn thực hiệ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 đổi 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 cuộc gọi đến 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ề chức năng của mình, sau đó tôi chuyển đổi nó thành một vòng lặp vô hạn:

    for(;;) recursiveFunction(oneParam);

3
Vòng lặp đầu tiên có lỗi cú pháp (thiếu dấu chấm phẩy).
Jens

3
Hà! Qua đó thể hiện mặt trái của for (;;);)
Andrew
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.