Percabangan switch memilih satu jalur eksekusi dari banyak kemungkinan nilai yang sudah diketahui. Struktur ini menjadi alternatif rantai else if apabila semua kasus berupa nilai tetap yang dapat didaftarkan satu per satu. Topik ini membahas struktur switch, case, dan default, perilaku fall-through yang muncul ketika break tidak ditulis, serta pertimbangan memilih switch daripada rantai if.
Struktur switch, case, dan default#
Pernyataan switch menguji nilai sebuah ekspresi bilangan bulat, lalu melompat ke label case yang nilainya sama. Label case wajib berupa konstanta, sehingga case 2 sah, sedangkan case nilai_input tidak. Ekspresi yang diuji boleh bertipe int, char, atau tipe bilangan bulat lain, tetapi tidak boleh string ataupun pecahan. Label default menampung semua nilai yang tidak cocok dengan label mana pun dan sifatnya opsional.
Bentuk umumnya dengan break pada setiap kasus tampak seperti berikut.
// tidak-dijalankan
switch (ekspresi) {
case nilai1:
/* pernyataan untuk nilai1 */
break;
case nilai2:
/* pernyataan untuk nilai2 */
break;
default:
/* pernyataan untuk nilai lain */
break;
}Program berikut menyimulasikan pemilihan layanan pada loket antrean tiket. Nilai pilihan ditetapkan sebelum pengujian, sehingga keluarannya tetap sama setiap kali program dijalankan.
#include <stdio.h>
int main(void) {
int pilihan = 2;
switch (pilihan) {
case 1:
printf("Layanan: tiket ekonomi\n");
break;
case 2:
printf("Layanan: tiket eksekutif\n");
break;
case 3:
printf("Layanan: pembatalan tiket\n");
break;
default:
printf("Pilihan tidak tersedia\n");
break;
}
return 0;
}Layanan: tiket eksekutifKata break di akhir setiap blok menghentikan eksekusi di dalam switch dan melanjutkan program pada pernyataan sesudahnya. Tanpa break, eksekusi jatuh ke pernyataan pada case di bawahnya, perilaku yang disebut fall-through. Perilaku ini bersifat bawaan bahasa C. Bagian berikutnya membahas fall-through beserta akibatnya. Penulisan label case yang sejajar dengan switch mengikuti kebiasaan umum agar daftar kasus mudah dipindai.
Perilaku fall-through#
Perilaku fall-through muncul apabila sebuah blok case tidak diakhiri break, sehingga eksekusi berlanjut ke pernyataan pada case di bawahnya tanpa memeriksa labelnya lagi. Label case hanyalah penanda titik lompatan, bukan pembatas blok. Diagram berikut memperlihatkan jalur eksekusi yang masuk pada label yang cocok, jatuh ke bawah ketika break tidak ada, dan keluar ketika break dijalankan.
Program berikut memperlihatkan akibatnya. Blok case 1 sengaja tidak diberi break, sehingga pernyataan milik case 2 ikut terjalankan.
#include <stdio.h>
int main(void) {
int pilihan = 1;
switch (pilihan) {
case 1:
printf("Membeli tiket\n");
/* break sengaja tidak ditulis */
case 2:
printf("Membatalkan tiket\n");
break;
default:
printf("Pilihan tidak tersedia\n");
break;
}
return 0;
}Membeli tiket
Membatalkan tiketKeluaran memperlihatkan dua baris padahal pilihan bernilai 1. Eksekusi masuk melalui case 1, mencetak baris pertama, lalu jatuh ke pernyataan pada case 2 tanpa memedulikan labelnya. Kekeliruan semacam ini mudah terlewat saat kode dibaca cepat karena strukturnya tampak lengkap.
Fall-through juga dapat dimanfaatkan secara sengaja. Beberapa label case boleh ditumpuk tanpa pernyataan di antaranya sehingga beberapa nilai berbagi satu blok pernyataan. Program berikut mengelompokkan nomor bulan ke dalam kuartal dengan pola tersebut.
#include <stdio.h>
int main(void) {
int bulan = 8;
switch (bulan) {
case 1:
case 2:
case 3:
printf("Kuartal pertama\n");
break;
case 4:
case 5:
case 6:
printf("Kuartal kedua\n");
break;
case 7:
case 8:
case 9:
printf("Kuartal ketiga\n");
break;
case 10:
case 11:
case 12:
printf("Kuartal keempat\n");
break;
default:
printf("Nomor bulan tidak valid\n");
break;
}
return 0;
}Kuartal ketigaNilai 8 melompat langsung ke label case 8, menemukan tidak ada pernyataan di sana, lalu jatuh ke pernyataan printf yang berbagi tiga label tersebut. Pada pola ini, jatuhnya memang disengaja dan mudah dikenali karena labelnya bertumpuk tanpa pernyataan di antaranya. Kompilator tidak menandai label kosong seperti ini sebagai fall-through yang bermasalah.
Peran label default#
Label default dijalankan apabila tidak ada satu pun label case yang cocok dengan ekspresi yang diuji. Perannya menyerupai else pada percabangan if, yaitu menampung semua nilai di luar daftar. Nilai pilihan 5 atau 0 pada program layanan loket jatuh ke default dan menampilkan pesan bahwa pilihan tidak tersedia. Tanpa default, nilai yang tidak cocok membuat seluruh switch dilewati tanpa efek apa pun, keadaan yang sering luput dari pengujian.
Posisi default yang lazim adalah di ujung bawah, setelah semua case, tetapi bahasa C memperbolehkan default ditulis di posisi mana pun. Apabila default diletakkan di tengah, sediakan break pada akhirnya agar eksekusi tidak jatuh ke case berikutnya. Satu switch hanya boleh memiliki satu label default. Apabila satu pengujian memerlukan penanganan untuk dua kelompok nilai yang berbeda, pecah masalahnya menjadi dua pernyataan switch yang berurutan atau gabungkan nilainya sebelum diuji. Kombinasi daftar case yang lengkap dan default yang menampung sisanya membuat kasus yang terlewat cepat ketahuan saat program diuji.
Memilih switch atau rantai if#
Keputusan memilih switch atau rantai else if sebaiknya didasarkan pada bentuk nilainya, bukan pada kebiasaan. Keduanya menghasilkan keputusan yang sama, sehingga pilihan menyangkut keterbacaan dan bentuk syaratnya. Tabel berikut merangkum perbedaan keduanya.
| Aspek | switch | Rantai else if |
|---|---|---|
| Nilai yang diuji | Bilangan bulat atau karakter, dibandingkan kesamaan dengan konstanta | Ekspresi apa pun yang bernilai benar atau salah |
| Bentuk syarat | Daftar nilai tetap yang diskrit | Rentang nilai atau gabungan beberapa kondisi |
| Keterbacaan | Daftar kasus tersusun rapi untuk pilihan yang banyak | Membengkak apabila kasusnya banyak dan seragam |
Perilaku tanpa break | Jatuh ke case berikutnya | Tidak ada padanannya karena setiap blok terpisah |
switch unggul apabila program harus membedakan banyak nilai tetap, misalnya nomor menu atau kode layanan, karena daftar kasusnya terbaca seperti tabel. Rantai else if tetap diperlukan apabila syaratnya berupa rentang, misalnya nilai >= 70, atau gabungan beberapa variabel. Kompilator juga dapat menerjemahkan switch yang kasusnya rapat menjadi tabel lompatan (jump table), sehingga waktu pencarian kasusnya tidak bertambah seiring jumlah label. Meskipun demikian, pilih struktur yang paling jelas menyatakan maksud program karena perbedaan kinerja pada program kecil jarang berarti.
Ringkasan#
switchmelompat ke labelcaseyang nilainya sama dengan ekspresi bilangan bulat yang diuji.- Tanpa
break, eksekusi jatuh ke case berikutnya, perilaku yang disebut fall-through. - Label bertumpuk tanpa pernyataan adalah pola fall-through yang disengaja untuk mengelompokkan nilai.
defaultmenampung nilai yang tidak cocok dengan label mana pun dan sebaiknya selalu disediakan.
Referensi#
- switch statement — Cppreference — Kaidah label case, default, dan lompatan pada pernyataan switch dalam standar C.
- if statement — Cppreference — Kaidah rantai else if yang dibandingkan dengan switch pada topik ini.