Variabel lokal biasa hidup hanya selama pemanggilan fungsi—setiap pemanggilan mendapatkan set variabel baru yang di-reset ke nilai awal. Tetapi kadang kita ingin sebuah variabel lokal mempertahankan nilainya antar pemanggilan fungsi, tanpa harus menjadikannya variabel global yang dapat diakses dari mana saja. Di sinilah peran static local variable: variabel yang scope-nya lokal (hanya terlihat di dalam fungsi), tetapi lifetime-nya statis (tetap hidup sepanjang program berjalan). Pada chapter ini kita akan menelusuri cara kerja static local variable, pola call counter, dan penggunaan static array untuk caching.
Karakteristik Static Local Variable #
Static local variable dideklarasikan dengan keyword static sebelum tipe variabel. Tiga sifat utamanya:
- Inisialisasi hanya sekali: pada pemanggilan pertama. Pemanggilan berikutnya tidak menginisialisasi ulang.
- Nilai tetap hidup antar pemanggilan: nilai variabel dipertahankan walaupun fungsi sudah selesai dieksekusi.
- Default zero initialization: bila tidak diberi inisialisasi eksplisit, variabel di-zero-initialize (sama seperti global).
Berikut contoh paling dasar: fungsi yang menghitung berapa kali ia dipanggil.
#include <stdio.h>
/* Static local variable: mempertahankan nilai antar pemanggilan */
int hitung_panggilan(void) {
static int counter = 0; /* Inisialisasi hanya sekali */
counter++;
return counter;
}
int main(void) {
printf("Panggilan ke-1: %d\n", hitung_panggilan());
printf("Panggilan ke-2: %d\n", hitung_panggilan());
printf("Panggilan ke-3: %d\n", hitung_panggilan());
printf("Panggilan ke-4: %d\n", hitung_panggilan());
return 0;
}Output yang Dihasilkan:
Panggilan ke-1: 1
Panggilan ke-2: 2
Panggilan ke-3: 3
Panggilan ke-4: 4Mari kita telaah baris-baris kode di atas:
- Baris 4 (
static int counter = 0;): deklarasi variabel lokalcounterdengan keywordstatic. Inisialisasi= 0hanya terjadi sekali—saat program dimulai (bukan saat fungsi dipanggil). Variabelcountertetap hidup sepanjang program berjalan. - Baris 5 (
counter++;): setiap kalihitung_panggilandipanggil, nilaicounterdinaikkan. Karena variabel tidak di-reset, nilainya terus bertambah:0 → 1 → 2 → 3 → 4. - Baris 6 (
return counter;): nilaicountersetelah inkremen dikembalikan ke pemanggil. Pemanggilan pertama mengembalikan1, pemanggilan kedua mengembalikan2, dan seterusnya. - Baris 10-13 (pemanggilan berturut-turut): setiap pemanggilan
hitung_panggilan()mengembalikan angka yang lebih besar, membuktikan bahwacountertetap hidup antar pemanggilan.
Pola Umum: ID Generator dan Memoization #
Static local variable sangat berguna untuk dua pola: ID generator (menghasilkan ID unik yang monoton naik) dan memoization (menyimpan hasil komputasi untuk dipakai ulang).
#include <stdio.h>
/* Static local untuk ID generator unik */
int buat_id_baru(void) {
static int id_berikutnya = 1000; /* Dimulai dari 1000 */
int id_sekarang = id_berikutnya;
id_berikutnya++;
return id_sekarang;
}
/* Static local untuk cache sederhana */
int fibonacci_memo(int n) {
static int memo[20] = {0}; /* Default 0 untuk semua elemen */
if (n < 1 || n > 19) return -1;
if (n == 1 || n == 2) return 1;
if (memo[n] != 0) return memo[n]; /* Sudah dihitung sebelumnya */
memo[n] = fibonacci_memo(n - 1) + fibonacci_memo(n - 2);
return memo[n];
}
int main(void) {
printf("ID baru: %d\n", buat_id_baru());
printf("ID baru: %d\n", buat_id_baru());
printf("ID baru: %d\n", buat_id_baru());
printf("Fib(10) = %d\n", fibonacci_memo(10));
printf("Fib(15) = %d\n", fibonacci_memo(15));
return 0;
}Output yang Dihasilkan:
ID baru: 1000
ID baru: 1001
ID baru: 1002
Fib(10) = 55
Fib(15) = 610Pada contoh di atas:
- Fungsi
buat_id_baru: variabelid_berikutnyaadalah static local. Setiap pemanggilan mengembalikan ID saat ini (1000,1001,1002), lalu menaikkan counter. Pola ini umum di library yang menghasilkan ID unik (misalnya pengelolaan sesi atau object handle). - Fungsi
fibonacci_memo: arraymemo[20]adalah static local array berisi 20 elemen, semuanya default0. Saat fungsi dipanggil dengann = 10, fungsi memeriksamemo[10]—bila sudah berisi nilai non-zero, fungsi mengembalikan nilai tersebut (cache hit). Bila masih0, fungsi menghitung rekursif dan menyimpan hasilnya kememo[n]. Pemanggilanfibonacci_memo(15)setelahnya dapat memanfaatkan hasilfibonacci_memo(10)yang sudah ada di cache—drastis mempercepat komputasi.
Static Const untuk Konstanta Lokal #
Sering kita ingin sebuah konstanta hanya terlihat di dalam fungsi tertentu, tanpa harus membuatnya global. Pola static const menggabungkan keuntungan static (inisisialisasi sekali, lifetime statis) dengan const (read-only, memungkinkan optimisasi compiler).
#include <stdio.h>
/* Static local: inisialisasi konstan hanya sekali */
double dapatkan_faktor_skala(void) {
static const double skala = 0.85; /* Inisialisasi sekali */
return skala;
}
int main(void) {
/* Walaupun dipanggil berkali-kali, skala tetap 0.85 */
for (int i = 0; i < 3; i++) {
printf("Skala pemanggilan %d: %.2f\n", i, dapatkan_faktor_skala());
}
return 0;
}Output yang Dihasilkan:
Skala pemanggilan 0: 0.85
Skala pemanggilan 1: 0.85
Skala pemanggilan 2: 0.85Pada contoh di atas, konstanta skala = 0.85 dideklarasikan sebagai static const double. Walaupun fungsi dapatkan_faktor_skala dipanggil tiga kali, konstanta tersebut tetap 0.85 karena static local hanya diinisialisasi sekali. Pendekatan ini lebih ringkas daripada mendeklarasikan konstanta global, dan tidak mencemari namespace file dengan nama skala yang hanya relevan untuk fungsi ini.
Dengan pemahaman static local, kita siap melangkah ke chapter Recursion untuk membahas pola pemanggilan diri sendiri—salah satu penggunaan fungsi yang paling elegan tetapi juga berbahaya bila tidak hati-hati.