Perulangan

for, while, do-while, dan foreach pada collections.

Daftar isi

Perulangan mengeksekusi blok kode secara berulang selama kondisinya terpenuhi. Topik ini membahas empat bentuk perulangan pada C#, yaitu for, while, do-while, dan foreach untuk collection. Setiap bentuk disertai contoh yang benar-benar dijalankan, kemudian ditutup dengan panduan memilih bentuk yang sesuai untuk suatu kebutuhan.

Perulangan for#

Perulangan for menggabungkan tiga bagian dalam satu baris, yaitu inisialisasi penghitung, kondisi kelanjutan, dan perubahan penghitung pada setiap putaran. Bagian inisialisasi dijalankan sekali di awal, kemudian kondisi diperiksa sebelum setiap putaran, dan badan perulangan dieksekusi selama kondisinya bernilai true. Setelah badan selesai, bagian perubahan penghitung dijalankan, lalu kondisi diperiksa kembali. Bentuk ini paling tepat apabila jumlah putaran sudah diketahui atau penghitung memang diperlukan di dalam badan.

csharp Contoh: perulangan for dengan penghitung menurun
// Contoh: perulangan for dengan penghitung menurun
for (int detik = 3; detik >= 1; detik--)
{
    Console.WriteLine($"Hitung mundur: {detik}");
}
text Keluaran
Hitung mundur: 3
Hitung mundur: 2
Hitung mundur: 1

Variabel detik dideklarasikan di dalam for sehingga hidupnya terbatas pada perulangan tersebut. Inisialisasi detik = 3, kondisi detik >= 1, dan langkah detik-- bekerja sama menghasilkan tiga putaran yang berhenti dengan sendirinya. Satu perulangan for juga dapat ditempatkan di dalam badan perulangan lain, dan susunan ini disebut perulangan bersarang.

csharp Contoh: perulangan for bersarang untuk tabel perkalian
// Contoh: perulangan for bersarang untuk tabel perkalian
for (int baris = 1; baris <= 3; baris++)
{
    for (int kolom = 1; kolom <= 3; kolom++)
    {
        Console.WriteLine($"{baris} x {kolom} = {baris * kolom}");
    }
}
text Keluaran
1 x 1 = 1
1 x 2 = 2
1 x 3 = 3
2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
3 x 1 = 3
3 x 2 = 6
3 x 3 = 9

Putaran luar memilih baris dan putaran dalam memilih kolom, sehingga sembilan kombinasi dicetak untuk tabel perkalian 3 x 3. Untuk setiap satu putaran luar, perulangan dalam menjalankan seluruh putarannya sampai selesai. Pola bersarang lazim digunakan untuk memproses data dua dimensi seperti tabel dan matriks.

Ketiga bagian pada for bersifat opsional dan boleh dibiarkan kosong, tetapi titik koma pemisahnya tetap wajib ditulis, sehingga bentuk for (;;) sah secara sintaks dan berperilaku sebagai perulangan tanpa syarat berhenti. Variabel penghitung juga tidak harus bertipe int, dan langkahnya tidak harus satu per satu, misalnya i += 5 untuk melangkah lima nilai sekali jalan. Nama penghitung sebaiknya tetap singkat dan bermakna, seperti baris dan kolom pada contoh bersarang, agar badan perulangan tetap terbaca.

while dan do-while#

Perulangan while memeriksa kondisinya sebelum setiap putaran, sehingga badannya dapat saja tidak pernah dijalankan. Bentuk do-while memeriksa kondisi setelah badan dieksekusi, sehingga badan pasti berjalan minimal satu kali. Perbedaan posisi pemeriksaan inilah yang membedakan kedua bentuk, dan pilihannya mengikuti kebutuhan program.

csharp Contoh: while dan do-while pada kondisi yang langsung salah
// Contoh: while dan do-while pada kondisi yang langsung salah
int stok = 0;

while (stok > 0)
{
    Console.WriteLine("while dijalankan");
    stok--;
}

do
{
    Console.WriteLine("do-while tetap dijalankan sekali");
    stok--;
} while (stok > 0);
text Keluaran
do-while tetap dijalankan sekali

Variabel stok bernilai 0 sejak awal, sehingga while melewati badannya tanpa mencetak apa pun. Sebaliknya, do-while menjalankan badannya terlebih dahulu, mencetak satu baris, kemudian berhenti karena kondisi stok > 0 bernilai false. Bentuk while cocok untuk menunggu keadaan yang mungkin sudah terpenuhi sejak awal, sedangkan do-while cocok untuk proses yang wajib dijalankan sekali sebelum dapat dinilai, misalnya menampilkan menu lalu membaca pilihan.

foreach pada collection#

Perulangan foreach menelusuri setiap elemen sebuah collection, yaitu struktur data yang menampung banyak elemen seperti array dan List<T>, tanpa mengelola penghitung secara manual. Variabel iterasi yang dideklarasikan pada foreach menampung elemen yang sedang ditelusuri dan bersifat hanya baca (read-only), sehingga penugasan ke variabel tersebut ditolak kompilator.

csharp Contoh: penugasan variabel iterasi foreach yang ditolak kompilator
// tidak-dijalankan
// Contoh: penugasan variabel iterasi foreach menghasilkan error CS1656
List<string> daftarBelanja = new() { "beras", "telur" };

foreach (string item in daftarBelanja)
{
    item = "minyak";
}

Kompilator melaporkan error CS1656 karena item adalah variabel iterasi foreach yang tidak boleh ditugasi. Larangan ini menjaga penelusuran tetap konsisten, karena elemen berjalan adalah hasil pembacaan collection dan bukan tempat penyimpanan. Larangan sejenis berlaku pula pada struktur collection itu sendiri, sebagaimana dijelaskan pada catatan berikut.

Perhatikan bahwa larangan tersebut menyasar perubahan struktur collection, bukan pembacaan elemen. Mengubah isi array sederhana dapat dilakukan dengan for yang mengakses elemen melalui indeks, sedangkan foreach dipilih ketika penelusuran murni dilakukan untuk membaca. Selain array dan List<T>, bentuk ini bekerja pada seluruh tipe yang mengimplementasikan antarmuka enumerasi bawaan .NET, sehingga satu pola penulisan sama berlaku untuk berbagai jenis collection.

Memilih bentuk perulangan#

Tabel berikut merangkum perbedaan keempat bentuk.

BentukWaktu pemeriksaan kondisiCocok untuk
forsebelum setiap putaranjumlah putaran diketahui atau penghitung diperlukan
whilesebelum setiap putaranputaran bergantung kondisi yang jumlahnya belum pasti
do-whilesetelah putaranbadan yang wajib dijalankan minimal satu kali
foreachper elemen, berhenti setelah elemen terakhirmenelusuri seluruh elemen collection tanpa penghitung

Program berikut merangkum keempat bentuk dalam satu berkas agar perilakunya dapat dibandingkan secara langsung.

csharp Program.cs
// Program perbandingan for, while, do-while, dan foreach

// for: jumlah perulangan diketahui, menghitung mundur
for (int detik = 3; detik >= 1; detik--)
{
    Console.WriteLine($"Hitung mundur: {detik}");
}

// while: pengulangan berhenti ketika kondisi tidak terpenuhi lagi
int stok = 8;
int pengambilan = 0;
while (stok > 5)
{
    stok -= 2;
    pengambilan++;
}
Console.WriteLine($"while: {pengambilan} kali pengambilan, stok tersisa {stok}");

// do-while: badan perulangan dijalankan minimal satu kali
int percobaan = 0;
do
{
    percobaan++;
} while (percobaan < 1);
Console.WriteLine($"do-while: badan dijalankan {percobaan} kali");

// foreach: menelusuri setiap elemen collection
List<string> daftarBelanja = new() { "beras", "telur", "minyak" };
foreach (string item in daftarBelanja)
{
    Console.WriteLine($"- {item}");
}
text Keluaran
Hitung mundur: 3
Hitung mundur: 2
Hitung mundur: 1
while: 2 kali pengambilan, stok tersisa 4
do-while: badan dijalankan 1 kali
- beras
- telur
- minyak

Bagian for menghitung mundur tiga kali, bagian while mengurangi stok dua unit per putaran hingga kondisinya terpenuhi, bagian do-while membuktikan badan berjalan satu kali meskipun kondisinya langsung salah, dan bagian foreach mencetak tiga elemen daftar belanja. Perhatikan bahwa perulangan while pada program tersebut melakukan dua pengambilan, yaitu stok berubah dari 8 menjadi 6 lalu 4, dan berhenti ketika syarat stok > 5 tidak lagi terpenuhi. Jalankan program tersebut dari folder topik dengan perintah berikut.

bash
# aktifkan .NET yang terpasang di sandbox
export DOTNET_ROOT=/home/kal/.dotnet PATH=/home/kal/.dotnet:$PATH DOTNET_CLI_TELEMETRY_OPTOUT=1 DOTNET_NOLOGO=1
# jalankan program contoh dari folder topik
dotnet run --file Program.cs
text Keluaran
Hitung mundur: 3
Hitung mundur: 2
Hitung mundur: 1
while: 2 kali pengambilan, stok tersisa 4
do-while: badan dijalankan 1 kali
- beras
- telur
- minyak

Kesalahan umum#

  • Menulis batas < dan <= secara tertukar, misalnya i <= angka.Length untuk array. Kesalahan off-by-one, yaitu meleset satu putaran, membuat program mengakses elemen di luar batas dan melempar exception.
  • Melupakan perubahan penghitung pada for atau while, sehingga kondisi selalu bernilai true dan perulangan menjadi tak berhingga (infinite loop). Periksa bagian perubahan penghitung setiap kali perulangan tidak berhenti.
  • Mengubah struktur collection di dalam foreach, yang mengakibatkan exception InvalidOperationException. Kumpulkan elemen yang akan dihapus, lalu lakukan perubahan setelah perulangan selesai.

Ringkasan#

  • for mengelola penghitung dalam satu baris dan tepat untuk jumlah putaran yang diketahui, sedangkan while dan do-while mengandalkan kondisi yang jumlah putarannya belum pasti.
  • Perbedaan while dan do-while terletak pada waktu pemeriksaan kondisi, sebelum atau sesudah badan dijalankan.
  • foreach menelusuri seluruh elemen collection tanpa penghitung, variabel iterasinya bersifat hanya baca, dan strukturnya tidak boleh diubah selama penelusuran berjalan.

Referensi#