Selain if-else, C menyediakan satu lagi bentuk percabangan: operator conditional ? :. Berbeda dengan if yang merupakan statement, operator ? : adalah ekspresi—artinya, ia menghasilkan nilai dan bisa ditempatkan di mana pun ekspresi diperbolehkan: di sisi kanan penugasan, di argumen printf, bahkan di indeks array. Karena ringkas, operator ini sering dipakai untuk substitusi if-else yang sangat sederhana. Pada chapter ini kita akan memahami sintaks ? :, memakainya dengan berbagai tipe data, dan membandingkannya langsung dengan if-else untuk melihat kapan satu lebih cocok daripada yang lain.

Sintaks Operator Conditional #

Berdasarkan ISO/IEC 9899 §6.5.15, bentuk operator conditional adalah:

c
ekspresi_kondisi ? ekspresi_jika_true : ekspresi_jika_false

Compiler mengevaluasi ekspresi_kondisi. Jika hasilnya tidak sama dengan 0 (true), ekspresi_jika_true yang dievaluasi dan menjadi hasil ekspresi. Jika hasil 0 (false), ekspresi_jika_false yang dievaluasi. Yang penting, hanya satu dari dua ekspresi yang dievaluasi—mirip short-circuit pada operator logika.

c
#include <stdio.h>

int main(void) {
    int a = 10, b = 20;
    int maks = (a > b) ? a : b;   /* operator conditional */
    printf("maks = %d\n", maks);

    /* Pemakaian untuk menentukan string yang dicetak */
    int umur = 16;
    printf("Status: %s\n", (umur >= 17) ? "dewasa" : "anak-anak");
    return 0;
}

Output yang Dihasilkan:

text
maks = 20
Status: anak-anak

Mari kita telaah baris-baris kode di atas:

  1. Baris 5 (int maks = (a > b) ? a : b;): compiler mengevaluasi a > b → 10 > 20 → 0 (false), sehingga b yang dipilih sebagai hasil. Variabel maks diisi 20.
  2. Baris 9 (printf("Status: %s\n", (umur >= 17) ? "dewasa" : "anak-anak");): ekspresi umur >= 17 → 16 >= 17 → 0, sehingga string "anak-anak" menjadi argumen %s.

Operator Conditional dengan Berbagai Tipe #

Operator ? : bekerja pada tipe apa pun yang valid sebagai ekspresi. Berikut pemakaian dengan int, double, dan char.

c
#include <stdio.h>

int main(void) {
    /* Operator conditional dengan berbagai tipe */
    int    angka  = 7;
    double harga  = 15000.0;
    char   kode   = 'V';
    int    stok   = 0;

    /* 1. int -> int */
    int label_angka = (angka % 2 == 0) ? 1 : -1;
    printf("label_angka = %d\n", label_angka);

    /* 2. double -> double (ekspresi conditional menjaga tipe) */
    double harga_final = (kode == 'V') ? harga * 0.9 : harga;
    printf("harga_final = %.2f\n", harga_final);

    /* 3. char -> char */
    char huruf = 'a';
    char kapital = (huruf >= 'a' && huruf <= 'z') ? (huruf - 32) : huruf;
    printf("kapital = %c\n", kapital);

    /* 4. Tipe berbeda -> promoted (usual arithmetic conversions) */
    int    i = 5;
    double d = 3.14;
    /* Hasil conditional dengan tipe berbeda akan dipromosikan ke double */
    printf("hasil = %.2f\n", (stok > 0) ? (double)i : d);
    return 0;
}

Output yang Dihasilkan:

text
label_angka = -1
harga_final = 13500.00
kapital = A
hasil = 3.14

Mari kita telaah empat demonstrasi di atas:

  1. label_angka: 7 % 2 = 1 (ganjil), kondisi 1 == 0 adalah false, sehingga -1 dipilih.
  2. harga_final: kode == 'V' adalah true, sehingga harga * 0.9 = 15000 * 0.9 = 13500.0 dijadikan hasil bertipe double.
  3. kapital: huruf = 'a' (kode 97). huruf - 32 menghasilkan 65 yang merupakan kode ASCII huruf 'A'.
  4. hasil: stok > 0 adalah false, sehingga d yang dipilih. Karena salah satu cabang bertipe double, seluruh hasil ekspresi dipromosikan ke double. Inilah usual arithmetic conversions yang juga berlaku pada operator aritmetika.

Perbandingan dengan if-else #

Operator ? : dan if-else bisa saling menggantikan untuk kasus dwi-cabang sederhana. Pilih mana yang paling jelas dibaca—sering kali jawabannya tergantung seberapa kompleks cabangnya.

c
#include <stdio.h>

int main(void) {
    /* Perbandingan if-else vs operator conditional */
    int nilai = 75;

    /* Versi if-else */
    char *predikat;
    if (nilai >= 70) {
        predikat = "Lulus";
    } else {
        predikat = "Belum lulus";
    }
    printf("if-else  : %s\n", predikat);

    /* Versi operator conditional: 1 baris */
    char *predikat2 = (nilai >= 70) ? "Lulus" : "Belum lulus";
    printf("ternary  : %s\n", predikat2);

    /* Tapi untuk logika kompleks, if-else lebih jelas */
    if (nilai >= 90) {
        printf("Kategori if-else: A\n");
    } else if (nilai >= 70) {
        printf("Kategori if-else: B\n");
    } else {
        printf("Kategori if-else: C\n");
    }

    /* Nested ternary: jangan ditiru untuk kode produksi */
    char *kategori = (nilai >= 90) ? "A" : ((nilai >= 70) ? "B" : "C");
    printf("Kategori ternary: %s\n", kategori);
    return 0;
}

Output yang Dihasilkan:

text
if-else  : Lulus
ternary  : Lulus
Kategori if-else: B
Kategori ternary: B

Pada contoh di atas, dua versi pertama (versi if-else dan versi ? :) menghasilkan output identik. Untuk dwi-cabang sederhana yang hanya menetapkan satu nilai, operator ? : sering lebih ringkas. Tetapi perhatikan baris terakhir: (nilai >= 90) ? "A" : ((nilai >= 70) ? "B" : "C")—nested ternary seperti ini sulit dibaca dan rawan kesalahan tanda kurung.

Kapan Memilih ? : dan Kapan Memilih if-else #

Beberapa pedoman praktis:

  1. Pakai ? : bila: cabang hanya menetapkan satu nilai ke variabel atau argumen, dan ekspresi kedua cabang pendek.
  2. Pakai if-else bila: salah satu cabang mengeksekusi beberapa statement, memanggil fungsi dengan side effect, atau cabang terlalu kompleks untuk dibaca dalam satu baris.
  3. Hindari nested ternary lebih dari dua tingkat. Walaupun valid secara sintaks, keterbacaan menurun drastis.
  4. Operator ? : menghasilkan nilai—ini menguntungkan bila kita perlu menempatkan percabangan di posisi ekspresi (misalnya argumen printf, indeks array, atau inisialisasi variabel const). if-else tidak bisa dipakai pada posisi ekspresi.

Perilaku Penting: Hanya Satu Cabang Dievaluasi #

Operator ? : hanya mengevaluasi satu dari dua cabang—mirip short-circuit pada && dan ||. Hal ini aman dipakai untuk menulis ekspresi yang melindungi dari operasi invalid, misalnya (p != NULL) ? p->nilai : 0. Cabang kanan p->nilai tidak dievaluasi bila p == NULL, sehingga tidak terjadi null pointer dereference.

Dengan pemahaman operator ? : ini, kita siap melangkah ke chapter terakhir pada Section percabangan: strategi menyusun kondisi agar kode tetap jelas dan mudah dirawat.