Blok adalah daftar pernyataan yang akan dieksekusi. Contoh di mana blok muncul di C adalah setelah pernyataan sementara dan di jika pernyataan
while( boolean expression)
statement OR block
if (boolean expression)
statement OR block
C juga memungkinkan blok untuk disarangkan di blok. Saya dapat menggunakan ini untuk menggunakan kembali nama variabel, misalkan saya sangat suka 'x'
int x = 0;
while (x < 10)
{
{
int x = 5;
printf("%d",x)
}
x = x+1;
}
akan mencetak nomor 5 sepuluh kali. Saya kira saya bisa melihat situasi di mana menjaga jumlah nama variabel rendah diinginkan. Mungkin dalam ekspansi makro. Namun, saya tidak dapat melihat alasan sulit untuk memerlukan fitur ini. Adakah yang bisa membantu saya memahami penggunaan fitur ini dengan menyediakan beberapa idiom di mana ia digunakan.
Jawaban:
Idenya bukan untuk menjaga jumlah nama variabel rendah atau mendorong penggunaan kembali nama, tetapi untuk membatasi ruang lingkup variabel. Jika Anda memiliki:
maka ruang lingkup
y
terbatas pada blok, yang berarti Anda dapat melupakannya sebelum atau setelah blok. Anda melihat ini paling sering digunakan sehubungan dengan loop dan kondisional. Anda juga melihatnya lebih sering dalam bahasa mirip C seperti C ++, di mana variabel yang keluar dari ruang lingkup menyebabkan kehancurannya.sumber
Karena di masa lalu C variabel baru hanya bisa dideklarasikan di blok baru.
Dengan cara ini programmer dapat memperkenalkan variabel baru di tengah fungsi tanpa membocorkannya dan meminimalkan penggunaan stack.
Dengan pengoptimal hari ini tidak ada gunanya dan tanda bahwa Anda perlu mempertimbangkan mengekstraksi blok dalam fungsinya sendiri.
Dalam pernyataan beralih, penting untuk melampirkan kasus di blok mereka sendiri untuk menghindari deklarasi ganda.
Dalam C ++ ini sangat berguna misalnya untuk penjaga kunci RAII dan memastikan destruktor menjalankan kunci pelepasan ketika eksekusi keluar dari ruang lingkup dan masih melakukan hal-hal lain di luar bagian kritis.
sumber
Saya tidak akan melihatnya sebagai blok "sewenang-wenang". Ini bukan fitur yang sangat berarti bagi penggunaan pengembang, tetapi cara C menggunakan blok memungkinkan konstruksi blok yang sama untuk digunakan di sejumlah tempat dengan semantik yang sama. Blok (dalam C) adalah ruang lingkup baru, dan variabel yang membiarkannya dihilangkan. Ini seragam terlepas dari bagaimana blok digunakan.
Dalam bahasa lain, ini bukan masalahnya. Ini memiliki keuntungan dengan memungkinkan lebih sedikit penyalahgunaan seperti yang Anda tunjukkan, tetapi kerugian yang menghalangi perilaku berbeda tergantung pada apa konteksnya.
Saya jarang melihat blok mandiri yang digunakan dalam C atau C ++ - sering kali ketika ada struktur besar atau objek yang mewakili koneksi atau sesuatu yang Anda ingin paksa penghancurannya. Biasanya ini adalah petunjuk bahwa fungsi Anda melakukan terlalu banyak hal dan / atau terlalu lama.
sumber
Anda harus sadar, prinsip-prinsip pemrograman yang tampak jelas sekarang tidak selalu demikian. Praktik terbaik C sangat tergantung pada berapa usia contoh Anda. Ketika C pertama kali diperkenalkan, memecah kode Anda menjadi fungsi-fungsi kecil dianggap terlalu tidak efisien. Dennis Ritchie pada dasarnya berbohong dan mengatakan panggilan fungsi sangat efisien dalam C (mereka tidak pada saat itu), yang membuat orang mulai menggunakan mereka lebih banyak, meskipun programmer C entah bagaimana tidak pernah benar-benar melewati budaya optimalisasi prematur.
Ini adalah praktik pemrograman yang baik bahkan hari ini untuk membatasi ruang lingkup variabel Anda sekecil mungkin. Saat ini, kami biasanya melakukan itu dengan membuat fungsi baru, tetapi jika fungsi dianggap mahal, memperkenalkan blok baru adalah cara logis untuk membatasi ruang lingkup Anda tanpa overhead panggilan fungsi.
Namun, saya mulai pemrograman dalam C lebih dari 20 tahun yang lalu, ketika Anda harus mendeklarasikan semua variabel Anda di bagian atas ruang lingkup, dan saya tidak ingat variabel shadowing seperti itu pernah dianggap gaya yang baik. Mendeklar ulang dalam dua blok satu demi satu seperti dalam pernyataan switch, ya, tapi tidak membayangi. Mungkin jika variabel sudah digunakan dan nama spesifik adalah sangat idiomatic untuk API Anda menelepon, seperti
dest
dansrc
distrcpy
, misalnya.sumber
Blok arbitrer berguna untuk memperkenalkan variabel perantara yang hanya digunakan dalam kasus khusus perhitungan.
Ini adalah pola umum dalam komputasi ilmiah, di mana prosedur numerik biasanya:
Karena poin kedua, berguna untuk memperkenalkan variabel sementara lingkup terbatas, yang dicapai jika menggunakan blok arbitrer atau dengan memperkenalkan fungsi bantu.
Sementara memperkenalkan fungsi tambahan mungkin terlihat seperti tidak punya otak atau praktik terbaik untuk diikuti secara membabi buta, sebenarnya ada sedikit manfaat untuk melakukannya dalam situasi khusus ini.
Karena ada banyak parameter dan jumlah perantara, kami ingin memperkenalkan struktur untuk meneruskannya ke fungsi bantu.
Tetapi, karena kami ingin menjadi konsekuen dengan praktik kami, kami tidak akan memperkenalkan hanya satu fungsi tambahan tetapi beberapa. Jadi, apakah kita memperkenalkan struktur ad-hoc menyampaikan parameter untuk setiap fungsi, yang memperkenalkan banyak kode-overhead untuk memindahkan parameter bolak-balik, atau kami memperkenalkan satu akan memerintah mereka semua struktur lembar kerja, yang berisi semua variabel kami tetapi terlihat seperti grabpack bit tanpa konsistensi, di mana setiap saat hanya separuh parameter memiliki makna yang menarik.
Oleh karena itu struktur bantu ini biasanya rumit dan menggunakannya berarti memilih antara kode-mengasapi atau memperkenalkan abstraksi yang ruang lingkupnya terlalu luas dan melemahkan arti program, alih-alih memilahnya .
Memperkenalkan fungsi bantu dapat memudahkan pengujian unit pada program dengan memperkenalkan granularitas uji yang lebih baik tetapi menggabungkan pengujian unit untuk tidak bahwa prosedur tingkat rendah dan pengujian regresi dalam bentuk perbandingan (dengan jumlah tambahan) jejak numerik prosedur melakukan pekerjaan yang sama baiknya .
sumber
Secara umum, penggunaan kembali nama variabel dengan cara ini menyebabkan terlalu banyak kebingungan bagi pembaca kode Anda di masa mendatang. Lebih baik hanya memberi nama variabel dalam sesuatu yang lain. Bahkan, bahasa C # secara khusus melarang penggunaan variabel dengan cara ini.
Saya bisa melihat bagaimana penggunaan blok bersarang dalam ekspansi makro akan berguna untuk mencegah tabrakan penamaan variabel.
sumber
Ini untuk pelingkupan hal-hal yang biasanya tidak memiliki cakupan pada tingkat itu. Ini sangat jarang, dan secara umum refactoring adalah pilihan yang lebih baik, tapi saya pernah bertemu sekali atau dua kali di masa lalu dalam pernyataan switch:
Ketika Anda mempertimbangkan pemeliharaan, refactoring ini harus seimbang dengan memiliki semua implementasi berturut-turut, selama masing-masing hanya beberapa baris panjang. Lebih mudah untuk menggabungkan semuanya, daripada daftar nama fungsi.
Dalam kasus saya, jika saya ingat dengan benar, sebagian besar kasus adalah sedikit variasi dari kode yang sama - kecuali bahwa salah satu dari mereka identik dengan yang lain, hanya dengan preprocessing tambahan. Switch akhirnya menjadi bentuk paling sederhana untuk mengambil kode, dan ruang lingkup tambahan memungkinkan penggunaan variabel lokal ekstra yang tidak perlu dikhawatirkan olehnya (seperti nama variabel yang secara tidak sengaja tumpang tindih dengan yang didefinisikan sebelum switch tetapi digunakan nanti).
Perhatikan bahwa pernyataan peralihan hanyalah penggunaannya yang pernah saya jumpai. Saya yakin itu bisa diterapkan di tempat lain juga, tetapi saya tidak ingat melihat mereka digunakan secara efektif seperti itu.
sumber