Saya memiliki guru ini, dia cukup pintar (kadang-kadang, haha) katanya programmer yang baik mencoba menggunakan while
loop, bukan for
loop. alasan yang dia berikan untuk ini adalah karena while
loop dapat dibuktikan, seperti pada, seseorang dapat sepenuhnya menjelaskan apa yang terjadi dalam satu while
loop sedangkan Anda tidak dapat melakukan itu untuk satu for
loop. dia juga mengatakan sesuatu tentang programmer NASA hanya menggunakan while
loop dan tidak diizinkan melakukan for
loop karena ini.
Saya mengalami kesulitan memahami hal ini, karena kedua loop dapat menjelaskan bagaimana mereka bekerja secara detail, bukan? untuk keduanya Anda akan selalu tahu apa yang akan terjadi?
Dapatkah seseorang menjelaskan kepada saya mengapa while
loop dapat dibuktikan (Dan karena itu, mungkin lebih baik daripada for
loop, dalam beberapa kasus setidaknya).
Meskipun ini masih tidak mengatakan apa-apa tentang perbedaan antara while dan for loop.
for
daripadawhile
sekadar tidak masuk akal. Mungkin ada satu, tapi ini bukan.for (init; test; step) { body }
memiliki desugaring sepele untukwhile
:{init; while (test) { step; body }}
.Jawaban:
Singkatnya : Apa yang mungkin dimaksudkan oleh guru Anda adalah bahwa semantik
while
hampir sama di sebagian besar bahasa, sedangkan semantikfor
mungkin berubah banyak (lihat diskusi di bawah). Oleh karena itu, bukti independen bahasa abstrak lebih dapat diandalkan dengan awhile
, tetapi orang harus berhati-hati bahwa bukti denganfor
loop mungkin tidak cocok dengan semantikfor
loop dalam banyak bahasa.Pertanyaan Anda tidak cukup tepat (meskipun itu mungkin bukan salah Anda).
Intinya adalah bahwa, afaik, tidak ada standar, standar yang didukung ISO, atau definisi
for
danwhile
loop referensi yang diterima secara resmi . Definisi ini tergantung pada bahasa pemrograman.Karenanya Anda tidak dapat membuat pernyataan umum apa pun tentang kesetaraannya sebelum Anda menentukan dengan tepat apa yang dapat dilakukan masing-masing. Saya mengemukakan hal itu dengan lebih tepat, karena itu adalah salah satu argumen utama yang digunakan dalam jawaban lain (dan diskusi akan bermanfaat dalam apa yang berikut).
Pada intertranslatability
for
danwhile
loopRingkasan : itu tergantung pada bahasa pemrograman, tetapi selalu mungkin selama Anda dapat memiliki satu loop tak terbatas dan cara untuk keluar darinya.
Tetapi Anda dapat membuat pernyataan seperti itu untuk bahasa pemrograman tertentu, dan jawabannya akan tergantung pada fitur untuk bahasa tersebut.
Itu juga berarti bahwa tidak ada bukti umum, tetapi hanya satu untuk setiap bahasa pemrograman.
Satu hal yang secara umum benar adalah bahwa
while
loop umumnya dapat menirufor
loop, karena loop sementara dapat melakukan pengujian kondisi keluar dari loop, melakukan inisialisasi variabel kontrol dengan tugas sebelum memasukkan loop, dan melakukan penambahan pada akhir loop body, sehinggamenjadi
Ini kurang lebih berfungsi untuk sebagian besar bahasa, tetapi tidak sejelas kelihatannya, dan mungkin ada banyak "detail" yang perlu dikhawatirkan.
Misalnya, dalam banyak bahasa,
for
loop mengevaluasinya 3 argumen (nilai awal, kenaikan, dan nilai akhir) sebagai argumen yang ketat , dievaluasi satu kali sebelum memasukkan loop, sementara yang lain akan menggunakan argumen thunk untuk dievaluasi kembali pada setiap belokan, atau mungkin sebagai argumen malas untuk dievaluasi hanya ketika pertama kali dibutuhkan.Poin lain mungkin bahwa variabel kenaikan mungkin lokal ke
for
loop, atau harus variabel lokal dari fungsi tempat loop muncul.Bergantung pada masalah-masalah seperti itu, terjemahan a
for
ke awhile
dapat sangat bervariasi, meskipun biasanya mungkin untuk mencapainya.Hal yang sama berlaku untuk yang sebaliknya, menerjemahkan a
while
ke dalam satufor
lingkaran.Masalah pertama adalah bahwa
while
loop akan selalu mengevaluasi kembali kondisi keluar di setiap belokan. Tetapi beberapafor
loop tidak menyediakan kondisi yang dievaluasi ulang pada setiap belokan, selain perbandingan variabel kontrol dengan beberapa nilai tetap yang dihitung pada entri loop. Maka terjemahan tidak mungkin kecuali ada cara lain untuk melompat keluar dari loop pada beberapa kondisi yang sewenang-wenang.Itu dapat dicapai dengan berbagai perangkat, biasanya dimulai dengan pernyataan kondisional menguji kondisi, diikuti dengan lompatan yang diimplementasikan, sebagaimana tersedia, dengan pernyataan keluar loop, pernyataan kembali (setelah merangkum loop dalam suatu fungsi), pernyataan goto atau peningkatan pengecualian.
Dengan kata lain, sekali lagi sangat tergantung pada bahasa, dan mungkin pada fitur bahasa yang halus.
Ini mengatakan, seperti dijawab oleh @milleniumbug , intertranslation mudah dalam bahasa C, karena
for
lopp pada dasarnya adalah sebuahwhile
loop ditambah beberapa tambahan untuk variabel kontrol yang ditambahkan.Tetapi ini tidak selalu berlaku untuk bahasa lain, dan kemungkinan besar tidak dengan cara yang sama.
Ini dikatakan, bahasa pemrograman biasanya memiliki kekuatan Turing dengan hanya satu dari loop ini, karena semua yang Anda butuhkan untuk itu adalah satu loop tak terbatas. Jadi, selama Anda memiliki beberapa cara pengulangan untuk selamanya, dan mungkin memutuskan untuk berhenti, Anda cukup yakin Anda dapat meniru konstruksi lain ... tetapi tidak harus dengan mudah.
Mengenai bukti
Ringkasan : Tidak ada alasan bagi saya untuk menyatakan bahwa bukti harus secara signifikan lebih sulit dengan satu atau yang lain (kecuali beberapa fitur aneh dari bahasa).
Mungkin ada kesalahpahaman, atau guru Anda memikirkan sesuatu yang lain.
Semantik formal dapat didefinisikan untuk berbagai jenis loop yang didefinisikan dalam bahasa pemrograman, dan kemudian digunakan untuk membuktikan properti.
Mungkin, sekali lagi tergantung pada bahasa, bahwa melakukan bukti formal mengenai program mungkin lebih kompleks dalam beberapa kasus. Tetapi itu tergantung pada bahasanya.
Saya tidak bisa membayangkan alasan mengapa bukti harus jauh lebih sulit dengan satu konstruksi lebih dari yang lain. The
for
Loop mungkin lebih kompleks karena dapat menawarkan, seperti di C, semua yang dilakukan denganwhile
ditambah hal-hal lain. Tetapi jika Anda melakukannya denganwhile
, Anda harus menambahkan ekstra dalam beberapa bentuk lain.Saya bisa menggunakan argumen umum formal tentang intertranslatabilitas, selama ada kemungkinan untuk satu loop tak terbatas. Namun saya akan menahan diri untuk tidak melakukan itu, karena konstruksi yang terlibat bukanlah sesuatu yang ingin Anda tangani dalam sebuah bukti, dan itu jelas merupakan pernyataan yang tidak adil, setidaknya dalam praktik.
Namun, setelah diskusi di atas, kita telah melihat bahwa kesulitan untuk transtranslabilitas berasal dari variabilitas besar
for
loop dari bahasa ke bahasa. Maka kesimpulan berikut yang mungkin merupakan jawaban yang tepat:Satu kemungkinan untuk memahami pernyataan guru Anda adalah bahwa semantik
while
loop hampir sama di semua bahasa pemrograman, sedangkan sintaks dan semantikfor
loop dapat bervariasi secara signifikan dari bahasa ke bahasa. Oleh karena itu, dimungkinkan untuk membuat bukti "abstrak" umum denganwhile
loop yang memiliki semantik independen bahasa sampai tingkat yang baik, sementara ini tidak mungkin untukfor
loop yang memiliki sintaks dan semantik berubah terlalu banyak dari bahasa ke bahasa. Tetapi ini tidak berlaku dalam bahasa tertentu, ketika semantik keduanya didefinisikan secara tepat.Saran terbaik saya adalah Anda harus bertanya kepada guru Anda apa yang ia maksudkan dengan tepat, dan apakah ia dapat memberi Anda contoh. Misphrasing atau kesalahpahaman adalah peristiwa umum.
sumber
Dalam bahasa C Anda dapat menulis ulang setiap
for
loop ke loop yang setarawhile
dan sebaliknya.while -> for
transformasi:Menulis kembali
untuk
for -> while
transformasi:Ini sedikit lebih rumit, terutama jika Anda memiliki
continue
pernyataan di loop Anda.Menulis kembali:
untuk:
tetapi ganti setiap
continue;
pernyataan dengangoto next_label;
pernyataan. Jikacondition
ini adalah instruksi nol, gantikan dengantrue
.Seperti yang Anda lihat, dalam bahasa C tidak ada yang lebih "dapat dibuktikan" (apa pun artinya) daripada yang lain, karena bahkan jika salah satu loop itu, Anda bisa menulis ulang dalam hal loop lain.
Sekarang, ada bahasa lain di mana
while <-> for
kesetaraan ini tidak ada. Misalnya, dalam Pascal, Anda dapat mengasumsikan lebih banyak tentangfor
loop. Ini berarti bahwa Anda tidak dapat mengekspresikan setiap konsep saat menulis satufor
lingkaran, tetapi Anda dapat membuktikan lebih banyak tentang aliran kode:Di sini,
n
disimpan di awal loop, jadi perubahan untukn
tidak membuat pengaruh pada jumlah iterasi, dan Anda tidak dapat memodifikasii
dalam tubuh loop. Ini berarti Anda dapat dengan mudah membuktikan bahwa loop ini pada akhirnya akan berakhir (sepertin
yang terbatas, dan Anda tidak dapat memodifikasii
).sumber
goto
. Jika seseorang menambahkan flag, semua loop lain dapat ditiru menggunakan satu "while (1) ..." di sekitar fungsi yang berjalan hingga "kembali"; jika seseorang menambahkan "goto", semua loop lain dapat ditiru menggunakan itu.Dalam logika Floyd-Hoare , sistem formal paling umum untuk alasan tentang kebenaran program komputer, ada aturan sementara .
Dalam kata-kata, jika Anda memiliki klausa penjaga (ekspresi dalam tanda kurung dalam
while()
), fungsi varian (ekspresi dengan nilai diskrit yang dapat ditunjukkan berkurang secara monoton setiap kali loop berjalan, dan selalu menjadi positif), dan loop invarian (pernyataan logika yang selalu benar sebelum dan sesudah setiap kali loop berjalan), Anda dapat membuktikan bahwa loop sementara akan selesai (karena fungsi varian tidak dapat terus menurun) dan bahwa akhirnya klausa penjaga akan salah dan loop invarian menjadi benar.Logika Floyd-Hoare tidak memiliki aturan untuk
for
loop atau apa pun yang membangun bahasa sebenarnya mungkin.Namun, seperti yang dijelaskan oleh jawaban lain, untuk loop selalu dapat ditulis dalam bentuk while loop. Itu berarti bahwa mereka dapat beralasan tentang, hanya butuh sedikit lebih banyak pekerjaan.
Jika guru Anda memiliki kursus di universitas di mana ia harus memberikan bukti kebenaran programnya, ia mungkin menulis program hanya menggunakan loop. Saya tahu saya melakukannya. Dan begitu Anda terbiasa berpikir dalam hal fungsi penjaga dan varian dan invarian loop, mereka tampak sangat alami. Terlalu sering menggunakan loop adalah kebiasaan yang Anda lihat dengan lulusan CS, saya harus belajar untuk berhenti melakukan itu di bulan-bulan pertama saya sebagai pengembang profesional.
Di suatu tempat di ujung jalur, guru Anda salah mengartikan semua ini sebagai "programmer yang baik gunakan saat loop", sedangkan apa yang sebenarnya terjadi lebih seperti "beberapa lulusan CS mengubah kebiasaan pembuktian kebenaran mereka menjadi kebiasaan pemrograman praktis".
sumber
for
loop, yang tidak memiliki definisi tetap dan lebih kompleks, tanpa secara formal diperlukan.Sebenarnya, dalam beberapa hal, kebalikannya adalah benar.
Bahasa dengan hanya
for
-lingkaran bukan Turing-lengkap, ia hanya dapat menghitung fungsi primitif-rekursif, tidak semua fungsi yang dapat dihitung-Turing. Karena semua perhitungan dalam bahasa denganfor
-lalu selalu berakhir, Masalah Henti dan semua Masalah Decidability lainnya berdasarkan itu, tidak muncul, jadi mungkin untuk secara mekanis memutuskan lebih banyak sifat statis dari program daripada dalam bahasa denganwhile
-lompat.OTOH, bahasa dengan hanya bilangan asli, satu variabel, dan
while
-lingkaran adalah Turing-lengkap, sehingga tidak mungkin untuk memutuskan bahkan properti paling sederhana: akankah program ini mengembalikan hasil?sumber
for
bahasa -hanya dapat menghasilkanwhile
perilaku -setara oleh decrementing variabel loop (dengan asumsi bahasa memungkinkan) selama iterasi yang tidak seharusnya mengakibatkan penghentian a. (Misalnya,for n in 1 to 2 { if condition then n := n-1 }
)Saya ingin mengatakan bahwa dalam kenyataan, tidak ada perbedaan. Pertanyaan Anda tidak relevan. Mungkin guru Anda mungkin bermaksud menggunakan while ketika tidak. iterasi tidak diketahui sebelumnya. Dalam banyak kasus kita perlu menggunakan loop sementara untuk mengekstrak digit dari no. saat pengguna memasukkan no. yang bisa berapa pun panjangnya. Secara teknis, kesamaan antara for & while loop adalah bahwa keduanya adalah entry-controlled loop di mana (test-expression / kondisi) dievaluasi sebelum masuk ke dalam loop body. Ini adalah perbedaan antara loop sementara & do-while.
sumber
Kemungkinan berasal dari pemrograman C awal di mana, dengan norma saat ini, loop secara luas disalahgunakan dan disalahgunakan, terutama kondisi yang sedang dimodifikasi. Ketika pemrogram mulai memahami efek gaya pemrograman tertentu, penyalahgunaan dan penyalahgunaan persyaratan loop tidak disukai, dan pernyataan itu, sementara (bisa dibilang) sekali valid, tidak lagi memiliki kebenaran.
Pernyataan itu sama sekali tidak benar jika Anda hanya melihat definisi bahasa dan sintaksis dan mengabaikan bagaimana itu digunakan.
Namun, pernyataan itu sendiri menawarkan pelajaran berharga bagi siapa pun yang ingin memahaminya, sejarahnya, dan mengapa itu tidak lagi dianggap benar. - Apa ungkapan tentang belajar, kesalahan dan ulangi mereka .....
sumber
Gurumu benar!
Alasannya berikut ini valid C
Anda tidak dapat menjamin variabel kondisi belum dirusak!
sumber
while
loop lebih baik di sini?while
loop Anda benar-benar dapat menjamin bahwa variabel kondisi belum dirusak? Bahkan, mengutak-atik variabel kondisi adalah satu-satunya cara untuk keluar dariwhile
loop! Saya biasanya menahan diri dari downvoting hal, tetapi untuk jawaban ini, saya akan membuat pengecualian.