Berbeda dengan Python yang menyediakan fungsi len(arr) atau Java dengan arr.length, bahasa C tidak menyimpan panjang array sebagai atribut yang bisa diakses saat runtime. Untuk mengetahui jumlah elemen sebuah array lokal, kita mengandalkan operator sizeof yang dievaluasi saat kompilasi. Idiom standarnya adalah sizeof(arr) / sizeof(arr[0])—ukuran total dibagi ukuran per elemen. Pada chapter ini kita akan menelusuri idiom ini, kapan idiom ini valid, kapan idiom ini menyesatkan (saat array sudah decay menjadi pointer), serta cara mempermudahnya dengan macro.
Mengapa sizeof(arr) / sizeof(arr[0]) Bekerja #
Operator sizeof mengembalikan jumlah byte yang dipakai suatu tipe atau variabel. Untuk array lokal int arr[5]:
sizeof(arr)= 5 elemen × 4 byte = 20 byte.sizeof(arr[0])= 4 byte (ukuran satuint).- Hasil bagi
20 / 4 = 5= jumlah elemen.
Idiom ini bekerja karena di scope tempat array dideklarasikan, sizeof(arr) benar-benar mengembalikan ukuran array, bukan ukuran pointer. Akan tetapi, idiom ini tidak berlaku di dalam fungsi yang menerima array sebagai parameter—di sana arr sudah meluruh menjadi pointer sehingga sizeof(arr) = ukuran pointer (8 byte pada 64-bit).
Menghitung Panjang Array #
Contoh berikut memperlihatkan idiom sizeof(arr) / sizeof(arr[0]) untuk tiga array dengan tipe berbeda.
#include <stdio.h>
int main(void) {
int angka[7] = {3, 6, 9, 12, 15, 18, 21};
char huruf[4] = {'a', 'b', 'c', 'd'};
double pecahan[3] = {1.5, 2.5, 3.5};
/* sizeof(arr) mengembalikan total byte */
/* sizeof(arr[0]) mengembalikan byte per elemen */
/* Hasil bagi = jumlah elemen */
size_t jumlah_angka = sizeof(angka) / sizeof(angka[0]);
size_t jumlah_huruf = sizeof(huruf) / sizeof(huruf[0]);
size_t jumlah_pecahan = sizeof(pecahan) / sizeof(pecahan[0]);
printf("angka : %zu elemen (sizeof=%zu, per elemen=%zu)\n",
jumlah_angka, sizeof(angka), sizeof(angka[0]));
printf("huruf : %zu elemen (sizeof=%zu, per elemen=%zu)\n",
jumlah_huruf, sizeof(huruf), sizeof(huruf[0]));
printf("pecahan: %zu elemen (sizeof=%zu, per elemen=%zu)\n",
jumlah_pecahan, sizeof(pecahan), sizeof(pecahan[0]));
/* Iterasi pakai jumlah elemen yang dihitung */
int total = 0;
size_t n = sizeof(angka) / sizeof(angka[0]);
for (size_t i = 0; i < n; i++) {
total += angka[i];
}
printf("Total angka: %d\n", total);
return 0;
}Output yang Dihasilkan:
angka : 7 elemen (sizeof=28, per elemen=4)
huruf : 4 elemen (sizeof=4, per elemen=1)
pecahan: 3 elemen (sizeof=24, per elemen=8)Mari kita telaah baris-baris kode di atas:
- Baris 4 (
int angka[7] = {...}): deklarasi arrayintberukuran 7 elemen. Total memori = 7 × 4 = 28 byte. - Baris 5 (
char huruf[4] = {...}): arraycharberukuran 4. Total memori = 4 × 1 = 4 byte. - Baris 6 (
double pecahan[3] = {...}): arraydoubleberukuran 3. Total memori = 3 × 8 = 24 byte. - Baris 12 (
size_t jumlah_angka = sizeof(angka) / sizeof(angka[0]);): idiom standar.sizeof(angka)= 28 byte,sizeof(angka[0])= 4 byte, hasil bagi = 7. Tipesize_tadalah unsigned integer yang cocok untuk ukuran memori. - Baris 25 (
for (size_t i = 0; i < n; i++)): loop memakaisize_tuntuk indeks. Memakaisize_t(bukanint) menghindari peringatan compiler saat membandingkan signed dan unsigned. - Baris 26 (
total += angka[i];): akumulasi nilai. Indeksiaman karena tidak pernah melebihin - 1= 6.
Mempermudah dengan Macro ARRAY_LEN #
Idiom sizeof(arr) / sizeof(arr[0]) cukup panjang untuk diketik berulang. Kita bisa membungkusnya dalam macro agar lebih ringkas. Contoh berikut juga memperlihatkan bahwa idiom ini bekerja untuk array dengan tipe apa pun.
#include <stdio.h>
/* Helper macro untuk menghitung jumlah elemen array */
#define ARRAY_LEN(a) (sizeof(a) / sizeof((a)[0]))
int main(void) {
int nilai[] = {80, 70, 90, 85, 60, 75};
double suhu[] = {27.5, 28.0, 28.5, 29.0};
char kode[] = {'X', 'Y', 'Z'};
printf("Panjang nilai: %zu\n", ARRAY_LEN(nilai));
printf("Panjang suhu : %zu\n", ARRAY_LEN(suhu));
printf("Panjang kode : %zu\n", ARRAY_LEN(kode));
/* Loop dengan ARRAY_LEN */
int total = 0;
for (size_t i = 0; i < ARRAY_LEN(nilai); i++) {
total += nilai[i];
}
printf("Rata-rata nilai: %.2f\n", (double)total / ARRAY_LEN(nilai));
return 0;
}Output yang Dihasilkan:
Panjang nilai: 6
Panjang suhu : 4
Panjang kode : 3
Rata-rata nilai: 76.67Pada contoh di atas, macro ARRAY_LEN(a) mengembalikan jumlah elemen array a. Macro ini generik—bisa dipakai untuk int, double, char, atau tipe lain tanpa modifikasi. Tanda kurung ganda di sekitar a (((a)[0])) melindungi dari operator precedence yang tak terduga bila macro dipakai di ekspresi kompleks.