Percabangan if / else

Pengambilan keputusan dengan if, else if, dan else, kondisi bersarang, serta bug tanda sama dengan tunggal.

Daftar isi

Program C menjalankan pernyataan satu per satu dari atas ke bawah sampai ada keputusan yang perlu diambil. Percabangan if / else memilih salah satu dari beberapa jalur eksekusi berdasarkan hasil pengujian sebuah kondisi. Topik ini membahas struktur dasar if dan else, rantai else if, kondisi bersarang, serta bug tanda sama dengan tunggal yang sering menimpa pemula.

Struktur dasar if dan else#

Pernyataan if menguji sebuah kondisi, lalu menjalankan blok pernyataan di dalam kurung kurawal apabila kondisinya benar. Kondisi berupa ekspresi apa pun, dan hasilnya dibandingkan dengan nol. Nilai nol dianggap salah, sedangkan nilai selain nol dianggap benar. Pernyataan else bersifat opsional dan menjalankan bloknya apabila kondisi if tidak terpenuhi, sehingga setiap keputusan selalu punya jalur keluar yang jelas.

Bentuk umum kedua pernyataan tersebut tampak seperti berikut.

c Bentuk umum if dan else
// tidak-dijalankan
if (kondisi) {
    /* dijalankan apabila kondisi benar */
} else {
    /* dijalankan apabila kondisi salah */
}

Contoh program berikut memeriksa tanda sebuah bilangan. Nilai angka ditetapkan langsung di dalam kode agar keluarannya dapat direproduksi setiap kali dijalankan. Kompilasi berkas tersebut, jalankan, lalu bandingkan hasilnya dengan blok keluaran di bawah.

c tanda-angka.c
#include <stdio.h>

int main(void) {
    int angka = -7;

    if (angka >= 0) {
        printf("Angka positif atau nol\n");
    } else {
        printf("Angka negatif\n");
    }

    return 0;
}
text Keluaran
Angka negatif

Pembanding >= menghasilkan nilai benar apabila operand kirinya lebih besar atau sama dengan operand kanannya. Karena angka bernilai -7, kondisi angka >= 0 bernilai salah sehingga blok else yang dijalankan. Apabila nilai angka diubah menjadi bilangan nonnegatif, blok if yang akan berjalan. Kurung kurawal sebenarnya boleh dihilangkan bila bloknya hanya berisi satu pernyataan, tetapi menuliskannya secara konsisten mencegah kekeliruan saat blok ditambah pernyataan baru.

Rantai else if#

Keputusan dengan lebih dari dua kemungkinan ditangani menggunakan rantai else if. Setiap kondisi diuji satu per satu dari atas ke bawah, dan blok milik kondisi pertama yang bernilai benar menjadi satu-satunya yang dijalankan. Sisa pengujian langsung dilewati, sehingga urutan kondisi memengaruhi hasil. Blok else pada ujung rantai menampung semua nilai yang tidak lolos pengujian mana pun. Apabila tidak ada kondisi yang lolos dan tidak ada blok else, tidak ada satu pernyataan pun yang dijalankan.

Diagram berikut menggambarkan alur pengujian tersebut untuk pengklasifikasian nilai ujian.

Masuk ke percabangannilai >= 85benarKategori: Asalahnilai >= 70benarKategori: Bsalahnilai >= 60benarKategori: Csalahblok elseKategori: DLanjut ke pernyataan sesudah if
Alur pengujian rantai else if dari atas ke bawah

Program berikut mengelompokkan nilai ujian ke dalam empat kategori. Nilai 78 lolos pada pengujian kedua karena 78 lebih kecil dari 85 tetapi masih lebih besar atau sama dengan 70.

c klasifikasi-nilai.c
#include <stdio.h>

int main(void) {
    int nilai = 78;

    if (nilai >= 85) {
        printf("Kategori: A\n");
    } else if (nilai >= 70) {
        printf("Kategori: B\n");
    } else if (nilai >= 60) {
        printf("Kategori: C\n");
    } else {
        printf("Kategori: D\n");
    }

    return 0;
}
text Keluaran
Kategori: B

Perhatikan bahwa kondisi kedua cukup ditulis nilai >= 70 tanpa memeriksa batas atasnya. Pengujian nilai >= 85 sudah gagal lebih dahulu, sehingga nilai 85 ke atas tidak mungkin sampai ke pengujian kedua. Dengan pola ini, kondisi ganda seperti nilai >= 70 && nilai < 85 tidak diperlukan, padahal bentuknya lebih panjang dan lebih mudah keliru. Urutan pengujian tetap harus dijaga karena menukar posisi kondisi akan mengubah hasil klasifikasi.

Kondisi bersarang#

Kondisi bersarang terbentuk apabila sebuah if berada di dalam blok if lain. Struktur ini dipakai apabila pengujian kedua hanya relevan setelah pengujian pertama lolos. Program berikut memeriksa dua syarat kelulusan secara bertingkat, yaitu nilai ujian dan persentase kehadiran. Nilai kehadiran dinyatakan dalam persen, sehingga batas 75 berarti tiga perempat dari total pertemuan.

c lulus-remedial.c
#include <stdio.h>

int main(void) {
    int nilai = 72;
    int kehadiran = 80;

    if (nilai >= 60) {
        if (kehadiran >= 75) {
            printf("Status: lulus\n");
        } else {
            printf("Status: remedial karena kehadiran kurang\n");
        }
    } else {
        printf("Status: remedial karena nilai kurang\n");
    }

    return 0;
}
text Keluaran
Status: lulus

Blok terluar memeriksa nilai >= 60 lebih dahulu. Pemeriksaan kehadiran hanya dilakukan apabila syarat nilai sudah terpenuhi, sehingga pesan yang muncul selalu menunjuk satu penyebab kegagalan yang tepat. Penulisan menjorok pada setiap tingkat membuat susunan kondisi mudah dibaca, dan kurung kurawal setiap tingkat tetap ditulis agar batas bloknya tidak rancu.

Apabila tingkat bersarang bertambah banyak, syarat yang tidak perlu membedakan pesan dapat digabungkan dengan operator logika &&, misalnya nilai >= 60 && kehadiran >= 75, agar struktur kembali rata. Kedua pendekatan menghasilkan keputusan yang sama, dan pilihannya ditentukan oleh pesan yang perlu ditampilkan. Pada program di atas, pesan kegagalan yang berbeda untuk setiap penyebab menjadi alasan kondisi bersarang dipertahankan.

Bug tanda sama dengan tunggal#

Kekeliruan yang sering terjadi pada penulisan kondisi adalah menukar == dengan =. Tanda = berarti penugasan, sedangkan == berarti pembanding kesamaan. Ekspresi penugasan di C memiliki nilai, yaitu nilai yang diberikan kepada variabelnya, sehingga stok = 0 bernilai 0 dan dianggap salah. Akibatnya, kondisi tidak pernah berperilaku sesuai maksud awal, dan variabelnya ikut berubah tanpa terlihat.

Program berikut dimaksudkan untuk melaporkan stok yang habis, tetapi kondisinya sengaja ditulis keliru.

c bug-tanda-sama-dengan.c
#include <stdio.h>

int main(void) {
    int stok = 3;

    if (stok = 0) {
        printf("Stok habis\n");
    } else {
        printf("Stok tersisa %d\n", stok);
    }

    return 0;
}
text Keluaran
Stok tersisa 0

Keluaran menyatakan stok tersisa 0 padahal nilai awalnya 3. Penyebabnya ada pada kondisi stok = 0 yang menugaskan nilai 0 kepada stok, lalu memakai nilai hasil penugasan itu sebagai kondisi. Karena hasilnya 0, kondisi dianggap salah dan blok else yang berjalan. Maksud awalnya hanya membandingkan, bukan mengubah nilai stok.

Kompilator dapat membantu mendeteksi kekeliruan ini. Perintah gcc -Wall -Wextra menandai baris if (stok = 0) dengan pesan peringatan suggest parentheses around assignment used as truth value, yang berarti kompilator menduga adanya penugasan yang tidak disengaja di dalam kondisi.

Ringkasan#

  • Pernyataan if menjalankan bloknya apabila kondisi bernilai selain nol, sedangkan else menampung kasus selainnya.
  • Rantai else if menguji kondisi dari atas ke bawah dan hanya menjalankan blok pertama yang lolos.
  • Kondisi bersarang menunda pengujian kedua sampai pengujian pertama lolos sehingga pesan kegagalannya lebih tepat.
  • Tanda = di dalam kondisi adalah penugasan, bukan pembanding, sehingga perbandingan wajib ditulis dengan ==.

Referensi#