Operator koma , adalah salah satu operator paling unik di C. Walaupun simbolnya sama dengan koma yang memisahkan argumen fungsi atau elemen array, operator koma sebagai operator memiliki makna khusus: mengevaluasi dua ekspresi secara berurutan dari kiri ke kanan dan mengembalikan nilai ekspresi sebelah kanan. Pada Chapter ini kita akan menelaah perilaku operator koma, perbedaan antara operator koma dengan pemisah koma sintaksis (seperti pada daftar argumen fungsi), serta idiom klasiknya di loop for yang membutuhkan lebih dari satu inisialisasi atau update. Kita juga akan melihat kasus ketika operator koma berguna, dan kapan justru harus dihindari karena menurunkan keterbacaan.
Sintaks dan Cara Kerja #
Operator koma memiliki bentuk ekspresi1 , ekspresi2. Aturan evaluasinya: ekspresi1 dievaluasi terlebih dahulu (dan hasilnya dibuang), kemudian ekspresi2 dievaluasi dan menjadi hasil seluruh ekspresi. Titik di antara dua evaluasi adalah sequence point, artinya efek samping dari ekspresi1 (seperti assignment atau pemanggilan fungsi) sudah selesai sepenuhnya sebelum ekspresi2 mulai dievaluasi.
#include <stdio.h>
int main(void) {
int a = (printf("eval 1\n"), 30); /* side-effect + nilai akhir */
printf("a = %d\n\n", a);
/* Ekspresi dengan efek samping */
int x = 0;
int y = (x = 5, x + 3); /* x diisi 5, lalu y = 8 */
printf("x = %d, y = %d\n", x, y);
return 0;
}Output yang Dihasilkan:
eval 1
a = 30
x = 5, y = 8Mari kita telaah baris-baris kode di atas:
- Baris 5 (
int a = (printf("eval 1\n"), 30);): ekspresiprintf("eval 1\n")dievaluasi terlebih dahulu dan mencetak"eval 1"; nilai kembalianprintf(jumlah karakter yang dicetak) dibuang; kemudian ekspresi30dievaluasi menjadi nilai30, yang akhirnya disalin ke variabela. - Baris 9 (
int y = (x = 5, x + 3);): ekspresix = 5dievaluasi terlebih dahulu sehinggaxbernilai5; kemudianx + 3dievaluasi menjadi8dan disalin key. - Tanda kurung di sekitar kedua ekspresi tersebut wajib karena operator koma memiliki precedence paling rendah di antara semua operator C—tanpa tanda kurung, ekspresi
int y = x = 5, x + 3;akan diparse secara berbeda dan tidak menghasilkan makna yang dimaksud.
Idiom di Loop for #
Pemakaian operator koma paling lazim dan paling berguna adalah pada loop for yang membutuhkan lebih dari satu variabel inisialisasi atau lebih dari satu ekspresi update. Tanpa operator koma, kita harus memilih salah satu indeks dan mengelola indeks lainnya secara terpisah di dalam loop body.
#include <stdio.h>
int main(void) {
/* Comma di for loop: inisialisasi & update ganda */
int total = 0;
for (int i = 0, j = 10; i < j; i++, j--) {
printf("i=%d, j=%d\n", i, j);
total += i + j;
}
printf("Total: %d\n\n", total);
/* Comma untuk multiple update */
int a = 1, b = 2, c = 3;
printf("Sebelum: a=%d, b=%d, c=%d\n", a, b, c);
a += 10, b += 10, c += 10; /* tiga ekspresi, namun statement ini hanya expression statement */
printf("Setelah: a=%d, b=%d, c=%d\n", a, b, c);
return 0;
}Output yang Dihasilkan:
i=0, j=10
i=1, j=9
i=2, j=8
i=3, j=7
i=4, j=6
Total: 50
Sebelum: a=1, b=2, c=3
Setelah: a=11, b=12, c=13Pada baris ke-6, ekspresi int i = 0, j = 10 bukan operator koma melainkan deklarasi dua variabel dalam satu pernyataan. Pada bagian update i++, j--, kedua ekspresi dipisahkan oleh operator koma: i++ dievaluasi terlebih dahulu (menaikkan i), kemudian j-- dievaluasi (menurunkan j). Hasil akhir operator koma (j--) tidak dipakai karena bagian update for hanya butuh efek samping, bukan nilai. Pada baris ke-15, tiga ekspresi assignment dipisahkan oleh dua operator koma; seluruhnya dievaluasi kiri-ke-kanan dan ketiga variabel diperbarui.
Kasus Lanjutan: Argumen dan Kondisi #
Operator koma kadang dipakai untuk menjalankan efek samping sebelum kondisi pada while atau sebagai argumen fungsi. Pola ini umum di code golf dan kode sistem kuno, namun sering menurunkan keterbacaan. Penggunaan yang bijak membatasi operator koma pada konteks yang jelas efeknya.
#include <stdio.h>
int akumulator(int a, int b, int c) {
return a + b + c;
}
int main(void) {
int step = 0;
/* Comma operator sebagai argumen tunggal (bukan dua argumen!) */
int hasil = akumulator((step = 1, step + 1), 5, 10);
printf("step = %d\n", step);
printf("hasil = %d\n", hasil);
/* Comma di while untuk efek samping sebelum tes kondisi */
int i = 0;
while (printf("iterasi %d\n", i), i < 3) {
i++;
}
printf("Akhir loop i=%d\n", i);
return 0;
}Output yang Dihasilkan:
step = 1
hasil = 17
iterasi 0
iterasi 1
iterasi 2
iterasi 3
Akhir loop i=3Pada baris ke-11, ekspresi (step = 1, step + 1) diapit tanda kurung sehingga operator koma di dalamnya menghasilkan satu nilai (2) yang dikirim sebagai argumen pertama akumulator; efek samping step = 1 ikut terjadi. Tanpa tanda kurung, akumulator(step = 1, step + 1, 5, 10) akan diparse sebagai pemanggilan fungsi dengan empat argumen—ini adalah kesalahan umum. Pada baris ke-16, ekspresi printf("iterasi %d\n", i) dievaluasi terlebih dahulu (mencetak teks), kemudian kondisi i < 3 dievaluasi untuk menentukan kelanjutan loop; akibatnya printf dieksekusi sekali lagi setelah i == 3 sebelum kondisi menjadi salah—perhatikan baris “iterasi 3” pada output.
Dengan operator koma kita memiliki cara untuk merangkai beberapa ekspresi dalam satu evaluasi. Pada Chapter berikutnya kita akan menelaah tabel precedence dan associativity yang menentukan urutan evaluasi operator dalam ekspresi kompleks.