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:
ekspresi_kondisi ? ekspresi_jika_true : ekspresi_jika_falseCompiler 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.
#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:
maks = 20
Status: anak-anakMari kita telaah baris-baris kode di atas:
- Baris 5 (
int maks = (a > b) ? a : b;): compiler mengevaluasia > b→10 > 20→0(false), sehinggabyang dipilih sebagai hasil. Variabelmaksdiisi20. - Baris 9 (
printf("Status: %s\n", (umur >= 17) ? "dewasa" : "anak-anak");): ekspresiumur >= 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.
#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:
label_angka = -1
harga_final = 13500.00
kapital = A
hasil = 3.14Mari kita telaah empat demonstrasi di atas:
label_angka:7 % 2=1(ganjil), kondisi1 == 0adalah false, sehingga-1dipilih.harga_final:kode == 'V'adalah true, sehinggaharga * 0.9=15000 * 0.9=13500.0dijadikan hasil bertipedouble.kapital:huruf = 'a'(kode 97).huruf - 32menghasilkan65yang merupakan kode ASCII huruf'A'.hasil:stok > 0adalah false, sehinggadyang dipilih. Karena salah satu cabang bertipedouble, seluruh hasil ekspresi dipromosikan kedouble. 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.
#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:
if-else : Lulus
ternary : Lulus
Kategori if-else: B
Kategori ternary: BPada 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:
- Pakai
? :bila: cabang hanya menetapkan satu nilai ke variabel atau argumen, dan ekspresi kedua cabang pendek. - Pakai
if-elsebila: salah satu cabang mengeksekusi beberapa statement, memanggil fungsi dengan side effect, atau cabang terlalu kompleks untuk dibaca dalam satu baris. - Hindari nested ternary lebih dari dua tingkat. Walaupun valid secara sintaks, keterbacaan menurun drastis.
- Operator
? :menghasilkan nilai—ini menguntungkan bila kita perlu menempatkan percabangan di posisi ekspresi (misalnya argumenprintf, indeks array, atau inisialisasi variabelconst).if-elsetidak 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.