Operator assignment adalah tulang punggung mutasi data di C. Tanpa operator assignment, sebuah program hanya bisa menghitung nilai tetapi tidak bisa menyimpan hasil perhitungan tersebut kembali ke variabel. Pada Chapter ini kita akan menelaah operator = beserta sepuluh bentuk augmented assignment (+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=), sifat right-to-left associativity yang memungkinkan chained assignment, serta jebakan klasik berupa kekeliruan menulis = ketika yang dimaksud adalah ==. Kita juga akan melihat mengapa operator assignment di C diperlakukan sebagai ekspresi yang menghasilkan nilai, bukan sekadar pernyataan.

Operator Assignment Dasar #

Operator = adalah operator assignment paling mendasar. Operator = mengevaluasi ekspresi di sisi kanan terlebih dahulu, kemudian menyalin hasilnya ke variabel di sisi kiri. Sisi kiri harus berupa lvalue—sebuah ekspresi yang merujuk ke lokasi memori yang dapat ditulis, seperti variabel atau elemen array. Sisi kanan boleh berupa ekspresi apa pun yang menghasilkan nilai.

Operator assignment di C adalah ekspresi, bukan pernyataan mandiri. Artinya, x = 42 menghasilkan nilai 42 setelah penugasan terjadi. Sifat inilah yang memungkinkan chained assignment seperti a = b = c = 0.

Augmented Assignment #

Sepuluh operator augmented assignment menggabungkan operasi biner dengan assignment dalam satu notasi singkat. Bentuk op= adalah syntactic sugar untuk lhs = lhs op rhs, dengan pengecualian bahwa sisi kiri hanya dievaluasi satu kali (penting saat lhs memiliki efek samping).

BentukEkuivalenOperasi
a += ba = a + bpenjumlahan
a -= ba = a - bpengurangan
a *= ba = a * bperkalian
a /= ba = a / bpembagian
a %= ba = a % bsisa bagi
a &= ba = a & bAND bitwise
a |= ba = a | bOR bitwise
a ^= ba = a ^ bXOR bitwise
a <<= ba = a << bgeser kiri
a >>= ba = a >> bgeser kanan
c
#include <stdio.h>

int main(void) {
    int saldo = 0;       /* assignment sederhana */
    saldo = 100000;      /* assignment ulang */
    printf("Saldo awal      : Rp %d\n", saldo);

    saldo += 50000;      /* saldo = saldo + 50000 */
    printf("Setelah nabung  : Rp %d\n", saldo);

    saldo -= 30000;      /* saldo = saldo - 30000 */
    printf("Setelah tarik   : Rp %d\n", saldo);

    saldo *= 2;           /* saldo = saldo * 2 */
    printf("Bonus kali 2    : Rp %d\n", saldo);

    saldo /= 4;           /* saldo = saldo / 4 */
    printf("Dibagi 4        : Rp %d\n", saldo);

    saldo %= 70000;       /* saldo = saldo % 70000 */
    printf("Sisa bagi 70rb  : Rp %d\n", saldo);
    return 0;
}

Output yang Dihasilkan:

text
Saldo awal      : Rp 100000
Setelah nabung  : Rp 150000
Setelah tarik   : Rp 120000
Bonus kali 2    : Rp 240000
Dibagi 4        : Rp 60000
Sisa bagi 70rb  : Rp 60000

Mari kita telaah baris-baris kode di atas:

  1. Baris 5 (int saldo = 0;): deklarasi sekaligus inisialisasi; saldo diisi 0.
  2. Baris 6 (saldo = 100000;): assignment ulang; nilai 0 ditimpa dengan 100000.
  3. Baris 10 (saldo += 50000;): ekspresi saldo + 50000 dievaluasi menjadi 150000, lalu disimpan kembali ke saldo.
  4. Baris 19 (saldo %= 70000;): saldo saat ini 60000; karena 60000 < 70000, hasil 60000 % 70000 adalah 60000 itu sendiri.

Chained Assignment dan Assignment sebagai Ekspresi #

Karena operator = bersifat right-associative dan menghasilkan nilai, kita dapat menulis rangkaian penugasan dalam satu pernyataan. Compiler memproses a = b = c = 7 sebagai a = (b = (c = 7)): pertama c diisi 7, ekspresi tersebut menghasilkan 7, lalu b diisi 7, dan akhirnya a diisi 7.

c
#include <stdio.h>

int main(void) {
    int a, b, c, d;

    /* Chained assignment: dievaluasi kanan-ke-kiri */
    a = b = c = d = 7;
    printf("a=%d b=%d c=%d d=%d\n", a, b, c, d);

    /* Assignment adalah ekspresi yang menghasilkan nilai */
    int x;
    int y = (x = 42) + 8;
    printf("x = %d, y = %d\n", x, y);

    /* Jebakan: = bukan == */
    int flag = 0;
    if (flag = 5) {       /* selalu benar karena 5 non-zero */
        printf("flag kini = %d, cabang ini selalu dijalankan\n", flag);
    }
    return 0;
}

Output yang Dihasilkan:

text
a=7 b=7 c=7 d=7
x = 42, y = 50
flag kini = 5, cabang ini selalu dijalankan

Pada baris ke-13, ekspresi (x = 42) menugasi x dengan 42 dan menghasilkan nilai 42. Nilai tersebut kemudian dijumlahkan dengan 8 menjadi 50 dan ditugasi ke y. Pada baris ke-18, pernyataan flag = 5 di dalam if adalah assignment (bukan perbandingan); operator assignment menghasilkan 5 yang dianggap benar, sehingga cabang selalu dijalankan.

Augmented Assignment Bitwise #

Lima operator augmented assignment terakhir berinteraksi dengan operator bitwise. Kita akan menelaah operator bitwise secara mendalam pada Chapter operator-bitwise, tetapi pada bagian ini kita melihat dulu bagaimana bentuk augmented-nya bekerja pada nilai unsigned int yang dipakai sebagai bitmask.

c
#include <stdio.h>

int main(void) {
    int x = 10;
    int y = 3;

    /* Augmented assignment pada ekspresi kompleks */
    x += y * 2;     /* ekuivalen: x = x + (y * 2) */
    printf("x += y*2  -> x=%d, y=%d\n", x, y);

    /* Operator bitwise augmented juga tersedia */
    unsigned int mask = 0xF0;
    mask |= 0x0F;       /* mask = mask | 0x0F */
    printf("mask |= 0x0F -> mask = 0x%X\n", mask);

    mask &= 0x33;
    printf("mask &= 0x33 -> mask = 0x%X\n", mask);

    mask ^= 0xFF;
    printf("mask ^= 0xFF -> mask = 0x%X\n", mask);

    mask <<= 2;
    printf("mask <<= 2  -> mask = 0x%X\n", mask);

    mask >>= 1;
    printf("mask >>= 1  -> mask = 0x%X\n", mask);
    return 0;
}

Output yang Dihasilkan:

text
x += y*2  -> x=16, y=3
mask |= 0x0F -> mask = 0xFF
mask &= 0x33 -> mask = 0x33
mask ^= 0xFF -> mask = 0xCC
mask <<= 2  -> mask = 0x330
mask >>= 1  -> mask = 0x198

Pada baris ke-9, x += y * 2 setara dengan x = x + (y * 2) karena precedence * lebih tinggi daripada +. Compiler pertama menghitung y * 2 = 6, lalu menambahkannya ke x yang bernilai 10 menjadi 16.

Dengan demikian, kita telah melihat bahwa operator assignment bukan sekadar penyimpanan nilai, melainkan ekspresi yang menghasilkan nilai dan dapat dirangkai. Pada Chapter berikutnya kita akan menelaah operator increment dan decrement yang merupakan bentuk paling ringkas dari += 1 dan -= 1.