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)?
c++
c
optimization
readability
infinite-loop
Chris Cooper
sumber
sumber
TRUE
???TRUE
harus dilakukan dengan C? Makro standar untuk hasil boolen benar di C99 masihtrue
. Dari manaTRUE
datangnya?#define EVER ;;
telah digunakan di IOCCC .. :)#define while(TRUE)
mendeklarasikan makro yang mengambil satu argumen yang disebutTRUE
tidak pernah digunakan, oleh karena itu mengubah setiap loop sementara di program Anda ke loop tak terbatas?TRUE
berasal 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 adiltrue
(dalam VS 6.0 juga), dalam C89 / 90 tidak ada hal seperti itu sama sekali, dan dalam C99 itu adalah makrotrue
. Ini berlaku untuk semua kompiler C / C ++.Jawaban:
sumber
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.
sumber
for(;;)
, itu pasti akan terlihat aneh. Tapi saya sarankan mencoba membiasakan diri karena itu adalah idiom umum, dan Anda akan bertemu dengannya lagi. ;)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 sebuahwhile
loop, ia harus mengujitrue
setiap 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 denganfor(;;)
Anda secara harfiah mengatakan "Tidak ada kondisi untuk diuji. Hanya loop". Saya menemukan itu setara dengan imajiner Andaloop {...}
while(true)
memberi peringatan.Secara pribadi saya menggunakan
for (;;)
karena tidak ada angka di dalamnya, itu hanya kata kunci. Saya lebih suka untukwhile (true)
,while (1)
,while (42)
,while (!0)
dll dllsumber
true
tidak lebih dari angka ajaib daripadafor
kata kunci ajaib atau yangfor(;;)
menggunakan tak terhingga sihir tersirat. (while (42)
memang kekejian.)for(;;)
diurai lebih cepat dari yang lain#define LIFE 42
while (LIFE)
:)while(true)
tidak mengandung nomor apa pun juga. dan untuk (;;) bukan kata kunciKarena 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.
sumber
while(TRUE)
, saya curiga programmer adalah pemula C, atau belajar C dari buku For Dummies.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 .
mengkompilasi ke (sebagian):
sumber
for_infinite
lebih cepat; 2 karakter lebih sedikitputs
.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 didefinisikantrue
, namunTRUE
juga makro yang umum digunakan. Jika Anda menggunakannyawhile (1)
benar dalam C dan C ++, dan JavaScript, tetapi bukan Java atau C #, yang mengharuskan kondisi loop menjadi boolean, sepertiwhile (true)
atauwhile (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.sumber
for (;;)
lebih baik.while (1)
danfor (;;)
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.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 menggunakanfor (;;)
idiom karena menonjol .Konstruk infinite loop harus mudah dilihat atau dipanggil dalam kode, dan saya pribadi berpendapat bahwa
for (;;)
style ini sedikit lebih baik daripadawhile (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.
sumber
Saya telah melihat beberapa orang lebih menyukainya karena mereka memiliki #define di suatu tempat seperti ini:
Yang memungkinkan mereka untuk menulis ini:
sumber
FOREVER
definisi makrofor(;;)
, tetapi itu tidak lebih baik. Makro IMO tidak boleh digunakan untuk 'menciptakan' bahasa baru.#define BEGIN {
dan#define END }
. Aku bahkan sudah melihatnya#define DONKEYS_FLY (0)
sehingga mereka bisa mengatakannyaif DONKEYS_FLY ...
. Siapa bilang perangkat lunak itu membosankan?#define never while(0)
dan#define always
Bagaimana dengan (jika bahasa Anda mendukungnya):
sumber
goto
banyak kelemahan tetapi, jika algoritma yang Anda coba implementasikan berasal dari diagram alur, ini adalah terjemahan yang paling langsung.goto
goto
adalah Anda tidak perlu khawatir tentang seseorang menambahkanbreak
untuk membuat loop Anda semakin tak terbatas. (kecuali jika Anda sudah berada di dalam lingkaran lainwhile
ataufor
tentu saja ...)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).
sumber
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.Bukan hanya pola yang terkenal, tetapi idiom standar dalam C (dan C ++)
sumber
while (true)
karena alasan yang sama mereka lakukanif (true)
.menghasilkan peringatan dengan Visual Studio (kondisinya konstan). Sebagian besar tempat saya bekerja mengkompilasi build produksi dengan peringatan sebagai kesalahan. Begitu
lebih disukai.
sumber
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:
Jika Anda membangunnya dalam mode Debug ( tanpa optimasi apa pun (/ Od) ) pembongkaran menunjukkan perbedaan yang jelas. Ada instruksi tambahan untuk
true
kondisi di dalamwhile
.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.
Apa pun yang akan Anda gunakan tidak masalah untuk kompiler yang layak dengan optimisasi kecepatan aktif.
sumber
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)
sumber
time head -10 >/dev/null
, ketik setiap 10 kali, dan ukur hasilnya. Saya yakin Anda akan lebih cepatfor(;;)
kecuali Anda menipu. Saya sekitar 14%.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".
sumber
++i
lebihi++
?++i
dani++
berpotensi menjadi signifikan jikai
adalah 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.++i
vsi++
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.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 .; sehinggafor(;;)
cenderung menghasilkan konsistensi yang lebih besar.sumber
while(TRUE)
dievaluasi sebagaiwhile(0)
tidak mungkin mendapat manfaatfor(;;)
.while(true)
harus disukai dalam hal apa pun. Dalam C ++bool
dicadangkan, dan dalam C didefinisikan dalam C stdbool.h (membuatnya kurang aman di C).for(;;)
menghapus semua keraguan.Lebih jelas dari:
Bukan berarti ini berlaku jika Anda tidak menggunakan
Sleep()
.sumber
timerService.scheduleRepeating (50, [] () { /* lots of code */ });
Loop "selamanya" populer di sistem embedded sebagai loop latar belakang. Beberapa orang menerapkannya sebagai:
Dan terkadang itu diimplementasikan sebagai:
Dan implementasi lain adalah:
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.
sumber
Saya berasumsi while (true) lebih mudah dibaca daripada for (;;) - sepertinya programmer melewatkan sesuatu untuk loop :)
sumber
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.
Ketika saya yakin dengan fungsi saya, maka saya mengonversinya menjadi loop tanpa batas:
sumber