Ini adalah latihan yang bagus .
Dengan membuat variabel di dalam loop, Anda memastikan cakupannya dibatasi di dalam loop. Itu tidak dapat dirujuk atau dipanggil di luar loop.
Cara ini:
Jika nama variabel sedikit "generik" (seperti "i"), tidak ada risiko untuk mencampurnya dengan variabel lain dengan nama yang sama di suatu tempat nanti dalam kode Anda (juga dapat dikurangi dengan menggunakan -Wshadow
instruksi peringatan pada GCC)
Kompilator tahu bahwa ruang lingkup variabel terbatas di dalam loop, dan karena itu akan mengeluarkan pesan kesalahan yang tepat jika variabel tersebut dirujuk secara tidak sengaja di tempat lain.
Last but not least, beberapa optimasi khusus dapat dilakukan lebih efisien oleh kompiler (paling penting mendaftar alokasi), karena ia tahu bahwa variabel tidak dapat digunakan di luar loop. Misalnya, tidak perlu menyimpan hasilnya untuk digunakan kembali nanti.
Singkatnya, Anda benar untuk melakukannya.
Namun perlu dicatat bahwa variabel tidak seharusnya mempertahankan nilainya antara setiap loop. Dalam hal demikian, Anda mungkin perlu menginisialisasi setiap waktu. Anda juga dapat membuat blok yang lebih besar, mencakup loop, yang tujuan utamanya adalah mendeklarasikan variabel yang harus mempertahankan nilainya dari satu loop ke loop lainnya. Ini biasanya termasuk penghitung putaran itu sendiri.
{
int i, retainValue;
for (i=0; i<N; i++)
{
int tmpValue;
/* tmpValue is uninitialized */
/* retainValue still has its previous value from previous loop */
/* Do some stuff here */
}
/* Here, retainValue is still valid; tmpValue no longer */
}
Untuk pertanyaan # 2: Variabel dialokasikan satu kali, ketika fungsi dipanggil. Bahkan, dari perspektif alokasi, itu (hampir) sama dengan mendeklarasikan variabel di awal fungsi. Satu-satunya perbedaan adalah ruang lingkup: variabel tidak dapat digunakan di luar loop. Bahkan dimungkinkan bahwa variabel tidak dialokasikan, hanya menggunakan kembali beberapa slot gratis (dari variabel lain yang ruang lingkupnya telah berakhir).
Dengan ruang lingkup terbatas dan lebih tepat datang optimasi yang lebih akurat. Tetapi yang lebih penting, itu membuat kode Anda lebih aman, dengan lebih sedikit status (yaitu variabel) yang perlu dikhawatirkan saat membaca bagian lain dari kode.
Ini benar bahkan di luar if(){...}
blok. Biasanya, alih-alih:
int result;
(...)
result = f1();
if (result) then { (...) }
(...)
result = f2();
if (result) then { (...) }
lebih aman untuk menulis:
(...)
{
int const result = f1();
if (result) then { (...) }
}
(...)
{
int const result = f2();
if (result) then { (...) }
}
Perbedaannya mungkin tampak kecil, terutama pada contoh kecil seperti itu. Tetapi pada basis kode yang lebih besar, ini akan membantu: sekarang tidak ada risiko untuk memindahkan sejumlah result
nilai dari f1()
ke f2()
blok. Masing result
- masing sangat terbatas pada ruang lingkupnya sendiri, menjadikan perannya lebih akurat. Dari sudut pandang pengulas, ini jauh lebih baik, karena ia memiliki variabel status jarak jauh yang kurang perlu dikhawatirkan dan dilacak.
Bahkan kompiler akan membantu lebih baik: dengan asumsi bahwa, di masa depan, setelah beberapa perubahan kode yang salah, result
tidak diinisialisasi dengan benar f2()
. Versi kedua hanya akan menolak untuk bekerja, menyatakan pesan kesalahan yang jelas pada waktu kompilasi (jauh lebih baik daripada waktu berjalan). Versi pertama tidak akan menemukan apa pun, hasilnya f1()
hanya akan diuji untuk kedua kalinya, menjadi bingung untuk hasilnya f2()
.
Informasi pelengkap
Alat open-source CppCheck (alat analisis statis untuk kode C / C ++) memberikan beberapa petunjuk yang sangat baik mengenai ruang lingkup variabel yang optimal.
Menanggapi komentar tentang alokasi: Aturan di atas benar dalam C, tetapi mungkin tidak untuk beberapa kelas C ++.
Untuk tipe dan struktur standar, ukuran variabel diketahui pada waktu kompilasi. Tidak ada yang namanya "konstruksi" di C, jadi ruang untuk variabel hanya akan dialokasikan ke stack (tanpa inisialisasi), ketika fungsi dipanggil. Itu sebabnya ada biaya "nol" ketika mendeklarasikan variabel di dalam satu loop.
Namun, untuk kelas C ++, ada hal konstruktor ini yang saya tahu jauh tentang. Saya kira alokasi mungkin tidak akan menjadi masalah, karena kompiler harus cukup pintar untuk menggunakan kembali ruang yang sama, tetapi inisialisasi kemungkinan terjadi pada setiap perulangan loop.