Hampir setiap algoritma berulang: menjelajah seluruh elemen array, membagi rentang untuk binary search, mengiterasi hingga kondisi terpenuhi. C++ menyediakan beberapa konstruksi perulangan yang masing-masing punya tempat terbaiknya. Pada Chapter ini kita akan mempelajari for klasik, while, do-while, dan range-based for — beserta kapan memakai yang mana dalam konteks DSA.

for Klasik #

for adalah pilihan utama bila jumlah iterasi sudah diketahui di awal: penjumlahan deret, traversal array dengan indeks, atau iterasi dari 0 sampai n-1.

Mekanisme: Tiga Bagian Header #

Header for (init; kondisi; step) memiliki tiga bagian dipisah titik koma. init dieksekusi sekali di awal. kondisi dievaluasi sebelum setiap iterasi — bila false, loop berhenti. step dijalankan di akhir setiap iterasi.

Kode: Penjumlahan Deret 1..n #

cpp
#include <iostream>

int main() {
    int n = 5;
    int total = 0;
    for (int i = 1; i <= n; ++i) {
        total += i;
    }
    std::cout << "sum 1..5 = " << total << '\n';
    return 0;
}

Output yang Dihasilkan:

text
sum 1..5 = 15
  1. Bagian int i = 1;: variabel counter i dideklarasikan dan diinisialisasi sekali. i hanya hidup di dalam loop.
  2. Bagian i <= n;: kondisi dicek sebelum setiap iterasi. Saat i menjadi 6, kondisi false, loop berhenti.
  3. Bagian ++i: increment di akhir iterasi. Memakai pre-increment ++i lebih efisien daripada i++ untuk tipe kompleks (tidak ada copy sementara), meski untuk int perbedaannya nihil.

while untuk Iterasi Bersyarat #

while cocok bila kita tidak tahu pasti berapa kali loop berjalan — kita hanya tahu kondisi yang harus tercapai. Contoh klasik: algoritma Euclidean GCD, mengecilkan rentang binary search, atau menghitung jumlah digit.

Kode: Hitung Jumlah Digit #

cpp
#include <iostream>

int main() {
    int angka = 12345;
    int digit = 0;
    int tmp = angka;
    while (tmp > 0) {
        tmp /= 10;
        ++digit;
    }
    std::cout << "digit dari " << angka << " = " << digit << '\n';
    return 0;
}

Output yang Dihasilkan:

text
digit dari 12345 = 5
  1. Baris int tmp = angka;: kita salin angka ke tmp agar nilai asli tidak rusak. Loop memodifikasi tmp hingga menjadi 0.
  2. Baris while (tmp > 0): kondisi dicek sebelum setiap iterasi. Saat tmp mencapai 0, loop berhenti.
  3. Baris tmp /= 10;: membuang digit terakhir. Setiap iterasi menambah digit sampai semua digit habis.

do-while: Minimal Sekali #

do-while mengevaluasi kondisi setelah iterasi pertama dijalankan, sehingga blok dijamin dieksekusi minimal satu kali. Jarang dipakai, tetapi berguna untuk menu interaktif atau loop yang butuh setidaknya satu langkah inisial.

Kode: Hitung Step dengan do-while #

cpp
#include <iostream>

int main() {
    int step = 0;
    int cap = 3;
    do {
        ++step;
    } while (step < cap);
    std::cout << "step akhir = " << step << '\n';
    return 0;
}

Output yang Dihasilkan:

text
step akhir = 3
  1. Baris do {: blok dijalankan pertama kali tanpa pengecekan kondisi apa pun.
  2. Baris } while (step < cap);: kondisi diperiksa setelah blok selesai. Bila true, loop mengulangi; bila false, berhenti. Perhatikan tanda titik koma di akhir.
  3. Pada iterasi terakhir, step bernilai 3 sehingga kondisi 3 < 3 menjadi false dan loop berhenti. Hasil akhir step adalah 3.

Range-Based for untuk Container #

Sejak C++11, range-based for memberi cara ringkas untuk menjelajah seluruh elemen container STL tanpa perlu indeks atau iterator eksplisit.

Mekanisme: Iterasi Tanpa Indeks #

Sintaks for (Tipe elem : container) mengikat elem ke setiap elemen secara berurutan. Tipe elem menentukan apakah kita mengakses copy, reference, atau const reference. Untuk container besar, pakai const T& agar tidak terjadi copy mahal.

Kode: Menjumlahkan Vector #

cpp
#include <iostream>
#include <vector>

int main() {
    std::vector<int> data{2, 4, 6, 8};
    long long sum = 0;
    for (int x : data) {
        sum += x;
    }
    std::cout << "sum vector = " << sum << '\n';

    // Versi const reference — lebih hemat untuk tipe besar
    long long sum2 = 0;
    for (const int& x : data) {
        sum2 += x;
    }
    std::cout << "sum2       = " << sum2 << '\n';
    return 0;
}

Output yang Dihasilkan:

text
sum vector = 20
sum2       = 20
  1. Baris for (int x : data): untuk setiap elemen data, nilai disalin ke x. Untuk int copy ini murah, tetapi untuk std::string akan mahal.
  2. Baris for (const int& x : data): referensi const — tidak ada copy, hanya membaca. Cocok bila kita tidak perlu memodifikasi elemen asli.
  3. Untuk memodifikasi elemen asli container, gunakan reference non-const: for (int& x : data) x *= 2;.

break dan continue #

break keluar dari loop secara paksa. continue melewatkan sisa iterasi saat ini dan langsung lompat ke iterasi berikutnya. Keduanya membuat kontrol alur lebih fleksibel, tetapi berlebihan akan menyulitkan pembacaan.

Kode: Mencari Elemen Pertama #

cpp
#include <iostream>
#include <vector>

int main() {
    std::vector<int> data{2, 4, 6, 8};
    int pertama_genap_diatas_5 = -1;
    for (int x : data) {
        if (x <= 5) continue;     // lewati yang tidak memenuhi syarat
        pertama_genap_diatas_5 = x;
        break;                    // keluar setelah ketemu
    }
    std::cout << "genap > 5 pertama = " << pertama_genap_diatas_5 << '\n';
    return 0;
}

Output yang Dihasilkan:

text
genap > 5 pertama = 6
  1. Baris if (x <= 5) continue;: bila x tidak lebih besar dari 5, lewati sisa iterasi dan lanjut ke elemen berikutnya. Pola ini efektif untuk filter awal.
  2. Baris break;: keluar dari loop setelah menemukan kandidat pertama yang valid. Menghindari iterasi sisa yang tidak perlu.

Kapan Memilih Apa #

SkenarioSarana
Jumlah iterasi diketahuifor klasik
Iterasi hingga kondisi tercapaiwhile
Butuh setidaknya satu eksekusido-while
Menjelajah seluruh container STLrange-based for
Mencari elemen pertama yang cocokfor + break

Ringkasan #

  • for klasik cocok untuk counter berbasis indeks; ingat tiga bagian init; kondisi; step.
  • while ideal bila kondisi berhenti tidak terkait langsung dengan jumlah iterasi.
  • do-while berguna saat blok harus dijalankan minimal satu kali.
  • Range-based for memberi sintaks ringkas untuk traversal container; gunakan const T& agar efisien.
  • break dan continue memperluas kontrol alur, tetapi jangan berlebihan agar kode tetap mudah dibaca.