Saya mengonversi algoritma C ++ ke C #. Saya menemukan ini untuk loop:
for (u = b.size(), v = b.back(); u--; v = p[v])
b[u] = v;
Ini tidak memberikan kesalahan dalam C ++, tetapi tidak di C # (tidak dapat mengkonversi int ke bool). Saya benar-benar tidak tahu ini untuk loop, di mana kondisinya?
Bisakah seseorang tolong jelaskan?
PS. Hanya untuk memeriksa, untuk mengadaptasi VECTOR ke LIST, apakah b.back () sesuai dengan b [b.Count-1]?
u--
. Semi-titik dua digunakan untuk membatasi berbagai bagianfor
pernyataan.; u-- != 0;
b
,u
,v
, dll Satu-satunya alasan mereka diberi nama dengan cara ini adalah karena seseorang ingin terlihat pintar dengan membuat kode mereka terbaca.do
artinya di C ++" - akan mendapatkan ribuan klik dari pemula yang mencari tutorial.Jawaban:
Kondisi
for
loop berada di tengah - di antara dua titik koma;
.Dalam C ++ tidak masalah untuk menempatkan hampir semua ekspresi sebagai suatu kondisi: apa pun yang dievaluasi menjadi nol berarti
false
; berarti bukan noltrue
.Dalam kasus Anda, syaratnya adalah
u--
: ketika Anda mengonversi ke C #, cukup tambahkan!= 0
:sumber
u = b.size() - 1
gantinya.Banyak jawaban yang akurat, tapi saya pikir ada baiknya menuliskan loop sementara yang setara.
Setara dengan:
Anda dapat mempertimbangkan refactoring ke format while () saat Anda menerjemahkan ke C #. Menurut saya itu lebih jelas, lebih sedikit jebakan untuk programmer baru, dan sama-sama efisien.
Seperti orang lain telah menunjukkan - tetapi untuk membuat jawaban saya lengkap - untuk membuatnya bekerja di C # Anda akan perlu untuk perubahan
while(u--)
kewhile(u-- != 0)
.... atau
while(u-- >0)
kalau-kalau Anda mulai negatif. (Oke,b.size()
tidak akan pernah menjadi negatif - tetapi pertimbangkan kasus umum di mana mungkin sesuatu yang lain diinisialisasi).Atau, untuk membuatnya lebih jelas:
Lebih baik jelas daripada singkat.
sumber
while (u-- >0)
formulir. Jika spasi menjadi kacau, Anda mungkin berakhir dengan loop "turun ke nol":,while (u --> 0)
yang cenderung membingungkan semua orang pada pandangan pertama. ( Saya tidak yakin apakah itu valid C #, tetapi dalam C, dan saya pikir mungkin juga dalam C ++? )for
bukannyawhile
justru bahwa Anda meletakkan inisialisasi dan kenaikan / penurunan dalam satu pernyataan, dan itu tidak selalu membuat kode lebih sulit untuk dipahami. Kalau tidak, kita tidak boleh menggunakanfor
sama sekali.--
token diikuti oleh>
token. Dua operator terpisah. Lingkaran "turun ke nol" hanyalah kombinasi langsung dari pengurangan setelah dan lebih besar dari. Kelebihan operator C ++ tidak membuat operator baru, melainkan hanya menggunakan yang sudah ada.Syaratnya
u--;
, karena berada di posisi kedua untuk instruksi.Jika nilai
u--;
berbeda dari 0, itu akan ditafsirkan sebagaitrue
(yaitu, secara implisit dicor ke nilai booleantrue
). Jika, sebagai gantinya, nilainya 0, itu akan dilemparkan kefalse
.Ini kode yang sangat buruk .
Pembaruan: Saya membahas penulisan loop "untuk" di posting blog ini . Rekomendasinya dapat diringkas dalam paragraf berikut:
Contoh ini jelas melanggar rekomendasi ini.
sumber
Ini akan menjadi bentuk C # dari loop Anda.
Cukup ganti yang setara dengan ukuran () dan kembali ().
Apa yang dilakukannya adalah membalik daftar dan menyimpannya dalam sebuah array. Tetapi dalam C # kita langsung memiliki fungsi yang ditentukan sistem untuk ini. Jadi Anda tidak perlu menulis loop ini juga.
sumber
v = b.back();
mengeluarkan intializer bukankah Anda mengubah cara kerjanya, karenav = p[v]
ditimpa olehv = b.back();
dieksekusi sekali sebelum iterasi dimulai danv = p[v]
dieksekusi pada awal setiap iterasi. Dalam versi C #v = p[v]
masih dieksekusi pada awal setiap iterasi tetapiv = b.back();
dieksekusi tepat setelah itu, mengubah nilaiv
untuk instruksi berikutnyab[u] = v;
. (mungkin pertanyaannya diedit setelah Anda membacanya)v = b.back()
. Anda memilikinya mengeksekusi di setiap loop iterasi bukan hanya yang pertama - kita tidak tahu apa yangback()
terjadi (apakah ada efek samping? Apakah itu mengubah representasi internalb
?), Jadi loop ini tidak setara dengan yang ada di pertanyaan.v = b.back()
dipindahkan di luar loop, di atasnya. (Juga, jika Anda mencoba menanggapi seseorang, gunakan@
di depan nama mereka, jadi kami mendapat pemberitahuan)adalah inisialisasi.
adalah kondisinya.
adalah iterasi
sumber
Kondisi adalah hasil dari
u--
, yang merupakan nilaiu
sebelum dikurangi.Dalam C dan C ++, sebuah
int
dapat dikonversi menjadi bool dengan secara implisit melakukan!= 0
perbandingan (0 adalahfalse
, yang lainnyatrue
).b.back()
adalah elemen terakhir dalam sebuah wadah, yaitub[b.size() - 1]
, kapansize() != 0
.sumber
Dalam C semuanya non-nol
true
dalam konteks "boolean", seperti kondisi akhir loop atau pernyataan kondisional. Dalam C # Anda harus membuat cek eksplisit:u-- != 0
.sumber
Seperti yang dinyatakan oleh orang lain, fakta bahwa C ++ memiliki casting implisit ke boolean berarti kondisional
u--
, yang akan benar jika nilainya tidak nol.Perlu ditambahkan, bahwa Anda memiliki asumsi yang salah dalam bertanya "di mana kondisional". Dalam C ++ dan C # (dan bahasa sintaksis lainnya yang serupa) Anda dapat memiliki kondisi kosong. Dalam hal ini selalu bernilai true, sehingga loop terus selamanya, atau sampai beberapa keluar kondisi lain (melalui
return
,break
atauthrow
).Memang, bagian mana pun dari pernyataan for dapat diabaikan, dalam hal ini tidak dilakukan.
Secara umum,
for(A; B; C){D}
ataufor(A; B; C)D;
menjadi:Satu atau lebih dari A, B, C atau D dapat diabaikan.
Sebagai akibatnya, beberapa bantuan
for(;;)
untuk loop tak terbatas. Saya melakukannya karena walaupunwhile(true)
lebih populer, saya membacanya sebagai "sampai kebenaran berakhir menjadi kenyataan", yang terdengar agak apokaliptik dibandingkan dengan pembacaan sayafor(;;)
sebagai "selamanya".Ini masalah selera, tetapi karena saya bukan satu-satunya orang di dunia yang menyukainya
for(;;)
, perlu mengetahui artinya.sumber
semua jawaban sudah benar: -
untuk loop dapat digunakan dalam berbagai cara sebagai berikut:
sumber
Dalam kode di atas,
u
danv
diinisialisasi denganb.size()
danb.back()
.Setiap kali kondisi diperiksa, ia mengeksekusi pernyataan penurunan juga yaitu
u--
.The
for
Loop akan keluar ketikau
akan menjadi0
.sumber
Kesalahan yang ditemui dalam C # itu sendiri menghapus keraguan. Pencarian for-loop untuk a
kondisi untuk mengakhiri. Dan seperti yang kita ketahui,
tetapi C # tidak dapat memproses ini sendiri tidak seperti C ++. Jadi kondisi yang Anda cari adalah
tetapi Anda harus secara eksplisit memberikan kondisi dalam C # as
atau
Tetapi tetap mencoba untuk menghindari praktik pengkodean semacam ini. Itu
dinyatakan di atas dalam jawaban adalah salah satu versi yang paling disederhanakan dari Anda
sumber
Jika Anda terbiasa dengan C / C ++ kode ini tidak terlalu sulit dibaca, meskipun cukup singkat dan tidak terlalu bagus. Jadi izinkan saya menjelaskan bagian-bagian yang lebih Cism daripada yang lain. Pertama, sintaks umum dari C untuk loop terlihat seperti ini:
Kode inisialisasi dijalankan sekali. Kemudian kondisi diuji sebelum setiap loop dan terakhir kenaikan dipanggil setelah setiap loop. Jadi, dalam contoh Anda, Anda akan menemukan kondisinya
u--
Mengapa
u--
berfungsi sebagai kondisi dalam C dan bukan C #? Karena C secara implisit mengubah banyak hal terlalu bodoh dan dapat menyebabkan masalah. Untuk bilangan apa pun yang bukan nol adalah benar dan nol adalah salah. Jadi itu akan menghitung mundur dari b.ukuran () - 1 ke 0. Memiliki efek samping dalam kondisi agak mengganggu dan akan lebih baik untuk meletakkannya di bagian kenaikan untuk loop, meskipun banyak C kode melakukan ini. Jika saya menulisnya, saya akan melakukannya lebih seperti ini:Alasannya adalah, setidaknya bagi saya, lebih jelas. Setiap bagian dari for loop melakukan tugasnya dan tidak ada yang lain. Dalam kode asli syaratnya adalah memodifikasi variabel. Bagian kenaikan sedang melakukan sesuatu yang harus di blok kode dll.
Operator koma mungkin juga melempar Anda untuk loop. Dalam C sesuatu seperti
x=1,y=2
tampak seperti satu pernyataan sejauh menyangkut kompiler dan cocok dengan kode inisialisasi. Itu hanya mengevaluasi setiap bagian dan mengembalikan nilai yang terakhir. Jadi misalnya:akan mencetak 2.
sumber