Perulangan mengeksekusi blok pernyataan yang sama berkali-kali selama kondisinya terpenuhi, sehingga pekerjaan berulang tidak perlu ditulis berulang. Topik ini membahas perulangan for dengan pencacahnya, pasangan while dan do-while, serta range-based for yang mengunjungi setiap elemen array dan string. Setiap bentuk disertai program utuh dan keluaran aslinya, dan topik ditutup dengan panduan memilih bentuk yang tepat untuk setiap kebutuhan.
Perulangan for#
Perulangan for menggabungkan tiga bagian dalam satu kepala, yaitu inisialisasi, kondisi, dan pembaruan, ditulis for (inisialisasi; kondisi; pembaruan). Inisialisasi dijalankan sekali di awal, kondisi diuji sebelum setiap putaran, dan pembaruan dieksekusi setelah badan perulangan selesai. Variabel pencacah yang dideklarasikan pada bagian inisialisasi hidup hanya di dalam perulangan itu, sehingga nama yang sama bebas digunakan lagi oleh perulangan lain. Susunan satu baris ini membuat keseluruhan mekanisme putaran terlihat pada satu tempat. Bentuk for paling tepat ketika banyaknya putaran diketahui atau berpola tetap.
Program berikut mencetak tabel perkalian tujuh dari satu sampai sepuluh. Kepala perulangannya memuat seluruh aturan putarannya, dan badannya hanya berisi satu pernyataan cetak.
#include <iostream>
int main() {
for (int i = 1; i <= 10; ++i) {
std::cout << i << " x 7 = " << i * 7 << '\n';
}
return 0;
}1 x 7 = 7
2 x 7 = 14
3 x 7 = 21
4 x 7 = 28
5 x 7 = 35
6 x 7 = 42
7 x 7 = 49
8 x 7 = 56
9 x 7 = 63
10 x 7 = 70Pembaruan ditulis dengan bentuk awalan ++i karena nilai lama i tidak diperlukan pada baris tersebut, sedangkan kondisi i <= 10 menjaga putaran terakhir tetap terjadi. Bentuk awalan menjadi kebiasaan yang dianjurkan karena tidak perlu menyimpan nilai lama untuk dibaca kembali. Mengubah batas menjadi i < 10 membuang putaran kesepuluh, dan perbedaan sekecil ini merupakan sumber kesalahan off-by-one yang paling lazim. Menetapkan batas secara sadar sejak awal, kemudian mengujinya dengan kasus tepi, mencegah kesalahan semacam itu.
while dan do-while#
Perulangan while hanya menetapkan kondisinya, sehingga bentuknya tepat ketika banyaknya putaran tidak diketahui di awal. Kondisi diuji sebelum badan dijalankan, sehingga badan mungkin tidak pernah berjalan apabila kondisi sejak awal bernilai false. Bentuk do-while membalik urutan tersebut, yaitu badan dieksekusi terlebih dahulu dan kondisi diuji sesudahnya, sehingga badan dijamin berjalan sekali. Kepala do-while diakhiri tanda titik koma setelah kondisi, dan kelalaian menuliskannya menjadi error kompilasi yang sering terjadi. Pada kedua bentuk ini, badan perulangan harus mengubah nilai yang diuji kondisinya agar perulangan tidak berjalan tanpa akhir.
Program berikut menjumlahkan digit sebuah bilangan menggunakan while, kemudian menunjukkan perilaku do-while pada bilangan 0. Sisa pembagian nilai % 10 mengambil digit terakhir, sedangkan pembagian bulat nilai /= 10 membuang digit itu, dan pengulangan keduanya berhenti ketika nilai mencapai 0. Percobaan kedua pada bilangan 0 memperlihatkan perbedaan urutan pengujian antara kedua bentuk.
#include <iostream>
int main() {
int nilai = 4092;
int jumlah = 0;
while (nilai > 0) {
jumlah += nilai % 10;
nilai /= 10;
}
std::cout << "Jumlah digit 4092: " << jumlah << '\n';
int kosong = 0;
int jumlahKosong = 0;
do {
jumlahKosong += kosong % 10;
kosong /= 10;
} while (kosong > 0);
std::cout << "Jumlah digit 0: " << jumlahKosong << '\n';
return 0;
}Jumlah digit 4092: 15
Jumlah digit 0: 0Empat putaran while mengambil digit 4, 0, 9, dan 2, sehingga jumlahnya 15. Badan do-while tetap berjalan sekali meskipun kosong bernilai 0 sejak awal, tetapi hasilnya tetap 0 karena satu-satunya putaran itu tidak menambahkan apa pun. Pada kasus lain yang badannya berbahaya apabila dijalankan dengan data kosong, while menjadi pilihan yang lebih aman.
Range-based for atas array dan string#
Bentuk range-based for yang diperkenalkan pada C++11 mengunjungi setiap elemen sebuah rentang tanpa pencacah dan tanpa indeks, ditulis for (deklarasi : rentang). Rentangnya dapat berupa array, std::string, atau container pustaka standar lainnya. Satu putaran berlangsung untuk setiap elemen, dan elemennya dibaca melalui variabel pada bagian deklarasi. Tidak ada indeks yang dirawat, sehingga kesalahan batas yang biasa menimpa for klasik tidak mungkin muncul pada bentuk ini. Bentuknya juga lebih pendek karena tiga bagian mekanis for klasik tidak ditulis sama sekali.
Program berikut menjumlahkan daftar harga belanja, kemudian menghitung huruf vokal pada sebuah kata. Perulangan pertamanya membaca array, sedangkan perulangan keduanya membaca string karakter demi karakter.
#include <iostream>
#include <string>
int main() {
int harga[] = {3500, 12000, 7800, 4400};
int total = 0;
for (int h : harga) {
total += h;
}
std::cout << "Total belanja: " << total << '\n';
std::string kata = "kembang";
int jumlahVokal = 0;
for (char c : kata) {
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
++jumlahVokal;
}
}
std::cout << "Jumlah huruf vokal: " << jumlahVokal << '\n';
return 0;
}Total belanja: 27700
Jumlah huruf vokal: 2Perulangan pertama membaca setiap elemen array harga sebagai int, sedangkan perulangan kedua membaca kata sebagai deretan char. Apabila elemen perlu diubah di dalam badan perulangan, deklarasinya ditulis sebagai referensi (reference), yaitu nama yang merujuk elemen yang sama, misalnya for (int& h : harga). Apabila elemen hanya dibaca dan ukurannya besar, bentuk for (const auto& x : ...) menghindari penyalinan yang tidak perlu.
Memilih bentuk perulangan#
Keempat bentuk perulangan saling melengkapi, dan pilihan yang tepat membuat maksud kode terbaca tanpa penjelasan tambahan. Tabel berikut meringkas ciri setiap bentuk beserta waktu pengujian kondisinya.
| Bentuk | Cocok untuk | Pengujian kondisi |
|---|---|---|
for | Banyaknya putaran diketahui atau berpola tetap | Sebelum setiap putaran |
while | Putaran bergantung pada kondisi yang berubah di badan | Sebelum setiap putaran |
do-while | Badan yang wajib berjalan sekali, misalnya menu pilihan | Sesudah badan |
| Range-based for | Mengunjungi seluruh elemen array, string, atau container | Tanpa kondisi eksplisit |
Rentang yang dikunjungi range-based for ditentukan ketika perulangan dimulai, sehingga perubahan ukuran container di tengah jalan tidak ikut dihitung dan justru berisiko. Ketika putaran bergantung pada masukan pengguna atau kegagalan proses, while menggambarkan maksud itu dengan lebih tepat. Perulangan for klasik tetap unggul ketika langkahnya tidak satu demi satu, misalnya mengunjungi elemen bernomor genap saja. Selebihnya, pilihlah bentuk yang paling sederhana yang memenuhi kebutuhan, karena kebiasaan itu menjaga kode tetap mudah ditelusuri.
Kesalahan umum#
Tiga kesalahan berikut paling sering muncul ketika perulangan ditulis. Semuanya berakibat putaran yang salah atau perulangan yang tidak berhenti.
- Batas putaran yang meleset satu. Kondisi
i < 10dani <= 10berbeda satu putaran, sehingga elemen terakhir dapat terbuang atau satu putaran ekstra terjadi. Tetapkan batasnya secara sadar, kemudian uji dengan kasus tepi seperti nol dan satu elemen. - Pembaruan yang terlupakan pada
while. Tanpa pernyataan yang menggerakkan kondisi menuju berhenti, perulangan berjalan tanpa akhir dan program harus dihentikan paksa. Periksa bahwa badan perulangan selalu mengubah sesuatu yang diuji oleh kondisinya. - Rentang yang diubah di tengah range-based for. Menambahkan elemen ke container selama perulangan berlangsung dapat menggugurkan iterator internalnya, dan perilakunya tidak terdefinisi. Tangguhkan perubahan struktur sampai perulangan selesai, atau gunakan indeks dengan kehati-hatian.
Ketiganya sama-sama sulit terlihat pada sekilas pandang karena sintaksnya sah. Menjalankan program dengan data kecil yang batasnya mudah dihitung manual menjadi pemeriksaan paling murah sebelum kode yang lebih besar ditulis.
Ringkasan#
formenggabungkan inisialisasi, kondisi, dan pembaruan dalam satu kepala, dengan pencacah yang berlingkup pada perulangannya.whilemenguji kondisi sebelum badan, sedangkando-whilemenjamin badan berjalan sekali sebelum kondisi diuji.- Range-based for mengunjungi setiap elemen array, string, atau container tanpa indeks, sehingga kesalahan batas tidak mungkin terjadi pada bentuknya.
Referensi#
- for statement — cppreference.com
— Kaidah formal perulangan
fordan semantik ketiga bagiannya. - while loop — cppreference.com — Semantik pengujian kondisi sebelum badan perulangan.
- Range-for statement — cppreference.com — Kaidah range-based for sejak C++11 beserta padanan mekanisnya.
- For statements — Learn C++
— Pembahasan
for, evaluasi kondisi, dan kebiasaan penghitungan yang benar. - Range-based for loops (for-each) — Learn C++
— Pemakaian range-based for beserta referensi dan
constpada elemennya.