Percabangan menentukan jalur eksekusi yang ditempuh program berdasarkan hasil pengujian kondisi. Topik ini membahas pernyataan if beserta else dan rantai else if, bentuk if bersarang, serta bentuk C++17 if dengan initializer yang membatasi lingkup variabelnya. Setiap mekanisme disertai program utuh beserta keluaran aslinya, sehingga perilakunya dapat diuji ulang dengan compiler g++ apa adanya.
Kondisi pada pernyataan if#
Pernyataan if mengeksekusi blok pernyataannya hanya apabila kondisinya bernilai true. Kondisi tersebut berupa ekspresi yang dapat dikonversi menjadi bool, biasanya hasil operator perbandingan seperti >= atau ==. Apabila kondisi bernilai false, program melompati blok if dan melanjutkan eksekusi pada pernyataan berikutnya. Bentuk else menyediakan jalur cadangan yang dijalankan hanya ketika kondisi if tidak terpenuhi. Rantai else if menguji beberapa kondisi secara berurutan, dan C++ berhenti pada kondisi pertama yang terpenuhi, sehingga urutan pengujian ikut menentukan hasilnya.
Program berikut mengklasifikasikan nilai ujian ke dalam kategori A sampai D. Pengujian disusun dari ambang tertinggi ke ambang terendah, sehingga nilai 78 teruji terhadap batas 85 lebih dahulu, gagal, kemudian teruji terhadap batas 70 dan terpenuhi. Pola menyusun rentang dari atas ke bawah semacam ini menghindari tumpang tindih antara kategori.
#include <iostream>
int main() {
int nilai = 78;
if (nilai >= 85) {
std::cout << "Kategori: A\n";
} else if (nilai >= 70) {
std::cout << "Kategori: B\n";
} else if (nilai >= 55) {
std::cout << "Kategori: C\n";
} else {
std::cout << "Kategori: D\n";
}
return 0;
}Kategori: BKeluaran menunjukkan kategori B karena kondisi nilai >= 85 bernilai false dan kondisi nilai >= 70 bernilai true. Apabila urutan kedua kondisi itu dibalik, nilai apa pun di atas 70 akan teruji terhadap batas 70 lebih dahulu dan kategori A tidak pernah tercapai. Kesalahan logika semacam ini lolos dari pemeriksaan compiler karena sintaksnya sah.
if bersarang#
Sebuah if dapat ditempatkan di dalam blok if lain, dan susunan ini disebut if bersarang. Pemisahan yang tepat menempatkan syarat umum pada tingkat luar dan pengecekan rinci pada tingkat dalam, sehingga kondisi dalam hanya diuji ketika syarat luarnya terpenuhi. Urutan itu juga menghemat pengujian karena kondisi dalam tidak pernah
dievaluasi ketika syarat luarnya gagal. Contoh berikut mengatur peminjaman buku perpustakaan, yaitu jumlah buku diperiksa lebih dahulu, kemudian lama pinjamnya.
Program berikut menerapkan pola tersebut dengan dua tingkat pengujian. Kedua tingkatnya menggunakan tanda kurung kurawal meskipun isinya hanya satu pernyataan. Kebiasaan ini menuntaskan keraguan tentang batas blok pada tingkat mana pun.
#include <iostream>
int main() {
int jumlahBuku = 2;
int lamaPinjam = 5;
if (jumlahBuku <= 3) {
if (lamaPinjam <= 7) {
std::cout << "Peminjaman disetujui\n";
} else {
std::cout << "Lama pinjam melebihi batas\n";
}
} else {
std::cout << "Jumlah buku melebihi batas\n";
}
return 0;
}Peminjaman disetujuiNilai jumlahBuku bernilai 2 sehingga kondisi luar terpenuhi, kemudian kondisi dalam menguji lamaPinjam dan mencetak persetujuannya. Apabila jumlah buku sudah melebihi 3, kondisi dalam tidak pernah diuji sama sekali dan pesan pada else luar yang tampil. Pemisahan dua tingkat ini juga menghasilkan pesan yang lebih spesifik dibanding satu kondisi gabungan seperti jumlahBuku <= 3 && lamaPinjam <= 7. Satu kondisi gabungan hanya mampu menyatakan tolak atau terima, sedangkan bentuk bersarang dapat menjelaskan penyebab penolakan.
if dengan initializer (C++17)#
Sejak C++17, pernyataan if menerima satu pernyataan inisialisasi sebelum kondisinya dengan bentuk if (inisialisasi; kondisi). Variabel yang dideklarasikan pada bagian inisialisasi hidup sepanjang keseluruhan if beserta blok else-nya, kemudian musnah setelah percabangan selesai. Lingkup yang sempit itu menguntungkan karena variabel sementara tidak bocor ke kode di luar percabangan dan tidak mungkin diakses pada tempat yang tidak memerlukannya. Bentuk yang sama juga tersedia pada switch dengan kaidah lingkup yang identik.
Program berikut mencari petugas piket pada tabel hari yang disimpan dalam std::map milik pustaka standar. Pencarian dilakukan dengan fungsi anggota find. Fungsi ini mengembalikan iterator, yaitu penunjuk posisi elemen di dalam map, atau iterator end() apabila tidak ada data yang cocok. Kedua pencarian pada program ini menggunakan nama variabel cari yang sama karena masing-masing hanya hidup pada pernyataan if-nya sendiri.
#include <iostream>
#include <map>
#include <string>
int main() {
std::map<std::string, std::string> piket{
{"Senin", "Ali"}, {"Rabu", "Budi"}, {"Jumat", "Citra"}};
if (auto cari = piket.find("Rabu"); cari != piket.end()) {
std::cout << "Petugas piket: " << cari->second << '\n';
} else {
std::cout << "Tidak ada piket terjadwal\n";
}
if (auto cari = piket.find("Selasa"); cari != piket.end()) {
std::cout << "Petugas piket: " << cari->second << '\n';
} else {
std::cout << "Tidak ada piket terjadwal\n";
}
return 0;
}Petugas piket: Budi
Tidak ada piket terjadwalPada percabangan pertama, find menemukan kunci “Rabu” sehingga kondisi cari != piket.end() bernilai true dan nama petugasnya dicetak melalui cari->second. Percabangan kedua mencari “Selasa” yang tidak ada dalam tabel, sehingga blok else menampilkan pesan cadangan. Perbandingan terhadap end() merupakan cara standar membedakan hasil pencarian yang ditemukan dan yang gagal.
Kesalahan umum#
Kesalahan berikut sering muncul pada penulisan percabangan dan sebagian besar tidak menghasilkan pesan error. Pola semacam ini berbahaya karena program tetap terkompilasi, sedangkan alurnya menyimpang dari maksud penulisnya. Flag peringatan seperti -Wall membantu menangkap sebagiannya saat kompilasi.
- Operator penugasan
=dipakai pada tempat perbandingan==. Ekspresiif (nilai = 0)menugaskan 0 kepadanilai, kemudian mengujinya sebagaifalse, sehingga jalur program berubah tanpa pesan apa pun. Perbaikannya adalah penulisan==secara eksplisit disertai kompilasi dengan-Wallagar pola serupa terdeteksi sejak awal. - Tanda titik koma tepat setelah kondisi. Penulisan
if (kondisi);mengakhiri pernyataan dengan badan kosong, sehingga blok yang tampak sebagai isinya justru selalu dijalankan. Perbaikannya adalah penghapusan titik koma tersebut. elseberpasangan denganifterdalam yang masih terbuka. Padaifbersarang tanpa tanda kurung kurawal,elsedapat berpindah pasangan keifyang tidak dimaksud, dan hasilnya berupa logika yang berubah tanpa error kompilasi. Menuliskan kurung kurawal pada setiap tingkat menuntaskan keraguan semacam ini.
Ringkasan#
ifmengeksekusi bloknya apabila kondisi bernilaitrue, sedangkanelse ifdanelsemenyediakan jalur alternatif yang dievaluasi berurutan dari atas ke bawah.ifbersarang menguji syarat umum di tingkat luar dan pengecekan rinci di tingkat dalam, dengan tanda kurung kurawal menjaga pasanganelsetetap jelas.- Bentuk C++17
if (inisialisasi; kondisi)menempatkan variabel sementara pada lingkup yang berakhir bersama percabangannya, sehingga tidak ada kebocoran nama ke kode lain.
Referensi#
- if statement — cppreference.com
— Kaidah formal pernyataan
if, termasuk bentuk C++17 dengan inisialisasi. - Introduction to if statements — Learn C++
— Pembahasan bertahap kondisi,
else, dan kebiasaan penulisanifyang benar. - Warning Options — GNU Project
— Daftar flag peringatan GCC, termasuk
-Wallyang menandai penugasan di dalam kondisi.