Saya sudah pemrograman di Jawa selama beberapa tahun sekarang, tetapi saya baru saja kembali ke sekolah untuk mendapatkan gelar formal. Saya cukup terkejut mengetahui bahwa, pada tugas terakhir saya, saya kehilangan poin karena menggunakan loop seperti di bawah ini.
do{
//get some input.
//if the input meets my conditions, break;
//Otherwise ask again.
} while(true)
Sekarang untuk pengujian saya, saya hanya memindai beberapa input konsol, tetapi saya diberitahu bahwa loop semacam ini tidak dianjurkan karena menggunakan break
mirip dengan goto
, kami hanya tidak melakukannya.
Saya mengerti sepenuhnya perangkap goto
dan sepupu Java-nya break:label
, dan saya memiliki akal sehat untuk tidak menggunakannya. Saya juga menyadari bahwa program yang lebih lengkap akan memberikan cara lain untuk melarikan diri, misalnya untuk mengakhiri saja program tersebut, tetapi itu bukan alasan yang dikutip oleh profesor saya, jadi ...
Ada apa dengan ini do-while(true)
?
sumber
break
mungkin bermakna baik, tetapi sebenarnya disalahpahami. Mungkin Anda bisa mendidik profesor Anda tentang ini;) Dalam pengalaman saya, profesor tidak tahu banyak tentang keahlian pemrograman.do {} while (true)
setarawhile(true) {}
dan yang terakhir sejauh ini merupakan bentuk yang lebih konvensional dan jauh lebih jelas.break
, mereka harus mencoba pemrograman dalam bahasa tanpa itu. Tidak perlu terlalu banyak loop sebelum Anda menginginkannya!Jawaban:
Saya tidak akan mengatakan itu buruk - tetapi sama-sama biasanya saya setidaknya akan mencari alternatif.
Dalam situasi di mana ini adalah hal pertama yang saya tulis, saya hampir selalu setidaknya mencoba untuk mengubahnya menjadi sesuatu yang lebih jelas. Kadang-kadang itu tidak dapat membantu (atau alternatifnya adalah memiliki
bool
variabel yang tidak melakukan apa pun yang berarti kecuali menunjukkan akhir dari loop, kurang jelas dari sebuahbreak
pernyataan) tetapi ada baiknya setidaknya mencoba.Sebagai contoh penggunaan yang lebih jelas
break
daripada bendera, pertimbangkan:Sekarang mari kita paksa untuk menggunakan bendera:
Saya melihat yang terakhir sebagai lebih rumit untuk dibaca: ada
else
blok tambahan ,actOnInput
lebih indentasi, dan jika Anda mencoba mencari tahu apa yang terjadi ketikatestCondition
kembalitrue
, Anda perlu melihat dengan hati-hati melalui sisa blok untuk memeriksa bahwa ada bukan sesuatu setelah ituelse
blok yang akan terjadi apakahrunning
telah ditetapkan kefalse
atau tidak.The
break
pernyataan berkomunikasi maksud lebih jelas, dan memungkinkan sisa blok melanjutkan apa yang perlu dilakukan tanpa khawatir tentang kondisi sebelumnya.Perhatikan bahwa argumen ini persis sama dengan argumen yang dimiliki orang tentang beberapa pernyataan pengembalian dalam suatu metode. Sebagai contoh, jika saya dapat menentukan hasil metode dalam beberapa baris pertama (misalnya karena beberapa input adalah nol, atau kosong, atau nol) saya merasa lebih jelas untuk mengembalikan jawaban itu secara langsung daripada memiliki variabel untuk menyimpan hasilnya , lalu seluruh blok kode lain, dan akhirnya sebuah
return
pernyataan.sumber
while (true)
AFAIK tidak ada, sungguh. Guru hanya alergi
goto
, karena mereka mendengar di suatu tempat itu sangat buruk. Kalau tidak, Anda hanya akan menulis:Yang merupakan hal yang hampir sama.
Mungkin ini lebih bersih (karena semua info perulangan terdapat di bagian atas blok):
sumber
Douglas Crockford memiliki komentar tentang bagaimana ia berharap JavaScript mengandung
loop
struktur:Dan saya tidak berpikir Java akan lebih buruk karena memiliki
loop
struktur juga.Tidak ada yang salah dengan
while(true)
loop, tapi ada adalah kecenderungan bagi guru untuk mencegah mereka. Dari perspektif pengajaran, sangat mudah untuk membuat siswa membuat loop tanpa akhir dan tidak mengerti mengapa loop tidak pernah lolos.Tetapi apa yang jarang mereka sebutkan adalah bahwa semua mekanisme perulangan dapat direplikasi dengan
while(true)
loop.sama dengan
dan
sama dengan:
dan
sama dengan:
Selama Anda dapat mengatur loop Anda dengan cara yang bekerja membangun yang Anda pilih untuk digunakan tidak penting. Jika kebetulan pas dalam satu
for
lingkaran, gunakan satufor
lingkaran.Satu bagian terakhir: jaga agar loop Anda tetap sederhana. Jika ada banyak fungsi yang perlu terjadi pada setiap iterasi, letakkan di fungsi. Anda selalu dapat mengoptimalkannya setelah berhasil.
sumber
for
loop ketikacontinue
pernyataan dilibatkan, tetapi itu bukan ekstensi utama.for (;;) {
lagi? (Diucapkan "selamanya"). Ini dulunya sangat populer.Kembali pada tahun 1967, Edgar Dijkstra menulis sebuah artikel di majalah perdagangan tentang mengapa goto harus dihilangkan dari bahasa tingkat tinggi untuk meningkatkan kualitas kode. Paradigma pemrograman keseluruhan yang disebut "pemrograman terstruktur" keluar dari ini, meskipun tentu tidak semua orang setuju bahwa goto secara otomatis berarti kode yang buruk.
Inti dari pemrograman terstruktur pada dasarnya adalah bahwa struktur kode harus menentukan alirannya daripada memiliki gotos atau istirahat atau terus menentukan aliran, sedapat mungkin. Demikian pula, memiliki beberapa titik masuk dan keluar ke loop atau fungsi juga tidak disarankan dalam paradigma itu.
Jelas ini bukan satu-satunya paradigma pemrograman, tetapi seringkali dapat dengan mudah diterapkan pada paradigma lain seperti pemrograman berorientasi objek (ala Java).
Guru-guru Anda mungkin telah diajar, dan sedang berusaha mengajar kelas Anda bahwa kami sebaiknya menghindari "kode spageti" dengan memastikan kode kami terstruktur, dan mengikuti aturan tersirat pemrograman terstruktur.
Sementara tidak ada yang secara inheren "salah" dengan implementasi yang menggunakan break, beberapa menganggapnya lebih mudah untuk membaca kode di mana kondisi untuk loop secara eksplisit ditentukan dalam kondisi while (), dan menghilangkan beberapa kemungkinan menjadi terlalu rumit. Pasti ada jebakan untuk menggunakan kondisi sementara (benar) yang tampaknya sering muncul dalam kode oleh programmer pemula, seperti risiko tidak sengaja membuat loop tak terbatas, atau membuat kode yang sulit dibaca atau membingungkan.
Ironisnya, penanganan pengecualian adalah area di mana penyimpangan dari pemrograman terstruktur pasti akan muncul dan diharapkan saat Anda masuk lebih jauh ke pemrograman di Jawa.
Mungkin juga instruktur Anda mungkin mengharapkan Anda untuk mendemonstrasikan kemampuan Anda untuk menggunakan struktur lingkaran atau sintaksis tertentu yang diajarkan dalam bab atau pelajaran teks Anda, dan sementara kode yang Anda tulis setara secara fungsional, Anda mungkin tidak menunjukkan keterampilan khusus yang seharusnya Anda pelajari dalam pelajaran itu.
sumber
Konvensi Java ususal untuk input bacaan adalah:
Dan konvensi C ++ biasa untuk membaca input adalah:
Dan di C, itu
atau jika Anda yakin tahu berapa lama baris teks terpanjang dalam file Anda, Anda bisa melakukannya
Jika Anda menguji untuk melihat apakah pengguna Anda memasukkan
quit
perintah, mudah untuk memperpanjang salah satu dari 3 struktur loop ini. Saya akan melakukannya di Jawa untuk Anda:Jadi, walaupun pasti ada kasus-kasus di mana
break
ataugoto
dibenarkan, jika semua yang Anda lakukan adalah membaca dari file atau konsol baris demi baris, maka Anda seharusnya tidak perluwhile (true)
loop untuk mencapainya - bahasa pemrograman Anda telah menyediakan Anda dengan idiom yang sesuai untuk menggunakan perintah input sebagai kondisi loop.sumber
while (true)
loop alih-alih salah satu dari loop input konvensional ini, Anda mungkin lupa memeriksa akhir file.while
kondisional. Pada kondisi Java terakhir sudah cukup lumayan, dan jika Anda harus melakukan manipulasi yang luas untuk memutuskan apakah akan melanjutkan atau tidak, mungkin akan cukup lama. Anda bisa membaginya menjadi fungsi terpisah, dan itu mungkin yang terbaik. Tetapi jika Anda menginginkannya dalam satu fungsi, dan ada pekerjaan yang tidak perlu dilakukan sebelum memutuskan apakah akan melanjutkan,while(true)
mungkin yang terbaik.gets()
bukan konvensi umum. Sangat kondusif untuk buffer overflows.fgets(buffer, BUFFER_SIZE, file)
jauh lebih seperti praktik standar.fgets
.Ini bukan hal yang mengerikan, tetapi Anda harus mempertimbangkan pengembang lain saat melakukan pengkodean. Bahkan di sekolah.
Rekan pengembang Anda harus dapat melihat klausa keluar untuk loop Anda, pada deklarasi loop. Kamu tidak melakukan itu. Anda menyembunyikan klausa keluar di tengah-tengah loop, membuat lebih banyak pekerjaan untuk orang lain yang datang dan mencoba memahami kode Anda. Ini adalah alasan yang sama sehingga hal-hal seperti "istirahat" dihindari.
Yang sedang berkata, Anda masih akan melihat hal-hal seperti ini dalam BANYAK kode di dunia nyata.
sumber
while (true)
cukup jelas bahwa akan adabreak
ataureturn
di dalamnya, atau itu akan berjalan selamanya. Menjadi jujur itu penting, tetapiwhile(true)
tidak terlalu buruk dengan sendirinya. Variabel yang memiliki invarian kompleks melintasi iterasi loop akan menjadi contoh dari sesuatu yang menyebabkan lebih banyak kecemasan.Ini pistol Anda, peluru dan kaki Anda ...
Itu buruk karena Anda meminta masalah. Bukan Anda atau poster lain di halaman ini yang memiliki contoh loop pendek / sederhana.
Masalahnya akan mulai pada waktu yang sangat acak di masa depan. Mungkin disebabkan oleh programmer lain. Mungkin orang yang menginstal perangkat lunak. Mungkin pengguna akhir.
Mengapa? Saya harus mencari tahu mengapa aplikasi 700K LOC secara bertahap akan mulai membakar 100% dari waktu CPU sampai setiap CPU jenuh. Itu adalah loop while (true) yang menakjubkan. Itu besar dan menjijikkan, tetapi akhirnya menjadi:
Tidak ada cabang final lain. Jika nilai tidak cocok dengan kondisi if, loop terus berjalan hingga akhir waktu.
Tentu saja, programmer menyalahkan pengguna akhir karena tidak memilih nilai yang diharapkan oleh programmer. (Saya kemudian menghapus semua instance while (true) dalam kode.)
IMHO itu bukan pemrograman defensif yang baik untuk menggunakan konstruksi seperti while (true). Itu akan kembali menghantui Anda.
(Tapi saya ingat profesor menilai jika kita tidak berkomentar setiap baris, bahkan untuk i ++;)
sumber
Ini buruk dalam arti bahwa konstruksi pemrograman terstruktur lebih disukai daripada (yang agak tidak terstruktur) istirahat dan melanjutkan pernyataan. Sebagai perbandingan, mereka lebih disukai daripada "kebagian" menurut prinsip ini.
Saya selalu merekomendasikan untuk membuat kode Anda terstruktur mungkin ... meskipun, seperti yang ditunjukkan Jon Skeet, jangan membuatnya lebih terstruktur daripada itu!
sumber
Menurut pengalaman saya dalam banyak kasus, loop memiliki kondisi "utama" untuk melanjutkan. Ini adalah kondisi yang harus ditulis ke dalam () operator itu sendiri. Semua kondisi lain yang dapat memutus loop adalah sekunder, tidak begitu penting dll. Mereka dapat ditulis sebagai
if() {break}
pernyataan tambahan .while(true)
sering membingungkan dan kurang bisa dibaca.Saya pikir aturan-aturan ini tidak mencakup 100% kasus tetapi mungkin hanya 98%.
sumber
Meskipun tidak selalu merupakan jawaban mengapa tidak menggunakan
while (true)
, saya selalu menemukan komik ini dan menyertai pernyataan penulis penjelasan singkat tentang mengapa melakukan sementara bukan melakukan-saat.Sehubungan dengan pertanyaan Anda: Tidak ada masalah yang melekat dengannya
... jika Anda tahu apa yang Anda lakukan dan memastikan bahwa
exit_time
pada titik tertentu akan dievaluasitrue
.Guru mencegah Anda menggunakan
while(true)
karena sampai dan kecuali Anda pada titik yang Anda tahu persis apa yang Anda lakukan, itu adalah cara mudah untuk membuat kesalahan kritis.sumber
exit_time = false; while(!exit_time) { execute_stuff(); }
dando { execute_stuff(); } while(! exit_time );
keduanya lebih jelas daripada memilikiif( condition ) { break; }
di akhir loop dengan awhile(true)
. Istirahat adalah hubung singkat untuk loop - baik-baik saja bila digunakan sebagai hubung singkat di tengah-tengah loop, tetapi Anda hanya harus mengevaluasi suatu kondisi dalam pernyataan sementara vs memiliki istirahat di akhir loop.Anda mungkin hanya menggunakan bendera Boolean untuk menunjukkan kapan harus mengakhiri loop while.
Break
dango to
alasan mengapa perangkat lunak sulit dipertahankan - krisis perangkat lunak (tm) - dan harus dihindari, dan bisa juga mudah.Ini pertanyaan apakah Anda pragmatis atau tidak. Coders pragmatis mungkin hanya menggunakan break dalam situasi sederhana itu.
Tapi itu baik untuk mendapatkan kebiasaan untuk tidak menggunakannya, jika tidak, Anda dapat menggunakannya dari kebiasaan dalam situasi yang tidak cocok, seperti dalam loop bersarang rumit di mana keterbacaan dan pemeliharaan kode Anda menjadi lebih sulit dengan menggunakan
break
.sumber
if (running)
dalam loop, indentasi semua sisa kode ketika semua yang saya inginkan adalah untuk keluar loop pasti kurang jelas bagi saya daripada pernyataan break sederhana yang menyatakan persis apa yang saya inginkan lakukan. Anda tampaknya mempertimbangkan menggunakan istirahat sebagai kebiasaan buruk secara aksiomatis - saya tidak menganggapnya sebagai kebiasaan buruk .Mungkin saya kurang beruntung. Atau mungkin saya hanya kurang pengalaman. Tetapi setiap kali saya ingat berurusan dengan
while(true)
memilikibreak
di dalam, adalah mungkin untuk meningkatkan kode menerapkan Metode Ekstrak ke -blok sementara , yang membuatwhile(true)
tetapi (secara kebetulan?) Mengubah semuabreak
s menjadireturn
s.Dalam pengalaman saya
while(true)
tanpa istirahat (yaitu dengan pengembalian atau lemparan) cukup nyaman dan mudah dimengerti.sumber
Saya pikir ya itu sangat buruk ... atau setidaknya, bagi banyak pengembang. Ini adalah gejala dari pengembang yang tidak memikirkan kondisi loop mereka. Akibatnya ada kesalahan rawan.
sumber
Tidak ada masalah besar
while(true)
denganbreak
pernyataan, namun beberapa orang mungkin berpikir itu sedikit menurunkan keterbacaan kode. Cobalah untuk memberikan variabel nama yang bermakna, mengevaluasi ekspresi di tempat yang tepat.Sebagai contoh Anda, tampaknya lebih jelas untuk melakukan sesuatu seperti:
Ini terutama benar jika loop do while menjadi panjang - Anda tahu persis di mana centang untuk melihat apakah ada iterasi tambahan yang terjadi. Semua variabel / fungsi memiliki nama yang sesuai di tingkat abstraksi. The
while(true)
pernyataan tidak adalah memberitahu Anda pengolahan yang tidak di tempat yang Anda pikir.Mungkin Anda ingin output yang berbeda pada kali kedua melalui loop. Sesuatu seperti
sepertinya lebih mudah dibaca oleh saya
Sekali lagi, dengan contoh sepele keduanya cukup mudah dibaca; tetapi jika loop menjadi sangat besar atau sangat bersarang (yang berarti Anda mungkin seharusnya sudah refactored), gaya pertama mungkin sedikit lebih jelas.
sumber
Saya menggunakan sesuatu yang serupa, tetapi dengan logika yang berlawanan, dalam banyak fungsi saya.
sumber
Ini lebih merupakan hal estetika, lebih mudah untuk membaca kode di mana Anda secara eksplisit tahu mengapa loop akan berhenti tepat di deklarasi loop.
sumber
Saya akan mengatakan bahwa secara umum alasan itu tidak dianggap ide yang baik adalah bahwa Anda tidak menggunakan konstruk untuk potensi penuh itu. Juga, saya cenderung berpikir bahwa banyak instruktur pemrograman tidak suka ketika siswa mereka datang dengan "bagasi". Maksud saya, saya pikir mereka suka menjadi pengaruh utama pada gaya pemrograman siswa mereka. Jadi mungkin itu hanya kesal dari instruktur.
sumber
Bagi saya, masalahnya adalah keterbacaan.
Pernyataan sementara dengan kondisi sebenarnya tidak memberi tahu Anda tentang loop. Itu membuat pekerjaan memahaminya jauh lebih sulit.
Apa yang akan lebih mudah dipahami dari kedua cuplikan ini?
sumber
Saya kira menggunakan istirahat untuk guru Anda seperti mematahkan sebatang pohon untuk mendapatkan buah, menggunakan beberapa trik lain (membungkuk cabang) sehingga Anda mendapatkan buah dan cabang masih hidup. :)
sumber
1) Tidak ada yang salah dengan a
do -while(true)
2) Guru Anda salah.
NSFS !!:
3) Kebanyakan guru adalah guru dan bukan programmer.
sumber
Mungkin buruk jika loop Anda berjalan di utas latar belakang, jadi ketika Anda menutup aplikasi Anda dengan mengakhiri utas UI, potongan kode itu akan terus dijalankan. Seperti yang sudah dikatakan orang lain, Anda harus selalu menggunakan semacam cek untuk memberikan cara pembatalan.
sumber