Operator conditional ? : adalah satu-satunya operator ternary (operator yang menerima tiga operand) di C. Operator ini adalah jalan pintas untuk if-else dalam bentuk ekspresi: ketika kita perlu memilih satu dari dua nilai berdasarkan sebuah kondisi, operator ? : memberikan cara ringkas tanpa memutus alur ekspresi. Pada Chapter ini kita akan menelaah sintaks operator conditional, perilaku evaluasinya yang hanya mengevaluasi cabang yang dipilih, pola nested ternary untuk klasifikasi bertingkat, dan kapan operator ini lebih tepat dipilih dibanding if-else biasa. Kita juga akan melihat jebakan ketika kedua cabang memiliki tipe berbeda.
Sintaks Dasar #
Operator conditional memiliki bentuk umum:
kondisi ? ekspresi_jika_benar : ekspresi_jika_salahOperator ? : pertama-tama mengevaluasi kondisi. Jika hasilnya non-zero (benar), ekspresi_jika_benar dievaluasi dan menjadi hasil seluruh ekspresi. Jika kondisi bernilai 0 (salah), ekspresi_jika_salah yang dievaluasi. Hanya satu dari dua cabang yang dievaluasi—sifat ini mirip dengan short-circuit pada operator logika.
#include <stdio.h>
int main(void) {
int nilai = 75;
int batas_lulus = 70;
const char *status = (nilai >= batas_lulus) ? "LULUS" : "GAGAL";
printf("Nilai %d -> %s\n", nilai, status);
/* Ternary bersarang */
int suhu = 38;
const char *kategori =
(suhu < 36) ? "hipotermia" :
(suhu <= 37) ? "normal" :
(suhu <= 39) ? "demam ringan" :
"demam tinggi";
printf("Suhu %d C -> %s\n", suhu, kategori);
/* Assignment bersyarat */
int diskon = (nilai >= batas_lulus) ? 10 : 0;
printf("Diskon: %d%%\n", diskon);
/* Ternary dalam argumen printf */
int n = 5;
printf("Ada %d buah%s\n", n, (n == 1) ? "" : "");
return 0;
}Output yang Dihasilkan:
Nilai 75 -> LULUS
Suhu 38 C -> demam ringan
Diskon: 10%
Ada 5 buahMari kita telaah baris-baris kode di atas:
- Baris 8 (
const char *status = (nilai >= batas_lulus) ? "LULUS" : "GAGAL";): kondisi75 >= 70benar, sehingga cabang"LULUS"dipilih dan disimpan ke pointerstatus. - Baris 13-17 (ternary bersarang): operator
? :dirangkai untuk kasus banyak kategori; cabang dievaluasi berurutan dari atas;"demam tinggi"adalah fallback jika tidak ada kondisi sebelumnya yang terpenuhi. - Baris 20 (
int diskon = (nilai >= batas_lulus) ? 10 : 0;): hasil bertipeint; jika kondisi benar,diskonbernilai10, sebaliknya0. - Baris 24 (
printf("Ada %d buah%s\n", n, (n == 1) ? "" : "");): pemakaian ternary untuk sufiks jamak; karenan == 5, sufiks yang dipilih adalah""(string kosong).
Mencari Maksimum, Minimum, dan Nilai Absolut #
Operator conditional cocok untuk ekspresi keputusan tunggal yang menghasilkan nilai. Pola paling sering adalah mencari nilai terbesar atau terkecil di antara beberapa operand, serta menghitung nilai absolut dari sebuah bilangan.
#include <stdio.h>
int main(void) {
int a = 10, b = 20, c = 15;
/* Mencari nilai maksimum dengan ternary */
int maksimum = (a > b) ? a : b;
maksimum = (maksimum > c) ? maksimum : c;
printf("Max(%d, %d, %d) = %d\n", a, b, c, maksimum);
/* Mencari nilai minimum dengan ternary */
int minimum = (a < b) ? a : b;
minimum = (minimum < c) ? minimum : c;
printf("Min(%d, %d, %d) = %d\n", a, b, c, minimum);
/* Ternary dengan expression yang berbeda tipe */
int pilih = 1;
double hasil = pilih ? (1.0 / 3.0) : (1.0 / 7.0);
printf("Hasil = %.6f\n", hasil);
return 0;
}Output yang Dihasilkan:
Max(10, 20, 15) = 20
Min(10, 20, 15) = 10
Hasil = 0.333333Pada baris ke-6, ekspresi (a > b) ? a : b memilih a jika a > b, sebaliknya b; hasilnya 20. Baris ke-7 memperbarui maksimum dengan membandingkannya terhadap c; karena 20 > 15, maksimum tetap 20. Pada baris ke-17, kedua cabang menghasilkan double sehingga tipe akhir adalah double; jika salah satu cabang bertipe int, usual arithmetic conversions akan menyamakan tipe keduanya—topik yang akan kita dalami di Chapter usual arithmetic conversions.
Ternary dalam Fungsi dan Return Value #
Karena operator ? : adalah ekspresi yang menghasilkan nilai, ia dapat dipakai langsung dalam pernyataan return. Pola ini sering menghasilkan kode yang ringkas untuk fungsi klasifikasi sederhana atau fungsi matematika kecil.
#include <stdio.h>
int abs_int(int n) {
/* Ternary sebagai return value */
return (n < 0) ? -n : n;
}
const char *klasifikasi_nilai(int n) {
/* Ternary bersarang untuk grade */
return (n >= 90) ? "A" :
(n >= 80) ? "B" :
(n >= 70) ? "C" :
(n >= 60) ? "D" :
"E";
}
int main(void) {
printf("abs(-15) = %d\n", abs_int(-15));
printf("abs(23) = %d\n", abs_int(23));
int daftar_nilai[] = {95, 82, 75, 63, 50};
for (int i = 0; i < 5; i++) {
printf("Nilai %d -> grade %s\n",
daftar_nilai[i],
klasifikasi_nilai(daftar_nilai[i]));
}
return 0;
}Output yang Dihasilkan:
abs(-15) = 15
abs(23) = 23
Nilai 95 -> grade A
Nilai 82 -> grade B
Nilai 75 -> grade C
Nilai 63 -> grade D
Nilai 50 -> grade EFungsi abs_int memakai ternary untuk membalikkan tanda bilangan negatif. Fungsi klasifikasi_nilai memakai nested ternary yang dievaluasi berurutan: jika n >= 90 maka return "A"; jika tidak, periksa n >= 80; pola ini berlanjut hingga fallback "E". Pola ini setara dengan if-else ladder namun lebih ringkas dan dapat dipakai sebagai ekspresi langsung dalam return.
Jebakan Tipe yang Berbeda #
Operator ? : mensyaratkan kedua cabang memiliki tipe yang kompatibel. Jika tipe keduanya berbeda (misalnya int dan double, atau char * dan void *), compiler akan menerapkan usual arithmetic conversions untuk menyamakan tipe. Hal ini kadang menghasilkan perilaku mengejutkan: cabang yang tidak dievaluasi tetap memengaruhi tipe hasil akhir.
Dengan operator conditional kita memiliki alat ringkas untuk percabangan dalam ekspresi. Pada Chapter berikutnya kita akan meninjau operator sizeof yang memeriksa ukuran tipe dan objek pada saat kompilasi.