Hampir setiap algoritma mengandung keputusan: apakah indeks valid? apakah elemen lebih kecil dari pivot? apakah state mesin sedang berjalan? Percabangan adalah cara C++ mengatur alur kontrol berdasarkan kondisi bool. Pada Chapter ini kita akan mempelajari if/else if/else, switch, dan ternary operator — beserta pola penggunaannya yang sering muncul di kode DSA seperti penanganan edge case dan klasifikasi state.

if, else if, dan else #

Pernyataan if mengevaluasi sebuah kondisi bool. Bila bernilai true, blok di bawahnya dijalankan; bila false, alur melompat ke else if berikutnya atau ke else bila ada.

Mekanisme: Evaluasi Berurutan dan Short-Circuit #

Saat beberapa else if dirantai, C++ mengevaluasi kondisi dari atas ke bawah dan hanya menjalankan blok pertama yang kondisinya true. Sisa cabang tidak dievaluasi lagi. Pola ini cocok untuk klasifikasi bertingkat seperti pengelompokan nilai.

Kode: Klasifikasi Nilai #

cpp
#include <iostream>

char kategori_nilai(int n) {
    if (n >= 90) return 'A';
    else if (n >= 80) return 'B';
    else if (n >= 70) return 'C';
    else if (n >= 60) return 'D';
    else return 'E';
}

int main() {
    int daftar[] = {95, 82, 75, 60, 40};
    for (int i = 0; i < 5; ++i) {
        std::cout << "nilai " << daftar[i] << " -> "
                  << kategori_nilai(daftar[i]) << '\n';
    }
    return 0;
}

Output yang Dihasilkan:

text
nilai 95 -> A
nilai 82 -> B
nilai 75 -> C
nilai 60 -> D
nilai 40 -> E
  1. Baris if (n >= 90) return 'A';: bila n minimal 90, fungsi langsung mengembalikan 'A'. Setelah return, cabang lain tidak diperiksa.
  2. Baris else if (n >= 80): hanya dievaluasi bila n < 90. Urutan cabang penting karena rentang saling tumpang tindih.
  3. Baris else return 'E';: cabang akhir menangkap semua nilai yang gagal di atasnya — fallback yang menjamin fungsi selalu mengembalikan sesuatu.

Edge Case: Validasi Input #

Salah satu kesalahan paling umum dalam algoritma adalah lupa menangani input kosong atau nilai batas. Kita perlu mengecek kondisi tersebut sebelum melakukan operasi yang berisiko seperti indexing array atau pembagian.

Kode: Validasi Sebelum Operasi #

cpp
#include <iostream>
#include <vector>

int main() {
    std::vector<int> data;          // sengaja kosong
    if (data.empty()) {
        std::cout << "tidak ada data\n";
    } else {
        std::cout << "elemen pertama = " << data.front() << '\n';
    }

    int n = 0;
    if (n <= 0) {
        std::cout << "input tidak valid\n";
    }
    return 0;
}

Output yang Dihasilkan:

text
tidak ada data
input tidak valid
  1. Baris if (data.empty()): pengecekan empty() mencegah kita memanggil data.front() pada vector kosong, yang merupakan undefined behavior.
  2. Baris if (n <= 0): menangkap input nol atau negatif sebelum dipakai dalam perhitungan iteratif seperti pembagian atau loop sebesar n.

switch untuk State Mesin #

switch cocok bila kita memilih satu di antara banyak cabang berdasarkan nilai konstanta integer atau enum. Compiler sering mengoptimalkannya menjadi jump table yang lebih cepat daripada rentetan if/else.

Mekanisme: Fall-through dan break #

Setiap case pada switch harus diakhiri break untuk berhenti. Tanpa break, eksekusi akan fall-through ke case berikutnya — kadang diinginkan, tetapi sering kali bug. C++17 memperkenalkan atribut [[fallthrough]] untuk menandai fall-through yang sengaja.

Kode: State Mesin Sederhana #

cpp
#include <iostream>

enum State { IDLE, RUNNING, STOPPED };

int main() {
    State s = RUNNING;
    switch (s) {
        case IDLE:
            std::cout << "mesin idle\n";
            break;
        case RUNNING:
            std::cout << "mesin berjalan\n";
            break;
        case STOPPED:
            std::cout << "mesin berhenti\n";
            break;
        default:
            std::cout << "state tidak dikenal\n";
    }
    return 0;
}

Output yang Dihasilkan:

text
mesin berjalan
  1. Baris enum State { IDLE, RUNNING, STOPPED };: mendefinisikan tipe enumerasi dengan tiga konstanta. Nilai default IDLE=0, RUNNING=1, STOPPED=2.
  2. Baris switch (s): mengevaluasi s dan melompat ke case yang cocok. Hanya satu cabang yang dijalankan berkat break.
  3. Baris default:: menangkap nilai yang tidak tercantum di case apa pun — penting untuk future-proofing bila enum ditambah anggota baru.

Ternary Operator #

Ternary kondisi ? a : b adalah cara ringkas untuk memilih satu dari dua nilai berdasarkan kondisi bool. Ternary menghasilkan nilai, sehingga bisa dipakai dalam inisialisasi const atau argumen fungsi — sesuatu yang tidak bisa dilakukan if/else.

Kode: Default Value dengan Ternary #

cpp
#include <iostream>

int main() {
    int ukuran_user = 0;
    int pakai = (ukuran_user == 0) ? 16 : ukuran_user;
    std::cout << "ukuran pakai = " << pakai << '\n';

    int a = 7, b = 12;
    int maks = (a > b) ? a : b;
    std::cout << "maks = " << maks << '\n';
    return 0;
}

Output yang Dihasilkan:

text
ukuran pakai = 16
maks = 12
  1. Baris int pakai = (ukuran_user == 0) ? 16 : ukuran_user;: jika ukuran_user nol, gunakan default 16. Pola ini sering muncul saat memilih ukuran awal container atau kapasitas buffer.
  2. Baris int maks = (a > b) ? a : b;: memilih bilangan yang lebih besar dalam satu ekspresi tanpa blok if/else.

Kapan Memilih Apa #

SkenarioSarana
Rentang nilai (≥, ≤, kombinasi kondisi)if / else if
Nilai diskret konstanta atau enumswitch
Memilih satu dari dua nilai dalam ekspresiternary ?:
Cabang dengan efek samping banyak barisif / else

Ringkasan #

  • if/else if/else cocok untuk klasifikasi berbasis rentang; evaluasi berhenti pada cabang pertama yang true.
  • Selalu uraikan edge case di awal fungsi untuk mencegah undefined behavior pada input kosong.
  • switch efisien untuk cabang berbasis konstanta integer/enum; jangan lupa break di setiap case.
  • Ternary menghasilkan nilai — pakai untuk inisialisasi ringkas, bukan untuk cabang yang kompleks.