Variabel adalah pondasi dari setiap program C. Tanpa variabel, program hanya bisa mencetak teks yang sama berulang-ulang dan tidak bisa menyimpan hasil perhitungan, input pengguna, ataupun status apa pun. Pada Chapter ini kita akan memetakan apa sesungguhnya variabel dari sudut pandang mesin, mengapa setiap variabel harus memiliki tipe data, serta bagaimana operasi baca dan tulis terhadap variabel bekerja di balik layar. Pemahaman ini penting karena kesalahan paling umum di C—seperti membaca variabel sebelum diberi nilai, atau mencampur tipe yang berbeda—berakar pada konsep dasar yang akan kita bahas berikut ini.

Variabel sebagai Nama untuk Lokasi Memori #

Variabel adalah identifier yang kita definisikan di kode sumber dan diterjemahkan oleh compiler menjadi alamat di memori komputer. Ketika kita menulis int umur = 25;, compiler mengalokasikan sekian byte di memori (biasanya 4 byte untuk int), mengisi byte tersebut dengan pola biner yang merepresentasikan angka 25, lalu mencatat bahwa nama umur merujuk pada alamat tersebut. Nama variabel hanya ada di kode sumber; setelah dikompilasi, yang tersisa hanyalah alamat memori.

c
#include <stdio.h>

int main(void) {
    int umur = 25;
    double tinggi = 168.5;
    char inisial = 'B';

    printf("umur    = %d tahun\n", umur);
    printf("tinggi  = %.1f cm\n", tinggi);
    printf("inisial = %c\n", inisial);

    umur = umur + 1;
    printf("umur setelah ulang tahun = %d tahun\n", umur);
    return 0;
}

Output yang Dihasilkan:

text
umur    = 25 tahun
tinggi  = 168.5 cm
inisial = B
umur setelah ulang tahun = 26 tahun

Mari kita telaah baris-baris kode di atas:

  1. Baris 4 (int umur = 25;): compiler mengalokasikan 4 byte di memori dan mengisinya dengan nilai 25; nama umur dipakai untuk merujuk lokasi tersebut.
  2. Baris 5 (double tinggi = 168.5;): tipe double membutuhkan 8 byte untuk menyimpan bilangan desimal dengan presisi ganda.
  3. Baris 6 (char inisial = 'B';): tipe char hanya butuh 1 byte; karakter 'B' disimpan sebagai kode numerik ASCII (66).
  4. Baris 11 (umur = umur + 1;): compiler membaca nilai umur saat ini (25), menambahkannya dengan 1, lalu menulis hasil 26 kembali ke lokasi memori yang sama.
  5. Baris 12 (printf(...)): mencetak nilai umur yang baru untuk memastikan perubahan benar-benar tersimpan.

Mengapa Setiap Variabel Harus Bertipe #

C adalah bahasa statically typed. Artinya, tipe variabel harus ditentukan saat deklarasi dan tidak bisa berubah selama program berjalan. Tipe memberi tahu compiler dua hal sekaligus: berapa banyak byte yang dialokasikan, dan bagaimana byte-byte tersebut harus diinterpretasikan (apakah sebagai bilangan bulat bertanda, bilangan desimal, karakter, atau pola lain). Tanpa informasi tipe, compiler tidak bisa menghasilkan instruksi mesin yang benar untuk membaca atau menulis nilai tersebut.

Sebagai contoh, pola byte 0x42 bisa diinterpretasikan sebagai karakter 'B' jika tipe variabel char, atau sebagai angka 66 jika tipe variabel int. Tipe yang berbeda juga menentukan operasi yang valid: kita bisa melakukan operasi modulo % pada int, tetapi operasi tersebut tidak diperbolehkan pada double.

c
#include <stdio.h>

int main(void) {
    int nilai = 42;
    printf("nilai         = %d\n", nilai);
    printf("alamat &nilai = %p\n", (void *)&nilai);
    printf("ukuran int   = %zu byte\n", sizeof(int));
    return 0;
}

Output yang Dihasilkan:

text
nilai         = 42
alamat &nilai = 0x7fff1ddb748c
ukuran int   = 4 byte

Alamat pada output di atas bisa berbeda setiap kali program dijalankan karena address space layout randomization (ASLR) yang diterapkan sistem operasi modern. Yang penting kita pahami, nama nilai dipetakan compiler menjadi alamat tertentu, dan operator & mengambil alamat tersebut secara langsung.

Variabel Menyimpan Salinan, Bukan Referensi #

Saat kita memberikan nilai dari satu variabel ke variabel lain, C menyalin nilainya, bukan membuat tautan antara kedua variabel. Hal ini berarti perubahan pada variabel sumber setelah penyalinan tidak memengaruhi variabel tujuan. Banyak pemula yang terkejut saat mengetahui bahwa jumlah = a + b tidak otomatis berubah ketika a diperbarui.

c
#include <stdio.h>

int main(void) {
    int a = 10;
    int b = 20;
    int jumlah = a + b;

    printf("a = %d, b = %d\n", a, b);
    printf("jumlah = a + b = %d\n", jumlah);

    a = 100;
    printf("setelah a diubah: a = %d, b = %d, jumlah = %d\n", a, b, jumlah);
    return 0;
}

Output yang Dihasilkan:

text
a = 10, b = 20
jumlah = a + b = 30
setelah a diubah: a = 100, b = 20, jumlah = 30

Pada baris ke-7, ekspresi a + b dievaluasi menjadi 30, lalu nilai tersebut disalin ke variabel jumlah. Ketika a diubah menjadi 100 di baris ke-11, variabel jumlah tetap menyimpan 30 karena jumlah tidak memiliki koneksi ke a atau b selain dari perhitungan sekali saaat saat penugasan.

Siklus Hidup Variabel Sederhana #

Variabel lokal yang dideklarasikan di dalam blok fungsi memiliki siklus hidup singkat: dibuat saat eksekusi memasuki blok, dihancurkan saat eksekusi keluar dari blok. Konsekuensinya, alamat dan isi memori variabel lokal tidak boleh diakses setelah fungsi selesai, karena memori tersebut bisa dipakai ulang untuk hal lain. Inilah pondasi mengapa kita harus berhati-hati saat mengembalikan pointer ke variabel lokal dari sebuah fungsi—topik yang akan kita dalami pada Section pointer.

Dengan konsep dasar ini—variabel sebagai nama untuk lokasi memori bertipe tertentu, menyimpan salinan nilai, dan memiliki siklus hidup terbatas—kita siap melangkah ke cara mendeklarasikan dan menginisialisasi variabel secara formal pada Chapter berikutnya.