Operator di C memiliki aturan precedence (kedudukan) dan associativity (arah evaluasi) yang menentukan urutan operasi pada ekspresi kompleks. Saat kita menulis a + b * c, compiler memahami ini sebagai a + (b * c) karena * memiliki precedence lebih tinggi daripada +. Bab ini menyediakan tabel referensi lengkap untuk semua operator C beserta contoh penggunaan dan jebakan yang sering kita temui.

Daftar Operator Berdasarkan Precedence #

Tabel berikut diurutkan dari precedence tertinggi (atas) ke terendah (bawah). Operator pada baris yang sama memiliki precedence sama, dan associativity menentukan urutan evaluasi jika beberapa operator precedence sama muncul berurutan.

PrecedenceOperatorNamaAssociativityContohHasil (a=10, b=3)
1()Pemanggilan fungsi / groupingL ke R(a + b)13
1[]Index arrayL ke Rarr[2]elemen ke-3
1.Akses member structL ke Robj.xfield x
1->Akses member via pointerL ke Rptr->xfield x
1(post)++Post-incrementL ke Ra++10 (a jadi 11)
1(post)--Post-decrementL ke Ra--10 (a jadi 9)
2++(pre)Pre-incrementR ke L++a11
2--(pre)Pre-decrementR ke L--a9
2+ (unary)Unary plusR ke L+a10
2- (unary)Unary minusR ke L-a-10
2!Logical NOTR ke L!a0
2~Bitwise NOTR ke L~a-11
2(type)CastR ke L(double)a10.0
2* (deref)Dereference pointerR ke L*ptrnilai di ptr
2& (addr)Address-ofR ke L&aalamat a
2sizeofUkuran tipe/objekR ke Lsizeof(int)4
2_AlignofAlignment requirementR ke L_Alignof(int)4
3* / / / %Perkalian, pembagian, moduloL ke Ra * b, a % b30, 1
4+ / - (biner)Penjumlahan, penguranganL ke Ra + b, a - b13, 7
5<< / >>Bitwise shiftL ke Ra << 2, a >> 140, 5
6< / <= / > / >=RelationalL ke Ra > b1
7== / !=PersamaanL ke Ra == b0
8& (bitwise)Bitwise ANDL ke Ra & b2
9^Bitwise XORL ke Ra ^ b9
10``Bitwise ORL ke R`a
11&&Logical ANDL ke R(a > 0) && (b > 0)1
12``Logical ORL ke R
13?:Ternary kondisionalR ke L(a > b) ? a : b10
14=AssignmentR ke La = 55
14+= -= *= /= %=Compound aritmetikaR ke La += 515
14<<= >>=Compound shiftR ke La <<= 240
14&= ^= `=`Compound bitwiseR ke La &= 0xF
15,CommaL ke R(x=1, y=2)2

Aritmetika, Bitwise, dan Logika #

Kode berikut mendemonstrasikan seluruh operator aritmetika, bitwise, logika, assignment gabungan, increment, ternary, comma, dan sizeof dalam satu program. Output pada setiap baris dicantumkan sebagai komentar untuk verifikasi.

c
/* File: op1.c - Demonstrasi operator C */
#include <stdio.h>

static int step(int *p) { *p += 1; return *p; }

int main(void) {
    int a = 10, b = 3, c = 5;

    /* Aritmetika */
    printf("a + b = %d\n", a + b);     /* 13 */
    printf("a - b = %d\n", a - b);     /* 7 */
    printf("a * b = %d\n", a * b);     /* 30 */
    printf("a / b = %d\n", a / b);     /* 3 (integer division) */
    printf("a %% b = %d\n", a % b);     /* 1 (modulo) */
    printf("-a = %d\n", -a);            /* -10 (unary minus) */

    /* Bitwise */
    printf("a & b = %d\n", a & b);      /* 2 */
    printf("a | b = %d\n", a | b);      /* 11 */
    printf("a ^ b = %d\n", a ^ b);      /* 9 */
    printf("~a = %d\n", ~a);            /* -11 */
    printf("a << 2 = %d\n", a << 2);    /* 40 */
    printf("a >> 1 = %d\n", a >> 1);    /* 5 */

    /* Perbandingan dan logika */
    printf("a > b : %d\n", a > b);      /* 1 */
    printf("(a > b) && (c > 0) : %d\n", (a > b) && (c > 0));   /* 1 */
    printf("(a < b) || (c > 0) : %d\n", (a < b) || (c > 0));   /* 1 */
    printf("! (a > b) : %d\n", !(a > b));   /* 0 */

    /* Assignment gabungan */
    int x = 100;
    x += 5;  printf("x += 5 -> %d\n", x);   /* 105 */
    x <<= 3; printf("x <<= 3 -> %d\n", x);  /* 24 (setelah x=3 dari %/) */
    x &= 0xF; printf("x &= 0xF -> %d\n", x);/* 8 */

    /* Increment / decrement */
    int y = 7;
    int post = y++;                       /* post = 7, y jadi 8 */
    printf("post = y++ : %d, y sekarang = %d\n", post, y);   /* 7, 8 */
    int pre = ++y;                        /* y jadi 9, pre = 9 */
    printf("pre = ++y : %d, y sekarang = %d\n", pre, y);     /* 9, 9 */

    /* Ternary */
    int max = (a > b) ? a : b;
    printf("max(a,b) = %d\n", max);          /* 10 */

    /* Comma operator: evaluasi kiri ke kanan, hasilkan operand terakhir */
    int counter = 0;
    int z = (step(&counter), step(&counter), step(&counter));
    printf("z (comma) = %d, counter = %d\n", z, counter);  /* 3, 3 */

    /* sizeof */
    printf("sizeof(int) = %zu\n", sizeof(int));   /* 4 */
    printf("sizeof(double) = %zu\n", sizeof(double)); /* 8 */

    return 0;
}

Compile dan jalankan:

bash
gcc -std=c11 -Wall -Wextra -o op1 op1.c
./op1

Output yang Dihasilkan:

text
a + b = 13
a - b = 7
a * b = 30
a / b = 3
a % b = 1
-a = -10
a & b = 2
a | b = 11
a ^ b = 9
~a = -11
a << 2 = 40
a >> 1 = 5
a > b : 1
(a > b) && (c > 0) : 1
(a < b) || (c > 0) : 1
! (a > b) : 0
x += 5 -> 105
x <<= 3 -> 24
x &= 0xF -> 8
post = y++ : 7, y sekarang = 8
pre = ++y : 9, y sekarang = 9
max(a,b) = 10
z (comma) = 3, counter = 3
sizeof(int) = 4
sizeof(double) = 8

Mari kita telaah baris-baris kode di atas:

  1. Baris 4 (static int step(int *p)): Fungsi pembantu yang menginkrement *p lalu mengembalikan nilai baru. Kita pakai ini untuk mendemonstrasikan comma operator dengan efek samping yang terlihat.
  2. Baris 21 (a / b): Pembagian integer membuang sisa. Hasil 10 / 3 adalah 3, bukan 3.33. Untuk pembagian pecahan, keduanya harus cast ke double lebih dulu.
  3. Baris 33 (~a): Bitwise NOT membalik semua bit. Untuk int 32-bit dengan two’s complement, ~10 = -11 karena ~x = -x - 1.
  4. Baris 53 (int z = (step(&counter), step(&counter), step(&counter));): Comma operator mengevaluasi setiap operand dari kiri ke kanan, lalu menghasilkan nilai operand paling kanan. Di sini counter dipertambah tiga kali menjadi 3, dan z menerima nilai terakhir 3.
  5. Baris 56 (sizeof(int)): sizeof mengembalikan tipe size_t—kita pakai %zu sebagai format specifier agar portable di platform 32-bit maupun 64-bit.

Jebakan Umum #

JebakanContoh BermasalahPerbaikan
Lupa precedence bitwisea & b == 0 (dievaluasi a & (b == 0))(a & b) == 0
Increment di argumen samaprintf("%d %d", i++, i++) (UB: urutan tak terdefinisi)Pisahkan ke baris terpisah
Assignment vs equalityif (a = b) (selalu true kecuali b=0)if (a == b)
Shift negatifa << -1 (UB)Validasi jumlah shift >= 0
Signed overflowINT_MAX + 1 (UB)Pakai tipe unsigned atau cek dulu

Cast dan Konversi Implicit #

C melakukan konversi tipe otomatis (implicit conversion) saat operand memiliki tipe berbeda. Aturan umum: tipe yang “lebih sempit” dipromosikan ke tipe yang “lebih lebar” sebelum operasi dilakukan. Promosi integer (integer promotion) mengubah char, short, dan unsigned char ke int atau unsigned int terlebih dahulu.

EkspresiKonversiHasil
char c = 'A'; c + 1c dipromosikan ke int66
int i = 5; i + 2.0i dikonversi ke double7.0
5 / 2Integer division2
5 / 2.05 dikonversi ke double2.5
(int)3.99Truncation ke int3
(unsigned)-1Reinterpretasi bit4294967295