Apakah "untuk (;;)" lebih cepat dari "sementara (BENAR)"? Jika tidak, mengapa orang menggunakannya?

164
for (;;) {
    //Something to be done repeatedly
}

Saya telah melihat hal semacam ini banyak digunakan, tetapi saya pikir ini agak aneh ... Bukankah lebih jelas untuk mengatakannya while(true), atau sesuatu seperti itu?

Saya menduga bahwa (seperti alasan banyak programmer untuk menggunakan kode samar) ini adalah margin kecil lebih cepat?

Mengapa, dan apakah itu sangat berharga? Jika demikian, mengapa tidak mendefinisikannya seperti ini:

#define while(true) for(;;)

Lihat juga: Mana yang lebih cepat: while (1) atau while (2)?

Chris Cooper
sumber
51
Apa TRUE???
AnT
20
@ Seven Sudit: Apa yang TRUEharus dilakukan dengan C? Makro standar untuk hasil boolen benar di C99 masih true. Dari mana TRUEdatangnya?
AnT
31
Makro itu tidak berfungsi, #define EVER ;;telah digunakan di IOCCC .. :)
18
Bukankah itu makro untuk #define while(TRUE)mendeklarasikan makro yang mengambil satu argumen yang disebut TRUEtidak pernah digunakan, oleh karena itu mengubah setiap loop sementara di program Anda ke loop tak terbatas?
AshleysBrain
9
@Steven Sudit: Tidak. Tidak ada "makro standar di VS 6.0". Makro TRUEberasal dari file header yang terkait dengan Windows API. Ini tidak terkait dengan VS 6.0 dengan cara apa pun. Dan, seperti yang saya katakan sebelumnya, itu tidak ada hubungannya dengan C atau C ++. Dalam C ++ literal "benar" adalah adil true(dalam VS 6.0 juga), dalam C89 / 90 tidak ada hal seperti itu sama sekali, dan dalam C99 itu adalah makro true. Ini berlaku untuk semua kompiler C / C ++.
AnT

Jawaban:

262
  1. Itu tidak lebih cepat.
  2. Jika Anda benar-benar peduli, kompilasi dengan output assembler untuk platform Anda dan lihat untuk melihat.
  3. Itu tidak masalah. Ini tidak masalah. Tulis loop tak terbatas Anda sesuka Anda.
Ben Zotto
sumber
227
Secara intuitif, mengoptimalkan loop tak terbatas menawarkan potensi untuk mempercepat tak terbatas. Untung kita tidak memprogram intuisi. :-)
Steven Sudit
5
Saya kira kamu benar. Saya pikir saya terjebak dalam debat "agama" tentang hal-hal kecil. Terima kasih telah mengguncang hati nurani saya. : D
Chris Cooper
6
@ Seven LOL, itu menarik, tetapi kemudian pertimbangkan bahwa satu-satunya skenario di mana Anda benar-benar mencapai potensi percepatan tak terbatas adalah ketika loop tidak pernah putus dan benar-benar berjalan tanpa batas, yang kemungkinan adalah bug, atau jika dimaksudkan, akan menjadi menunggu tanpa batas sebelum mencapai potensi itu.
AaronLS
7
@ Chris. Dalam pemrograman seperti dalam hidup, perdebatan agama hanya sepadan dengan waktu Anda untuk hal-hal yang benar-benar penting. Ini bukan salah satu dari hal-hal itu. Seperti yang Anda lihat, setiap orang memiliki cara kesayangan untuk menulis loop tanpa akhir. Pilih sendiri apa pun yang membuat Anda paling bahagia untuk hal-hal kecil, dan kemudian jalankan profiler Anda pada kode yang penting. :)
Ben Zotto
3
Itu penting, karena beberapa kompiler awal pada beberapa platform memuat konstanta dan membuat lompatan bersyarat. Yang pada perangkat keras hari itu, memang penting.
peterchen
176

saya lebih memilih for(;;) karena dua alasan.

Salah satunya adalah bahwa beberapa kompiler menghasilkan peringatan while(true) (sesuatu seperti "kondisi loop konstan"). Menghindari peringatan selalu merupakan hal yang baik untuk dilakukan.

Lain adalah bahwa saya pikir for(;;)lebih jelas dan lebih jitu. Saya ingin loop tanpa batas. Secara harfiah memiliki tidak kondisi, itu tidak bergantung pada apa pun. Saya hanya ingin itu berlanjut selamanya, sampai saya melakukan sesuatu untuk keluar darinya.

Padahal dengan while(true) , yah, apa yang sebenarnya harus dilakukan dengan apa pun? Saya tidak tertarik pada perulangan sampai benar menjadi salah, yang secara formal dikatakan oleh bentuk ini (perulangan sementara benar adalah benar). Saya hanya ingin mengulang.

Dan tidak, sama sekali tidak ada perbedaan kinerja.

jalf
sumber
73
+1 untuk menghindari peringatan. Tetapi untuk kejelasan, saya menemukan sementara lebih jelas daripada untuk dalam konteks ini. Saya kira aspek itu hanya turun ke preferensi pribadi.
Tim
14
Yap, preferensi dan kebiasaan. Jika Anda tidak terbiasa melihat for(;;), itu pasti akan terlihat aneh. Tapi saya sarankan mencoba membiasakan diri karena itu adalah idiom umum, dan Anda akan bertemu dengannya lagi. ;)
jalf
7
Komentar jalf tentang hal itu menjadi idiomatik benar-benar jawabannya di sini. Ini biasanya digunakan untuk "infinite loop" hanya karena itu adalah cara yang umum digunakan untuk menulis "infinite loop" dalam C. Tidak harus ada alasan yang baik untuk idiom - itu hanya konvensi yang memperkuat diri sendiri.
caf
7
@Steve: Saya tidak melihat mengapa saya pernah menggunakan for(;condition;). Itulah yang sementara loop adalah untuk . Tapi seperti saya katakan, dengan loop tak terbatas, saya tidak benar-benar ingin kompiler membandingkan kondisi apa pun . Secara naif, dengan sebuah whileloop, ia harus menguji truesetiap iterasi (jelas, bahkan kompiler paling bodoh pun tidak akan melakukan itu, tetapi itu adalah prinsip yang menggangguku. Itu menurut saya terlalu melebih-lebihkan kode Anda), sementara dengan for(;;)Anda secara harfiah mengatakan "Tidak ada kondisi untuk diuji. Hanya loop". Saya menemukan itu setara dengan imajiner Andaloop {...}
jalf
32
Kompiler Anda payah jika while(true)memberi peringatan.
Albert
56

Secara pribadi saya menggunakan for (;;)karena tidak ada angka di dalamnya, itu hanya kata kunci. Saya lebih suka untuk while (true), while (1), while (42), while (!0)dll dll

ta.speot.is
sumber
38
0, 1, dan tak terhingga adalah angka ajaib yang dapat diterima, memperluas 0 dan 1 menjadi false dan true bukan kerugian. truetidak lebih dari angka ajaib daripada forkata kunci ajaib atau yang for(;;)menggunakan tak terhingga sihir tersirat. ( while (42)memang kekejian.)
38
Tangent: salah satu profesor CS saya mengatakan "hanya ada tiga angka dalam pemrograman: 0, 1, dan n. Yang lainnya disebut angka ajaib."
Ben Zotto
21
sementara (42) adalah yang paling keren, tidak menghasilkan hasil yang berbeda sehubungan dengan while (1) atau while (true) atau while (! 0), dan memiliki makna filosofis . Saya kira for(;;)diurai lebih cepat dari yang lain
ShinTakezou
2
@ShinTakezou jauh lebih baik untuk #define LIFE 42 while (LIFE):)
mr5
1
juga while(true)tidak mengandung nomor apa pun juga. dan untuk (;;) bukan kata kunci
RiaD
49

Karena Dennis Ritchie

  • Saya mulai menggunakan for (;;)karena itulah yang dilakukan Dennis Ritchie di K&R, dan ketika belajar bahasa baru saya selalu mencoba meniru orang-orang pintar.

  • Ini adalah C / C ++ idiomatik. Ini mungkin lebih baik dalam jangka panjang untuk terbiasa jika Anda berencana untuk melakukan banyak hal di ruang C / C ++.

  • Anda #define tidak akan berfungsi, karena hal yang menjadi # define harus terlihat seperti pengidentifikasi C.

  • Semua kompiler modern akan menghasilkan kode yang sama untuk kedua konstruk tersebut.

Mark Harrison
sumber
10
Ya, ini adalah bagaimana Anda tahu bahwa seseorang belajar C dari K&R, cara itu harus dipelajari. Setiap kali saya melihat while(TRUE), saya curiga programmer adalah pemula C, atau belajar C dari buku For Dummies.
Kristopher Johnson
13
Saya mendengar para pemula menggunakan gaya definisi fungsi bermodel baru juga.
Justin
46

Ini tentu tidak lebih cepat di kompiler waras. Keduanya akan dikompilasi menjadi lompatan tanpa syarat. Untuk versi lebih mudah untuk mengetik (seperti kata Neil) dan akan menjadi jelas jika Anda mengerti sintaks loop.

Jika Anda penasaran, inilah yang diberikan gcc 4.4.1 kepada saya untuk x86. Keduanya menggunakan instruksi x86 JMP .

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

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

mengkompilasi ke (sebagian):

.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
Matthew Flaschen
sumber
Saya ragu ini lebih cepat bahkan dalam mode debug.
Steven Sudit
106
for_infinitelebih cepat; 2 karakter lebih sedikit puts.
Dave Jarvis
43

saya lebih memilih for (;;) karena ini paling konsisten di berbagai bahasa mirip-C.

Dalam C ++ while (true)baik-baik saja, tetapi dalam C Anda bergantung pada header untuk didefinisikan true, namun TRUEjuga makro yang umum digunakan. Jika Anda menggunakannya while (1)benar dalam C dan C ++, dan JavaScript, tetapi bukan Java atau C #, yang mengharuskan kondisi loop menjadi boolean, seperti while (true)atau while (1 == 1). Dalam PHP, kata kunci tidak peka huruf besar-kecil tetapi bahasanya lebih suka huruf besarTRUE .

Namun, for (;;)selalu sepenuhnya benar dalam semua bahasa tersebut.

Boann
sumber
9
Terima kasih atas jawaban anda! Saya pikir ini sebenarnya jawaban pertama yang menunjukkan cara obyektif yang for (;;)lebih baik.
Chris Cooper
8
Saya rasa saya tidak perlu menulis kode yang benar dalam C, C ++, JavaScript, Java, dan C #. Mereka bahasa yang berbeda.
Keith Thompson
6
@KeithThompson ini bukan tentang menulis kode yang benar dalam banyak bahasa; Saya pikir ini adalah tentang menghindari salah tafsir antara pengembang dengan latar belakang yang berbeda.
Mauro Sampietro
6
@sam: Keduanya while (1)dan for (;;)merupakan idiom umum untuk loop tak terhingga dalam C. Siapa pun yang membaca program C yang kesulitan memahami kemungkinan besar akan mengalami masalah dengan sisa kode. Tidak ada gunanya menulis kode C yang dapat dengan mudah dibaca oleh seseorang yang tidak tahu C.
Keith Thompson
6
@KeithThompson Sementara pembaca yang kompeten dari C pasti harus terbiasa dengan kedua idiom, ini juga bisa berguna jika penulis adalah seorang programmer polyglot. Di pekerjaan terakhir saya, saya bekerja di JS, ActionScript, dan PHP setiap hari, dan menyatukan cara seseorang menulis kode (di mana masuk akal untuk melakukannya) dapat membuat pemrograman lebih cepat dan pemeliharaan lebih mudah.
Ionoclast Brigham
21

Saya pribadi lebih suka for (;;)idiom (yang akan dikompilasi dengan kode yang sama denganwhile (TRUE) .

Menggunakan while (TRUE)mungkin lebih mudah dibaca di satu sisi, saya telah memutuskan untuk menggunakan for (;;)idiom karena menonjol .

Konstruk infinite loop harus mudah dilihat atau dipanggil dalam kode, dan saya pribadi berpendapat bahwa for (;;)style ini sedikit lebih baik daripada while (TRUE)atauwhile (1) .

Juga, saya ingat bahwa beberapa kompiler mengeluarkan peringatan ketika ekspresi pengontrol loop sementara adalah konstan. Saya tidak berpikir itu terjadi terlalu banyak, tetapi hanya potensi peringatan palsu sudah cukup bagi saya untuk ingin menghindarinya.

Michael Burr
sumber
17

Saya telah melihat beberapa orang lebih menyukainya karena mereka memiliki #define di suatu tempat seperti ini:

#define EVER ;;

Yang memungkinkan mereka untuk menulis ini:

for (EVER)
{
    /* blah */
}
rmeador
sumber
24
Saya juga pernah melihatnya; tetapi itu bukan alasan yang baik untuk memilihnya. Sebagai pengelola, Anda masih harus memeriksa definisi makro untuk memastikan bahwa itu melakukan apa yang Anda harapkan, sedangkan kode asli cukup jelas. RTOS VxWorks memiliki FOREVERdefinisi makro for(;;), tetapi itu tidak lebih baik. Makro IMO tidak boleh digunakan untuk 'menciptakan' bahasa baru.
Clifford
8
Sebenarnya tujuan makro dalam beberapa bahasa adalah untuk menciptakan sintaks baru. Tapi terlepas dari 'untuk (PERNAH)' di C / C ++ itu keji.
Dan Olson
15
Beberapa orang melakukan hal-hal lucu, seperti jika mereka suka Pascal yang mereka katakan #define BEGIN {dan #define END }. Aku bahkan sudah melihatnya #define DONKEYS_FLY (0)sehingga mereka bisa mengatakannya if DONKEYS_FLY .... Siapa bilang perangkat lunak itu membosankan?
Mike Dunlavey
11
Di California saya percaya Anda, Anda harus #define untuk (;;) LIKE_FOREVER
Martin Beckett
1
Saya tidak bisa menahan: #define never while(0)dan#define always
alfC
16

Bagaimana dengan (jika bahasa Anda mendukungnya):

start:
/* BLAH */
goto start;
mengerjakan dgn kurang baik
sumber
... yang seharusnya menghasilkan output yang identik di tangan setiap kompiler yang masuk akal.
Ben Zotto
9
+1! Ini tidak memperbaiki gotobanyak kelemahan tetapi, jika algoritma yang Anda coba implementasikan berasal dari diagram alur, ini adalah terjemahan yang paling langsung.
Edmund
4
Saya pribadi mengambil pandangan utilitarian tentang goto. Tidak ada raptor. Raptor adalah orang-orang. Dan orang-oranglah yang mulai menggunakan goto untuk membuat kode spageti. Juga, output yang dirangkai untuk sebuah loop terlihat sangat mirip seperti ini. Set instruksi untuk komputer tidak memiliki konsep "untuk" atau "sementara", hanya "melompat".
josaphatv
tidak pernah menggunakangoto
Edward Karak
Yang benar-benar menyenangkan gotoadalah Anda tidak perlu khawatir tentang seseorang menambahkan breakuntuk membuat loop Anda semakin tak terbatas. (kecuali jika Anda sudah berada di dalam lingkaran lain whileatau fortentu saja ...)
12

Tidak ada perbedaan dalam hal kode mesin yang dihasilkan.

Namun, hanya untuk melawan tren, saya berpendapat bahwa bentuk sementara (BENAR) jauh lebih mudah dibaca dan intuitif daripada untuk; Saya telah mendengar untuk pendekatan for (;;) (Saya lebih suka mendasarkan pedoman pengkodean saya pada alasan yang kuat dan / atau bukti keefektifan diri saya sendiri).

Jason Williams
sumber
6
Itu tergantung pada bahasa Anda. for(;;)adalah cara tradisional untuk melakukan ini dalam C dan C ++. while(true)tampaknya menjadi konvensi dalam bahasa C # dan Java dan lainnya. Jarak tempuh Anda mungkin beragam.
Billy ONeal
9
Ya, dan seseorang yang tidak terlalu mengenal C atau C ++ mungkin menemukan STRING_SCAN_FORMATTED lebih mudah dibaca daripada sscanf, tetapi Anda tidak melihat ada orang yang menempatkan #define STRING_SCAN_FORMATTED sscanf di bagian atas kode mereka.
ta.speot.is
4
Saya akan mengatakan cara idiomatis untuk melakukannya sebaiknya yang paling mudah dibaca oleh pengembang Anda. Kalau tidak, Anda benar-benar membutuhkan pengembang yang lebih baik.
Jalf
5
@ Bagian: Jika seseorang tidak cukup akrab dengan C + + untuk mengenali idiom itu untuk apa itu, maka mereka perlu menjauh dari basis kode saya.
Billy ONeal
4
Saya setuju bahwa cara idiomatik seharusnya menjadi yang paling mudah dibaca. Itulah sebabnya cara-cara idiomatis selalu perlu ditantang dan diubah seiring perkembangan bahasa dan praktik. Butuh bertahun-tahun untuk gaya pengkodean "idiomatik" K&R yang mengerikan digantikan oleh gaya modern yang lebih mudah dibaca, tetapi itu masih terjadi.
Jason Williams
11

Bukan hanya pola yang terkenal, tetapi idiom standar dalam C (dan C ++)

James McLeod
sumber
3
Ya, dan saya pikir beberapa kompiler memperingatkan while (true)karena alasan yang sama mereka lakukan if (true).
Steven Sudit
11
while(true)

menghasilkan peringatan dengan Visual Studio (kondisinya konstan). Sebagian besar tempat saya bekerja mengkompilasi build produksi dengan peringatan sebagai kesalahan. Begitu

for(;;)

lebih disukai.

Michael
sumber
7
versi studio visual apa yang Anda gunakan? Dengan 2008 saya tidak mendapatkan peringatan ini, bahkan pada tingkat peringatan 4.
Jörgen Sigvardsson
11

Keduanya harus sama jika kode Anda dioptimalkan oleh kompiler. Untuk menjelaskan apa yang saya maksud dengan optimasi, berikut ini contoh kode yang ditulis dalam MSVC 10:

int x = 0;

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

    printf("%d", x);
}

Jika Anda membangunnya dalam mode Debug ( tanpa optimasi apa pun (/ Od) ) pembongkaran menunjukkan perbedaan yang jelas. Ada instruksi tambahan untuk truekondisi di dalam 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)  

Namun, jika Anda membuat kode dalam mode Rilis (dengan Kecepatan Maksimalkan default (/ O2) ) Anda mendapatkan output yang sama untuk keduanya. Kedua loop dikurangi menjadi satu instruksi lompatan.

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)  

Apa pun yang akan Anda gunakan tidak masalah untuk kompiler yang layak dengan optimisasi kecepatan aktif.

SylvanBlack
sumber
Ini sebenarnya poin yang sangat bagus! Tanpa optimasi, bahkan kompiler modern akan berbeda dengan beberapa instruksi.
9

Ini masalah preferensi pribadi mana yang lebih cepat. Secara pribadi, saya seorang touchtypist dan tidak pernah melihat keyboard saya, selama pemrograman - saya dapat menyentuh semua 104 tombol pada keyboard saya.

Saya menemukan jika lebih cepat mengetik "while (TRUE)".

Saya secara mental menambahkan beberapa pengukuran gerakan jari dan menjumlahkannya. "for (;;)" memiliki sekitar 12 lebar tombol dari gerakan ke belakang dan keempat (antara tombol beranda dan tombol, dan antara tombol beranda dan tombol SHIFT) "sementara (TRUE)" memiliki sekitar 14 lebar tombol gerakan ke belakang dan ke belakang. keempat.

Namun, saya jauh lebih rentan kesalahan saat mengetik yang terakhir. Saya secara mental berpikir dalam kata-kata pada suatu waktu, jadi saya merasa lebih cepat untuk mengetik hal-hal seperti "nIndex" daripada akronim seperti "nIdx" karena saya harus benar-benar secara mental mengeja huruf daripada berbicara di dalam pikiran saya dan membiarkan jari-jari saya otomatis -tip kata (seperti naik sepeda)

(Patokan TypingTest.com saya = 136 WPM)

Mark Rejhon
sumber
3
Saya percaya OP mengacu pada kecepatan runtime, bukan kecepatan mengetik.
Aku tahu. Hanya harus menutupi pangkalan itu juga.
Mark Rejhon
7
s / preferensi pribadi / kebiasaan individu /
SamB
@ SamB: Beri komentar suara untuk s ///. xD Dan ya, meskipun saya menyarankan mungkin karena kecepatan runtime, saya tidak tahu jawaban yang sebenarnya. Jika ini dia, saya pasti senang.
Chris Cooper
Jalankan time head -10 >/dev/null, ketik setiap 10 kali, dan ukur hasilnya. Saya yakin Anda akan lebih cepat for(;;)kecuali Anda menipu. Saya sekitar 14%.
PSkocik
6

Semua jawaban yang baik - perilaku harus persis sama.

NAMUN - Anggap saja APA membuat perbedaan. Misalkan salah satu dari mereka mengambil 3 instruksi lagi per iterasi.

Haruskah kamu peduli?

HANYA jika apa yang Anda lakukan di dalam loop hampir tidak ada , yang hampir tidak pernah terjadi.

Maksud saya adalah, ada optimasi mikro dan optimasi makro. Optimalisasi mikro seperti "memotong rambut untuk menurunkan berat badan".

Mike Dunlavey
sumber
3
Seberapa sering Anda melihat orang-orang disuruh memilih ++ilebih i++?
Dennis Zickefoose
7
@ Dennis Zickefoose: Perbedaan antara ++idan i++berpotensi menjadi signifikan jika iadalah turunan dari kelas daripada built-in dan kompiler tidak menerapkan optimasi sepele. Sarannya adalah untuk mendapatkan kebiasaan sehingga tidak akan menangkap Anda ketika itu penting.
Clifford
5
Hal tentang ++ivs i++adalah bahwa Anda tidak perlu mengeluarkan biaya apa pun untuk melakukan "optimasi". Benar, dalam banyak kasus sama sekali tidak ada bedanya, tetapi mereka sama-sama mudah diketik, jadi mengapa tidak lebih suka yang paling efisien secara potensial? Dan saya kira hal yang sama berlaku di sini. Jika salah satu adalah sedikit lebih cepat dari yang lain, mengapa tidak pergi untuk lebih cepat satu? Apa yang akan kita ruguhkan dengan melakukannya? Keduanya cukup mudah dibaca dan diketik.
jalf
2
@ Dennis Zickefoose: Anda benar. Saya melihat banyak hal di SO, dan komentar Clifford benar. Selain itu, ada sesuatu yang tidak saya lihat banyak di SO, dan itu adalah bagaimana melakukan optimasi makro, seperti speedup 43x: stackoverflow.com/questions/926266/… . Jadi saya bertanya-tanya tentang prioritas kami.
Mike Dunlavey
2
@ Mike: Ya, tapi itu perbandingan apel dengan jeruk. Mendapatkan potongan rambut membutuhkan waktu aktual, dan bahkan mungkin uang. Saya setuju itu adalah optimasi mikro yang tidak terlalu penting. Tetapi itu juga tidak membebani kita apa-apa. jika saya dapat memilih untuk pergi ke kiri atau kanan, dan jaraknya sama, medannya sama, semuanya sama, kecuali bahwa jalur kiri memiliki beberapa manfaat mikroskopis marjinal, mengapa tidak ke kiri? Anda benar, itu bukan argumen yang mengesankan. Tetapi ketika biaya secara harfiah nol, saya tidak melihat alasan untuk memilih rute yang kurang optimal.
Jalf
5

Saya tidak dapat membayangkan bahwa kompiler yang berharga akan menghasilkan kode yang berbeda. Bahkan jika itu terjadi, tidak akan ada cara untuk menentukan tanpa menguji kompiler tertentu yang lebih efisien.

Namun saya sarankan Anda lebih suka for(;;)karena alasan berikut:

  • sejumlah kompiler yang saya gunakan akan menghasilkan peringatan ekspresi konstan untuk sementara (benar) dengan pengaturan tingkat peringatan yang sesuai.

  • dalam contoh Anda, makro yang BENAR mungkin tidak didefinisikan seperti yang Anda harapkan

  • ada banyak kemungkinan varian terbatas sementara lingkaran seperti while(1), while(true), while(1==1)dll .; sehingga for(;;)cenderung menghasilkan konsistensi yang lebih besar.

Clifford
sumber
TRUE mungkin bukan #define TRUE 1, tetapi basis kode apa pun yang while(TRUE)dievaluasi sebagai while(0)tidak mungkin mendapat manfaat for(;;).
Justin
@Justin: Saya setuju, itu akan benar-benar menyimpang, dan itu bukan yang terkuat dari tiga argumen, tetapi Bjarne Stoustrup menggunakan argumen serupa untuk menghindari makro NULL di C ++. while(true)harus disukai dalam hal apa pun. Dalam C ++ booldicadangkan, dan dalam C didefinisikan dalam C stdbool.h (membuatnya kurang aman di C). for(;;)menghapus semua keraguan.
Clifford
5
for(;;Sleep(50))
{
    // Lots of code
}

Lebih jelas dari:

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

Bukan berarti ini berlaku jika Anda tidak menggunakan Sleep().

Armada
sumber
1
Ini kode yang sangat buruk, penghitung waktu harus digunakan alih-alih tidur, jadi ini adalah contoh yang buruk
ST3
12
@ ST3 - Ya, Anda benar. Kode saya buruk. Saya harus berusaha lebih keras saat berikutnya saya membuat loop tak terbatas.
Armada
1
@Frammo - tergantung pada OS Anda, tetapi biasanya sesuatu sepertitimerService.scheduleRepeating (50, [] () { /* lots of code */ });
Periata Breatta
2
Tidak ada yang bersih tentang memanggil fungsi seperti tidur di dalam for for loop seperti itu
Greg
1
OMG, timerService.scheduleRepeating (50, [] () {}) sangat mudah untuk diketik dan dipahami daripada tidur (50).
Cool Javelin
4

Loop "selamanya" populer di sistem embedded sebagai loop latar belakang. Beberapa orang menerapkannya sebagai:

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

Dan terkadang itu diimplementasikan sebagai:

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

Dan implementasi lain adalah:

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

Kompiler pengoptimalisasi harus menghasilkan kode perakitan yang sama atau serupa untuk fragmen ini. Satu catatan penting: waktu eksekusi untuk loop bukan masalah besar karena loop ini berlangsung selamanya, dan lebih banyak waktu dihabiskan di bagian pemrosesan.

Thomas Matthews
sumber
8
Jika kompiler membuat kode yang berbeda untuk mereka, saatnya untuk membuang kompiler dan mendapatkannya dari dua dekade terakhir.
GManNickG
5
"waktu eksekusi untuk loop bukan masalah besar karena loop ini berlangsung selamanya" - itu terdengar sangat salah bagi saya ..
Blindy
3
@ Blindy - karena itu salah, yang perlu diperhatikan adalah fraksi runtime yang dihabiskan untuk memproses logika perulangan, atau jumlah logika perulangan per unit pekerjaan yang bermanfaat, yang tidak satu pun terbantu oleh loop yang tidak terbatas
Ben Voigt
3

Saya berasumsi while (true) lebih mudah dibaca daripada for (;;) - sepertinya programmer melewatkan sesuatu untuk loop :)

nik
sumber
Saya peduli kecepatan. Apalagi jika ada optimasi yang akan mempengaruhi kode saya kali tak terbatas.
Kowalski
2

Alasan paling penting untuk menggunakan "for (;;)" adalah ketakutan untuk menggunakan "while (TRUE)" ketika Anda melakukan pemrograman eksplorasi. Lebih mudah untuk mengontrol jumlah pengulangan dengan "untuk", dan juga, lebih mudah untuk mengubah loop "untuk" menjadi tak terbatas.

Misalnya, jika Anda membuat fungsi rekursif, Anda dapat membatasi jumlah panggilan ke fungsi sebelum mengubahnya menjadi loop tak terbatas.

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

Ketika saya yakin dengan fungsi saya, maka saya mengonversinya menjadi loop tanpa batas:

    for(;;) recursiveFunction(oneParam);
Ignacio Cortorreal
sumber
3
Loop pertama memiliki kesalahan sintaksis (tidak ada tanda titik koma).
Jens
3
Ha! Dengan demikian menunjukkan sisi buruk untuk (;;);)
Andrew