Setelah kita bisa membuat dan mengisi array maupun vector, pekerjaan paling umum berikutnya adalah mengunjungi setiap elemennya: mencetak isi, menjumlahkan nilai, atau memodifikasi data. C++ menyediakan tiga gaya iterasi yang masing-masing memiliki kegunaan berbeda: loop indeks klasik ketika posisi dibutuhkan, range-based for ketika hanya nilainya yang penting, dan iterator eksplisit sebagai fondasi algoritma standard library. Pada Chapter ini kita mempraktikkan ketiganya pada satu vector yang sama agar perbedaannya terlihat jelas.

Empat Gaya dalam Satu Program #

Program berikut mengunjungi vector yang sama dengan empat pendekatan. Perhatikan pola output: gaya indeks dan nilai mengunjungi elemen asli, gaya reference mengubah elemen, lalu gaya iterator membaca hasil perubahannya.

cpp
#include <iostream>
#include <string>
#include <vector>

int main() {
    std::vector<std::string> kota = {"Jakarta", "Bandung", "Surabaya"};

    // Gaya 1: loop indeks klasik
    for (std::size_t i = 0; i < kota.size(); ++i) {
        std::cout << "indeks " << i << ": " << kota[i] << "\n";
    }

    // Gaya 2: range-based for by value (salinan)
    for (std::string nama : kota) {
        std::cout << "nilai: " << nama << "\n";
    }

    // Gaya 3: range-based for by reference (ubah elemen langsung)
    for (std::string& nama : kota) {
        nama = nama + "!";
    }

    // Gaya 4: iterator eksplisit
    for (auto it = kota.begin(); it != kota.end(); ++it) {
        std::cout << "iterator: " << *it << "\n";
    }

    return 0;
}

Output yang Dihasilkan:

text
indeks 0: Jakarta
indeks 1: Bandung
indeks 2: Surabaya
nilai: Jakarta
nilai: Bandung
nilai: Surabaya
iterator: Jakarta!
iterator: Bandung!
iterator: Surabaya!

Mari kita telaah apa yang terjadi pada baris-baris kode di atas:

  1. Baris 9-11 (Gaya 1): loop indeks memakai std::size_t agar tipenya cocok dengan size() yang unsigned. Gaya ini dipilih ketika posisi elemen dibutuhkan — di sini nomor indeks ikut dicetak.
  2. Baris 14-16 (Gaya 2): for (std::string nama : kota) menyalin setiap elemen ke variabel nama. Mengubah nama di dalam blok tidak memengaruhi elemen asli karena kita bekerja pada salinan.
  3. Baris 19-21 (Gaya 3): deklarasi std::string& nama menjadikan nama alias ke elemen asli. Penambahan "!" diterapkan langsung ke isi vector — itulah sebabnya gaya 4 selanjutnya mencetak Jakarta!, Bandung!, Surabaya!.
  4. Baris 24-26 (Gaya 4): iterator it menunjuk elemen, *it mengambil isinya, dan ++it bergerak ke elemen berikutnya. Loop berhenti ketika it mencapai kota.end() — posisi satu langkah setelah elemen terakhir.

Kapan Memakai Gaya yang Mana #

Setiap gaya punya keunggulan yang membuatnya tepat di situasi tertentu. Tabel berikut merangkum pemilihannya:

GayaGunakan ketikaKelemahan
Loop indeksposisi elemen dibutuhkan; melompati elemen; iterasi mundurlebih banyak kode; risiko salah batas
Range-based forsetiap elemen diproses sekali, berurutantidak ada indeks; tidak bisa mengubah struktur container
Iterator eksplisitmenyisip/menghapus di tengah; bekerja dengan algoritma STLsintaks paling verbose untuk pemula

Aturan praktis yang sehat: mulai dari range-based for karena paling ringkas dan tidak mungkin salah batas. Pindah ke loop indeks bila posisi memang diperlukan. Iterator eksplisit biasanya muncul ketika kita mulai memanggil algoritma seperti std::find atau menyisipkan elemen di tengah container — topik yang dibahas tuntas pada Section Iterators dan Algorithms.

Iterasi Array C-style dan std::array #

Ketiga gaya yang sama juga berlaku untuk array C-style dan std::array, dengan satu perbedaan kecil: array mentah tidak memiliki member .begin() dan .end(), tetapi std::begin() dan std::end() bebas-fungsi dari header <iterator> melayaninya. Range-based for bekerja pada array C-style tanpa bantuan apa pun karena compiler mengetahui ukurannya dari deklarasinya.

cpp
#include <array>
#include <iostream>

int main() {
    int angkaCStyle[] = {10, 20, 30};
    std::array<int, 3> angkaStd = {40, 50, 60};

    for (int nilai : angkaCStyle) {
        std::cout << "C-style  : " << nilai << "\n";
    }

    for (int nilai : angkaStd) {
        std::cout << "std::array: " << nilai << "\n";
    }

    return 0;
}

Output yang Dihasilkan:

text
C-style  : 10
C-style  : 20
C-style  : 30
std::array: 40
std::array: 50
std::array: 60

Kedua bentuk array diiterasi dengan range-based for tanpa perbedaan sintaks: compiler mengetahui ukuran angkaCStyle dari deklarasinya dan angkaStd membawa ukurannya sebagai bagian dari tipenya.

Catatan penting untuk array C-style yang dikirim ke fungsi: karena array ter-decay menjadi pointer saat menjadi parameter, range-based for di dalam fungsi penerima tidak bisa dipakai — informasi ukuran sudah hilang. Situasi ini dibedah tuntas pada Chapter array sebagai parameter fungsi, dan solusinya (memakai std::span atau meneruskan ukuran) sudah kita singgung di sana.

Satu kebiasaan terakhir yang layak dibiasakan: pada range-based for yang hanya membaca, gunakan const auto& (for (const std::string& nama : kota)) agar tidak ada salinan elemen yang dibuat. Pada elemen bertipe besar seperti std::string, hemat salinan ini terasa jelas ketika data membesar. Chapter berikutnya menutup Section ini dengan panduan memilih antara array C-style, std::array, std::vector, dan std::string untuk kebutuhan nyata.