Apa istilah untuk loop "while (true)" dengan "break" di dalamnya? [Tutup]

24

Misalkan saya memiliki loop dalam C ++ atau C # yang berjalan seperti ini:

while( true ) {
    doSomething();
    if( condition() ) {
        break;
    }
    doSomethingElse();
}

Ini biasa disebut "infinite loop". Namun itu tidak terbatas secara teknis - itu akan berhenti begitu kontrol mengalir break.

Apa istilah untuk loop seperti itu - yang memiliki pernyataan kontrol loop "loop forever" dan "break" di dalamnya?

sharptooth
sumber
22
Saya rasa tidak ada istilah khusus.
ChrisF
2
Apakah ada jaminan bahwa kontrol akan mengalir melalui terobosan? Dalam contoh itu, bagaimana jika condition()selalu mengembalikan false? Saya akan mengatakan itu adalah loop tak terbatas dengan istirahat bersyarat.
JohnL
1
Bahkan tanpa a break, loop tidak terbatas ( kill, ctrl-alt-del, cabut ...). Jadi mengapa repot dengan detail terminologi?
mouviciel
5
"Apa istilahnya?" - "Ini biasa disebut infinite loop". Itu jawaban Anda di sana. Anda jelas tidak senang dengan istilah itu, tetapi itu tidak menghilangkan fakta bahwa bahasa (alami) bersifat deskriptif. "Istilah untuk X" adalah apa pun yang digunakan orang, bukan apa yang seharusnya mereka gunakan.
MSalters
5
Pertanyaan ini tampaknya di luar topik karena itu adalah pertanyaan "nama benda itu". "Sebutkan hal itu" adalah pertanyaan buruk karena alasan yang sama yang "mengidentifikasi acara TV, film, atau buku yang tidak jelas ini berdasarkan karakter atau ceritanya" adalah pertanyaan buruk: Anda tidak dapat Google, mereka tidak praktis dengan cara apa pun, mereka jangan membantu orang lain, dan membiarkan mereka membuka pintu untuk menanyakan jenis pertanyaan marginal lainnya. Lihat blog.stackoverflow.com/2012/02/lets-play-the-guessing-game
agung

Jawaban:

24

Mempelajari CS, profesor ini mengajarkan kita bahwa ada loop pra-pengecekan ( while(cond) {}), loop pasca-pengecekan ( do {} while(cond);), dan loop tengah-memeriksa . (Saya mungkin telah menerjemahkan ini ke dalam bahasa Inggris dengan buruk, tetapi Anda mendapatkan idenya.)

C dan C ++ tidak memiliki yang terakhir (ISTR Ada yang memilikinya, BICBW), jadi konstruk Anda digunakan untuk itu dalam C dan C ++.

sbi
sumber
1
Ya, Ada memiliki ini:loop ... exit when condition; ... end loop;
Keith Thompson
@Keith: Terima kasih sudah mengkonfirmasi! Sudah hampir 20 tahun sejak saya melakukan beberapa Ada.
sbi
1
Untuk apa nilainya, saya telah menjadi programmer profesional selama lebih dari 20 tahun (dan seorang hobiis lebih lama dari itu), dan saya belum pernah mendengar istilah itu.
offby1
Mengenai terjemahan - saya pikir "dalam" biasanya lebih cocok ketika "pra" dan "posting" digunakan, misalnya "preorder / postorder / traversal tree inorder".
Oak
1
Istilah saya tumbuh dengan adalah "mid-exit loop." Saya telah bekerja dalam beberapa bahasa berbeda dengan dukungan eksplisit untuk loop keluar-tengah.
mjfgates
13

Kursus pertama dalam CS di Stanford ( Metodologi Pemrograman oleh Mehran Sahami ) menyebut ini sebagai satu setengah lingkaran . Dan itu belum tentu praktik pemrograman yang buruk. Pertimbangkan contoh ini untuk mengumpulkan input pengguna (diambil dari The Art and Science of Java oleh Eric Roberts , di mana Roberts juga menyebutnya a-loop-and-a-half ):

prompt user and read in the first value
while (value != sentinel) {
    process the data value
    prompt user and read in a new value
}

Dan kemudian hal yang sama diselesaikan dengan menggunakan ide setengah dan setengah untuk menghindari kode duplikat:

while (true) {
    prompt user and read in a value
    if (value == sentinel) break;
    process the data value
}
ernes7a
sumber
10

Karena tidak memiliki nama resmi, saya akan menyebutnya Broken Loop . Ambiguitas istilah ini dimaksudkan, karena penembusan di tengah-tengah loop agak najis, hampir seperti a goto.

pengguna281377
sumber
Menurut saya, jauh lebih buruk daripada kebohongan. Saya lebih suka melihat kebohongan daripada kondisi yang salah dalam satu lingkaran seperti itu.
Brian Knoblauch
14
@ Brian Apa? Kondisi 'benar' membuatnya jelas dan loop seperti itu sangat umum. Misalnya, jika Anda ingin menambahkan setiap baris file ke daftar, Anda harus mencoba membaca baris (melakukan sesuatu), berhenti jika gagal (jika kondisinya rusak), jika tidak tambahkan ke daftar dan ulangi (lakukan sesuatu lain).
Craig Gidney
7
Tidak ada yang salah dengan istirahat di tengah lingkaran. Jika Anda perlu melakukan beberapa operasi pada setiap awal siklus, Anda harus menduplikasi kode atau memasukkan operasi ini ke dalam kondisi. Salah satu varian jelas memiliki kekurangan. gotojuga memiliki aplikasi yang valid, misalnya emulasi percobaan ... akhirnya diblokir dalam C.
Malcolm
1
Malcolm: Masalah yang mungkin terjadi adalah ketika membaca kode, lebih sulit untuk melihat kapan dan mengapa loop keluar. Masalah tambahan muncul ketika Anda membuat dua atau lebih lingkaran seperti itu, dan ingin keluar dari loop luar berdasarkan kondisi yang ditemukan di loop dalam.
user281377
Katakanlah Anda memiliki lingkaran acara mengendarai sebuah aplikasi Xorg, seperti (dalam pseudo-code :) while(XEventGet(&ev) != NULL){ ... }, Anda secara alami akan ingin memeriksa kunci dalam loop: if(ev.key == XK_q) break;. Melakukan hal berikut while(XEventGet(&ev) != NULL && ev.key != XK_q){ ... }:, jelek dan bisa dibilang lebih sulit dibaca daripada istirahat pertengahan-loop. Plus, bagaimana jika sesuatu harus dilakukan dengan nilai terlebih dahulu sebelum dapat diperiksa? Anda tidak akan dengan serius memasukkan semua itu ke dalam kasing loop, bukan?
Braden Best
8

Tidak ada nama pasti. Loop tak terbatas, saya pikir, adalah istilah yang tepat. Tidak ada loop yang benar-benar tak terbatas, tetapi ini memiliki potensi untuk menjadi tak terbatas secara efektif karena mungkin cabang yang berisi istirahat tidak akan pernah terjadi.

Jika Anda memberi tahu seseorang "buat loop tak terbatas, dan gunakan jeda untuk kondisi X" dan mereka akan tahu apa yang Anda maksud. Jika seseorang meninjau kode Anda dan mengatakan tidak lebih dari "Saya tidak suka loop tak terbatas yang Anda tulis", Anda akan tahu apa yang mereka bicarakan (kecuali Anda memiliki lebih dari satu, tentu saja).

Bryan Oakley
sumber
1
Ini bukan loop tak terbatas; itu memiliki kondisi terminasi yang terdefinisi dengan baik, seperti whileloop normal dan cara Anda melakukan pembatalan itu persis sama (menemukan metrik penurunan monoton adalah awal yang baik).
Donal Fellows
8

Ini loop do-while dengan kondisional di tempat yang salah.

Malfist
sumber
2
Ya, harus ditulis: while (keep_going) {doSomething (); if (kondisi) {keep_going = false; } else {doSomethingElse (); }}
Stephen Gross
10
jadi ... Anda mengatakan bahwa jika Anda mengajar kursus komputer dan ingin menggambarkan ini, Anda akan mengatakan "dan sekarang, kita akan belajar tentang loop * do-while dengan kondisional di tempat yang salah "? Itu terdengar lebih seperti pendapat keagamaan daripada nama.
Bryan Oakley
5
@StephenGross Potongan kode itu adalah saran yang mengerikan. Refactor untuk memasukkan kondisi aktual dalam definisi loop, atau cukup gunakan breakatau continue. Menghindari nilai sentinel dengan cara apa pun, itu hanyalah sepotong negara sewenang-wenang yang harus dilacak secara mental, yang menyamarkan tujuan kode.
Izkata
2
Nilai sentinal adalah goto yang tertunda.
Winston Ewert
2
-1 untuk menjadi weenie keluar tunggal.
Donal Fellows
6

Saya akan memilih "loop tanpa syarat" , mirip dengan "lompatan tanpa syarat". Ini menggambarkan apa yang sedang terjadi (kode loop tanpa syarat), tanpa berbohong (tidak seperti "loop tak terbatas").

tammmer
sumber
1
Tetapi memiliki kondisi pemutusan; bahwa if/ breakdi tengah adalah bagian dari pola.
Donal Fellows
5

Apa istilah untuk loop seperti itu - yang memiliki pernyataan kontrol loop "loop forever" dan "break" di dalamnya?

Ini adalah loop tanpa batas dengan kondisi break.

Saya setuju dengan ammilind dalam hal itu jika Anda ingin memberikannya nama khusus, Anda dapat menyebutnya sebagai Infinite Partial Loop

Ramhound
sumber
1
Sama sekali tidak terbatas; titik di mana kondisi terminasi diperiksa hanya di tempat yang berbeda.
Donal Fellows
5

Pada Kode Rosetta, pola khusus ini digambarkan sebagai loop "N plus satu setengah" . Meskipun ini bukan istilah favorit saya, itu tidak mengerikan dan jelas merupakan pola yang berguna untuk beberapa jenis loop. (Alternatifnya adalah menduplikasi kode sebelum-kondisi-berpotensi rumit dalam program nyata - atau untuk meningkatkan kedalaman bersarang dari kode setelah-kondisi sambil menambahkan variabel kondisi lingkaran; tidak meningkatkan kemampuan pemeliharaan atau pemahaman kode Satu-satunya alasan untuk menolak konstruksi tersebut adalah jika seseorang bersikeras menulis loop menjadi break-gratis.)

Donal Fellows
sumber
4

Tidak ada istilah standar, tapi saya akan mengatakannya sebagai Partial loop .

Loop ini digunakan ketika Anda ingin memecah hanya setelah mengeksekusi beberapa bagian dari loop untuk yang terakhir kalinya (yaitu eksekusi parsial). Ini digunakan ketika Anda tidak menemukan situasi yang cocok di mana Anda mungkin ingin memutus seluruh loop .

Dalam hal ini, Anda ingin memutus loop setelah setidaknya mengeksekusi untuk doSomething()terakhir kalinya.

iammilind
sumber
2

Saya harus setuju dengan sbi di sini - Saya suka istilah loop tengah-memeriksa . Konstruk semacam ini lebih populer ketika Structured Programming mulai bergulir dan banyak bahasa memiliki dukungan sintaksis untuk mereka.

Yang mengatakan, sekarang pengetahuan luas bahwa whileloop biasanya lebih dapat dipertahankan, karena lebih mudah untuk alasan tentang invarian dan mereka sering menangani kasus kosong yang rumit dengan lebih baik.

Dalam kasus khusus Anda, loop Anda hanya setara dengan

for(; doSomething(), !condition(); doSomethingElse()){}

jadi saya hanya akan menggunakan breakversi jika salah satu doSomethingatau doSomethingElsemelibatkan beberapa pernyataan dan saya lebih suka tidak menyimpannya dalam fungsi yang terpisah seperti yang Anda lakukan.

Yang mengatakan, jika loop Anda lebih rumit maka iterasi (mulai, periksa, kenaikan) maka Anda harus mempertimbangkan refactoring itu menjadi sesuatu yang lebih sederhana.

hugomg
sumber
1

Saya kira jika kita akan mencoba membuat istilah untuk ini, mungkin:

Loop yang Dapat Diabaikan

LarsTech
sumber
-1. pertanyaannya bukan tentang membuat nama, ini tentang apakah nama umum sudah ada. Selain itu, semua loop "dapat diloloskan" sehingga ini bukan nama yang efektif.
Bryan Oakley
@BryanOakley Loop tak terbatas, menurut definisi, seharusnya tidak dapat dipecahkan. Mungkin seharusnya tidak ada istilah untuk ini, selain, pemrograman yang buruk.
LarsTech
0

Tidak begitu buruk dalam setiap kasus. Saya menemukan diri saya menulis loop semacam ini dengan jenis API tertentu. Katakan, misalnya, bahwa Anda memiliki objek loop, dan perlu memeriksa beberapa kondisi yang cukup mendalam di dalamnya, seperti:

while (loop
    .getAExecutionModelFactory()
    .getActiveXexecutor()
    .getYCancelModelHandler()
    .getCurrentHandler()
    .isCancelled()) {
        // ... do something with the current Handler ....
        loop = ..... // prepare for next loop
}

Sekarang anggaplah setiap metode getXXX berpotensi mengembalikan nol. Maka masih mungkin untuk menulis ekspresi boolean, meskipun yang cukup rumit dan tidak dapat dibaca. Dan kemudian kita harus melakukan mengulang hampir sama untuk mendapatkan objek handler saat ini. Dalam kasus seperti itu, saya merasa lebih mudah untuk menulis while (true)loop dengan break dan melanjutkan.

Ingo
sumber