Ketiga loop yang sudah kita pelajari — for, while, do-while — mengandalkan counter dan kondisi indeks. Padahal kebutuhan yang paling sering muncul jauh lebih sederhana: “kerjakan sesuatu untuk SETIAP elemen dalam koleksi ini”. Loop yang disebut range-based for (bentuk lengkapnya for (elemen : koleksi)) dirancang khusus untuk itu; ia diperkenalkan di C++11 dan sejak itu menjadi loop paling populer di kode C++ modern. Pada Chapter ini kita mengunjungi array, std::string, dan std::vector dengannya, lalu membahas keputusan penting di balik bentuknya: menyalin elemen atau meminjamnya lewat reference.

Bentuk Dasar: Setiap Elemen, Tanpa Indeks #

Strukturnya dua bagian: di kiri titik dua ada variabel yang menerima elemen, di kanan ada koleksinya. Loop sendiri yang mengurus pengambilan elemen dari awal sampai akhir — tidak ada i, tidak ada i < ukuran, tidak ada kemungkinan salah batas. Mari kita kunjungi tiga jenis koleksi sekaligus:

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

int main() {
    // std::vector: container dinamis; dibahas tuntas pada Chapter std::vector
    std::vector<int> skor = {90, 85, 77};

    for (int s : skor) {
        std::cout << "Skor: " << s << "\n";
    }

    for (int x : {2, 4, 6}) {   // initializer_list literal
        std::cout << "Angka: " << x << "\n";
    }

    std::string nama = "Budi";
    for (char c : nama) {       // setiap karakter dalam string
        std::cout << c << "\n";
    }

    return 0;
}

Output yang Dihasilkan:

text
Skor: 90
Skor: 85
Skor: 77
Angka: 2
Angka: 4
Angka: 6
B
u
d
i

Tiga koleksi, satu pola:

  1. Baris 7 (std::vector<int> skor): std::vector adalah container standar yang isinya bisa bertambah — di Chapter ini cukup dipahami sebagai “daftar nilai”; detailnya menanti pada Chapter std::vector di Section Array dan String. Karena ada di sini, header <vector> ikut di-include pada baris 3.
  2. Baris 9-11 (for (int s : skor)): pada setiap putaran, elemen berikutnya dari skor disalin ke variabel s, lalu badan mencetaknya. Loop berjalan persis sebanyak jumlah elemen — 3 putaran, tanpa konstanta batas yang ditulis tangan.
  3. Baris 13-15 (for (int x : {2, 4, 6})): kanan titik dua boleh berupa initializer_list literal — daftar nilai yang ditulis langsung di tempat, praktis untuk iterasi sekali jalan.
  4. Baris 18-20 (for (char c : nama)): std::string pun bisa dikunjungi; yang “diputarkan” adalah karakternya satu per satu, sehingga tiap huruf “Budi” tercetak pada barisnya sendiri.

Perhatikan apa yang HILANG dari kode ini dibanding loop berindeks: tidak ada deklarasi batas, tidak ada ekspresi skor[i], dan tidak ada peluang kesalahan off-by-one (salah satu/dua putaran). Bila kita menulis for (int s : skor) atas koleksi 3 elemen, jumlah putarannya dijamin 3. Sintaks lengkap range-based for tersaji di cppreference .

by Value versus by Reference #

Kiri titik dua adalah deklarasi variabel biasa — dan di sanalah keputusan penting bersembunyi: int s menerima SALINAN elemen, sedangkan int& s menerima alias ke elemen aslinya. Tanda & di situ menandai reference, konsep yang akan dibedah tuntas pada Section Pointer dan Reference; untuk sekarang cukup pahami bahwa & mengubah “salinan” menjadi “jendela ke aslinya”. Program berikut memperlihatkan konsekuensinya:

cpp
#include <iostream>
#include <vector>

int main() {
    std::vector<int> harga = {10, 20, 30};

    // by value: mengubah salinan, elemen asli tidak tersentuh
    for (int h : harga) {
        h = h * 2;
    }
    std::cout << "Setelah loop by value: "
              << harga[0] << ", " << harga[1] << ", " << harga[2] << "\n";

    // by reference: mengubah elemen asli di dalam vector
    for (int& h : harga) {
        h = h * 2;
    }
    std::cout << "Setelah loop by reference: "
              << harga[0] << ", " << harga[1] << ", " << harga[2] << "\n";

    // const reference: membaca tanpa menyalin, gaya modern dengan auto
    for (const auto& h : harga) {
        std::cout << "Harga: " << h << "\n";
    }

    return 0;
}

Output yang Dihasilkan:

text
Setelah loop by value: 10, 20, 30
Setelah loop by reference: 20, 40, 60
Harga: 20
Harga: 40
Harga: 60

Tiga loop, tiga pelajaran:

  1. Loop pertama (for (int h : harga)): h adalah salinan; menggandakannya dua kali hanya mengubah salinan yang dibuang di akhir putaran. Vector tetap 10, 20, 30 — inilah sumber bug klasik pemula: “loop saya berjalan, tetapi datanya tidak berubah”.
  2. Loop kedua (for (int& h : harga)): tanda & membuat h alias ke elemen asli; perkalian menulis ulang elemen vector itu sendiri, sehingga tercetak 20, 40, 60.
  3. Loop ketiga (for (const auto& h : harga)): const melarang perubahan sekaligus mendokumentasikan niat “hanya baca”, sedangkan auto membiarkan compiler menyimpulkan tipenya (lihat Chapter auto dan Type Deduction). Bentuk const auto& inilah gaya bawaan yang dianjurkan untuk membaca koleksi: benar, aman, dan tanpa biaya penyalinan.

Koleksi Apa Saja yang Didukung #

Range-based for bekerja pada semua koleksi yang punya awal dan akhir — konsep yang disebut range dan dibedah lebih dalam pada Section Iterators dan Algorithms. Yang sudah Anda pegang saat ini:

  • Array C biasa seperti int data[] = {1, 2, 3}; — loop tahu panjangnya dari tipenya.
  • std::string — memutarkan karakter, seperti contoh pertama.
  • std::vector dan std::array — container standar; std::array dibahas pada Chapter std::array dan std::vector di Section Standard Library.
  • initializer_list literal seperti {2, 4, 6} — daftar sementara yang ditulis langsung.

Satu detail mekanisme yang menenangkan: bila kanan titik dua berupa objek sementara (temporary), misalnya for (char c : std::string{"halo"}), C++ memperpanjang masa hidup objek sementara itu sampai loop selesai — sehingga pola di aman dan tidak membaca objek yang sudah dibongkar. Meski demikian, bentuk yang paling umum di kode nyata tetap mengiterasi variabel yang berumur lebih panjang.

Dengan range-based for, mengunjungi koleksi kini semurah satu baris header. Namun loop yang panjang sering perlu dihentikan di tengah jalan atau melompati putaran tertentu — dua kebutuhan yang dilayani break dan continue, topik Chapter berikutnya.