Untuk memilih satu cabang dari banyak kemungkinan berbasis nilai konstan, C menyediakan switch. Berbeda dengan else if yang bekerja pada ekspresi kompleks, switch mengevaluasi sebuah ekspresi integer dan melompat langsung ke case label yang cocok. Konstruksi ini cocok untuk pola seperti menu pilihan, kode hari, kode operasi, atau komando karakter. Pada chapter ini kita akan memakai switch pada int dan char, memahami aturan dari ISO/IEC 9899 §6.8.5, dan menunjukkan bahwa switch pada float maupun string tidak dapat dikompilasi beserta pesan kesalahan yang dihasilkan.

Sintaks switch #

Berdasarkan ISO/IEC 9899 §6.8.5, bentuk switch di C adalah:

c
switch (ekspresi_integer) {
    case konstanta_1:
        /* statement */
        break;
    case konstanta_2:
        /* statement */
        break;
    /* ... */
    default:
        /* statement */
        break;
}

Compiler mengevaluasi ekspresi_integer. Jika hasilnya sama dengan salah satu case konstanta, eksekusi melompat ke statement setelah label tersebut. Bila tidak ada case yang cocok, eksekusi melompat ke default (bila ada). Setiap case harus berupa konstanta integer—bukan variabel, bukan rentang, bukan ekspresi runtime.

Visualisasi Konsep #

Diagram berikut memperlihatkan alur dispatch switch yang melompat langsung ke case label yang cocok, dengan default sebagai cadangan bila tidak ada yang cocok:

Pada diagram di atas, switch mengevaluasi ekspresi_integer sekali dan melompat langsung ke case label yang cocok—tidak ada perbandingan berurutan seperti pada rantai else if. Bila nilai ekspresi sama dengan salah satu konstanta case, eksekusi melompat ke blok statement yang sesuai. Bila tidak ada case yang cocok, eksekusi melompat ke blok default (bila ada). Statement break di setiap blok menyebabkan eksekusi keluar dari switch dan melanjutkan ke kode setelah blok. Tanpa break, eksekusi akan terus mengalir (fallthrough) ke case berikutnya.

switch pada int #

Pemakaian paling umum switch adalah memetakan kode numerik. Contoh berikut menerjemahkan angka 1–7 menjadi nama hari.

c
#include <stdio.h>

int main(void) {
    int hari = 3;

    switch (hari) {
        case 1:
            printf("Senin\n");
            break;
        case 2:
            printf("Selasa\n");
            break;
        case 3:
            printf("Rabu\n");
            break;
        case 4:
            printf("Kamis\n");
            break;
        case 5:
            printf("Jumat\n");
            break;
        case 6:
            printf("Sabtu\n");
            break;
        case 7:
            printf("Minggu\n");
            break;
        default:
            printf("Nomor hari tidak valid\n");
            break;
    }
    return 0;
}

Output yang Dihasilkan:

text
Rabu

Mari kita telaah baris-baris kode di atas:

  1. Baris 5 (switch (hari)): compiler mengevaluasi hari (hasil 3) dan mencari case label yang cocok.
  2. Baris 12 (case 3:): label dengan nilai konstan 3 dipilih. Eksekusi melompat ke printf setelahnya.
  3. Baris 13 (printf("Rabu\n");): mencetak nama hari yang sesuai.
  4. Baris 14 (break;): menghentikan eksekusi switch dan keluar dari blok. Tanpa break, eksekusi akan terus mengalir ke case berikutnya—pola fallthrough yang akan kita bahas tuntas pada chapter break-dan-fallthrough.
  5. Baris 24 (default:): tidak dieksekusi karena sudah ada case yang cocok.

switch pada char #

Karena char di C adalah tipe integer (kode numerik ASCII/Unicode), switch juga bekerja pada char. Kita menulis label dengan literal karakter 'A', 'B', dst.

c
#include <stdio.h>

int main(void) {
    char kode = 'B';

    switch (kode) {
        case 'A':
            printf("Kategori A: pelanggan VIP\n");
            break;
        case 'B':
            printf("Kategori B: pelanggan reguler\n");
            break;
        case 'C':
            printf("Kategori C: pelanggan trial\n");
            break;
        default:
            printf("Kode kategori tidak dikenal\n");
            break;
    }
    return 0;
}

Output yang Dihasilkan:

text
Kategori B: pelanggan reguler

Pada contoh di atas, kode = 'B' dienkode sebagai integer 66 (kode ASCII huruf B besar). Compiler membandingkan 66 dengan setiap case label: 65 (A), 66 (B), 67 (C). Cocok di case 'B', eksekusi melompat ke sana, mencetak pesan, lalu break keluar.

switch pada float Tidak Bisa Dikompilasi #

switch hanya menerima tipe integer (int, char, short, long, enum, dan variannya). Tipe float, double, dan tipe non-integer lain tidak diperbolehkan sebagai ekspresi switch. Berikut kode yang mencoba memakai float:

c
#include <stdio.h>

int main(void) {
    float harga = 100.5f;

    switch (harga) {     /* ERROR: float tidak diperbolehkan */
        case 100.5f:
            printf("Harga standar\n");
            break;
        default:
            printf("Harga lain\n");
            break;
    }
    return 0;
}

Output compiler (kesalahan kompilasi):

text
test_switch3_float.c: In function 'main':
test_switch3_float.c:6:13: error: switch quantity not an integer
    6 |     switch (harga) {     /* ERROR: float tidak diperbolehkan */
      |             ^~~~~
test_switch3_float.c:7:9: error: case label does not reduce to an integer constant
    7 |         case 100.5f:
      |         ^~~~

Compiler GCC menolak dengan dua kesalahan: (1) ekspresi switch harus berupa integer, dan (2) case label harus berupa konstanta integer. Untuk logika percabangan berbasis nilai float, gunakan if-else dengan rentang, misalnya if (harga >= 100.0f && harga <= 100.99f).

switch pada String Tidak Bisa Dikompilasi #

C juga tidak memiliki tipe string bawaan. String di C adalah array char yang berakhir dengan '\0'. Karena string bukan integer dan bukan konstanta integer, switch pada string tidak dapat dikompilasi.

c
#include <stdio.h>
#include <string.h>

int main(void) {
    char perintah[] = "start";

    switch (perintah) {     /* ERROR: string tidak diperbolehkan */
        case "start":
            printf("Memulai server\n");
            break;
        case "stop":
            printf("Menghentikan server\n");
            break;
        default:
            printf("Perintah tidak dikenal\n");
            break;
    }
    return 0;
}

Output compiler (kesalahan kompilasi):

text
test_switch3_str.c: In function 'main':
test_switch3_str.c:7:13: error: switch quantity not an integer
    7 |     switch (perintah) {     /* ERROR: string tidak diperbolehkan */
      |             ^~~~~~~~
test_switch3_str.c:8:9: error: pointers are not permitted as case values
    8 |         case "start":
      |         ^~~~
test_switch3_str.c:11:9: error: pointers are not permitted as case values
   11 |         case "stop":
      |         ^~~~

Compiler memberi tahu bahwa perintah (yang decay menjadi char*) bukan integer, dan case label berupa string literal ("start", "stop") dianggap sebagai pointer—pointer juga tidak diperbolehkan sebagai case label. Untuk memilih cabang berdasarkan string, gunakan if-else dengan strcmp:

c
if (strcmp(perintah, "start") == 0) {
    printf("Memulai server\n");
} else if (strcmp(perintah, "stop") == 0) {
    printf("Menghentikan server\n");
} else {
    printf("Perintah tidak dikenal\n");
}

Kapan Memilih switch Daripada else if #

Beberapa kondisi yang membuat switch lebih cocok daripada else if:

  1. Pemetaan nilai diskrit: setiap cabang membandingkan variabel dengan konstanta berbeda.
  2. Banyak cabang: 5 atau lebih nilai konstan. Rantai else if yang panjang seringkali lebih sulit dibaca.
  3. Kebutuhan fallthrough sengaja: misalnya menerapkan logika kumulatif pada angka 1, 2, 3, 4.
  4. Optimasi compiler: compiler dapat menerjemahkan switch dengan banyak case menjadi jump table—lookup langsung lebih cepat daripada serangkaian perbandingan else if.

Pada chapter berikutnya kita akan menelaah lebih dalam peran case dan default—termasuk urutan keduanya, penggunaan beberapa label untuk satu blok, dan apa yang terjadi bila default tidak ada.