Satu variabel struct Mahasiswa hanya menampung data satu mahasiswa. Nyatanya, sebuah kelas bisa berisi puluhan mahasiswa; sebuah toko menyimpan ribuan produk; sebuah sistem memuat jutaan pesanan. Kita membutuhkan cara untuk menyimpan banyak struct bertipe sama dan mengiterasinya. Di C, solusi paling alami adalah array of struct: sebuah array yang setiap elemennya adalah struct. Array seperti ini menggabungkan kekuatan dua mekanisme—kemampuan array untuk diiterasi dengan indeks, dan kemampuan struct untuk membungkus beberapa atribut menjadi satu unit. Pada chapter ini kita akan mendeklarasikan array of struct, mengiterasinya, dan mengirimkannya ke fungsi.

Mendeklarasikan Array of struct #

Sintaks deklarasi array of struct sama dengan array biasa, hanya saja tipe elemennya adalah struct atau alias typedef-nya. Bentuk umum: struct Tag nama_array[ukuran]; atau AliasTipe nama_array[ukusan];. Inisialisasi aggregate bisa dipakai dengan tanda kurung kurawal berlapis: luar untuk elemen array, dalam untuk member struct.

Mekanisme memori: seluruh elemen array of struct menempati satu blok memori berurutan. Alamat elemen ke-i dihitung sebagai base + i * sizeof(struct). Karena elemen saling berdekatan, iterasi dengan indeks adalah cara tercepat untuk membaca atau memproses seluruh elemen—sebanding dengan array int biasa.

c
#include <stdio.h>
#include <string.h>

struct Mahasiswa {
    char nama[40];
    int  umur;
    float ipk;
};

int main(void) {
    /* Array of struct dengan inisialisasi aggregate */
    struct Mahasiswa kelas[3] = {
        {"Budi Santoso", 21, 3.65f},
        {"Siti Aminah",  22, 3.85f},
        {"Andi Wijaya",  20, 3.55f}
    };

    /* Iterasi array of struct */
    printf("Daftar Mahasiswa:\n");
    printf("-------------------------------------------\n");
    for (int i = 0; i < 3; i++) {
        printf("%d. %-15s  %d thn  IPK %.2f\n",
               i + 1, kelas[i].nama, kelas[i].umur, kelas[i].ipk);
    }

    /* Hitung rata-rata IPK */
    float total = 0.0f;
    for (int i = 0; i < 3; i++) {
        total += kelas[i].ipk;
    }
    printf("Rata-rata IPK: %.2f\n", total / 3.0f);

    /* Cari IPK tertinggi */
    int idx_max = 0;
    for (int i = 1; i < 3; i++) {
        if (kelas[i].ipk > kelas[idx_max].ipk) {
            idx_max = i;
        }
    }
    printf("IPK tertinggi: %s (%.2f)\n",
           kelas[idx_max].nama, kelas[idx_max].ipk);

    return 0;
}

Output yang Dihasilkan:

text
Daftar Mahasiswa:
-------------------------------------------
1. Budi Santoso     21 thn  IPK 3.65
2. Siti Aminah      22 thn  IPK 3.85
3. Andi Wijaya      20 thn  IPK 3.55
Rata-rata IPK: 3.68
IPK tertinggi: Siti Aminah (3.85)

Mari kita telaah baris-baris kode di atas:

  1. Baris 11-15 (struct Mahasiswa kelas[3] = {...};): deklarasi array kelas berisi 3 elemen struct Mahasiswa. Inisialisasi aggregate berlapis: setiap {...} dalam mewakili satu elemen array, dan nilai-nilai di dalamnya mengisi member nama, umur, ipk sesuai urutan.
  2. Baris 21-23 (for (...) loop pertama): iterasi dengan indeks 0..2. Ekspresi kelas[i].nama mengakses member nama dari elemen ke-i. Format %-15s mencetak string rata kiri dengan lebar minimum 15 karakter.
  3. Baris 26-30 (loop rata-rata): akumulator total diisi dengan menjumlahkan kelas[i].ipk dari setiap elemen. Setelah loop, total / 3.0f menghasilkan rata-rata.
  4. Baris 33-38 (loop pencarian max): pola klasik “cari indeks elemen maksimum”. Variabel idx_max menyimpan indeks elemen dengan IPK tertinggi. Komparasi kelas[i].ipk > kelas[idx_max].ipk memutuskan apakah idx_max perlu diperbarui.
  5. Baris 39-40 (printf(...)): mencetak nama dan IPK mahasiswa dengan IPK tertinggi menggunakan kelas[idx_max].nama dan kelas[idx_max].ipk.

Mengoper Array of struct ke Fungsi #

Array of struct bisa dioper ke fungsi seperti array biasa. Saat dioper ke fungsi, array mengalami array decay menjadi pointer ke elemen pertama. Oleh karena itu, ukuran array tidak bisa dihitung di dalam fungsi dengan sizeof(arr)—kita perlu mengoper jumlah elemen sebagai parameter terpisah.

c
#include <stdio.h>
#include <string.h>

typedef struct {
    char  kode[10];
    char  nama[40];
    int   sks;
    int   semester;
} Matakuliah;

/* Fungsi yang menerima array of struct */
int total_sks(const Matakuliah *mk, int n) {
    int total = 0;
    for (int i = 0; i < n; i++) {
        total += mk[i].sks;
    }
    return total;
}

int main(void) {
    /* Inisialisasi array of struct */
    Matakuliah mk[] = {
        {"IF101", "Algoritma dan Pemrograman", 4, 1},
        {"IF102", "Struktur Data",            3, 2},
        {"IF103", "Basis Data",               3, 3},
        {"IF104", "Sistem Operasi",           4, 4}
    };
    int n = sizeof(mk) / sizeof(mk[0]);

    printf("Jumlah matakuliah: %d\n", n);
    printf("Total SKS        : %d\n", total_sks(mk, n));

    /* Filter matakuliah semester tertentu */
    int target = 3;
    printf("\nMatakuliah semester %d:\n", target);
    for (int i = 0; i < n; i++) {
        if (mk[i].semester == target) {
            printf("  %s - %s (%d SKS)\n", mk[i].kode, mk[i].nama, mk[i].sks);
        }
    }

    return 0;
}

Output yang Dihasilkan:

text
Jumlah matakuliah: 4
Total SKS        : 14

Matakuliah semester 3:
  IF103 - Basis Data (3 SKS)

Pada contoh di atas, Matakuliah mk[] = {...} mendeklarasikan array tanpa menyebut ukuran eksplisit—compiler menghitung jumlah elemen dari inisialisasi aggregate, yaitu 4. Idiom sizeof(mk) / sizeof(mk[0]) menghasilkan jumlah elemen (4) dan disimpan ke variabel n. Fungsi total_sks menerima pointer const Matakuliah *mk dan jumlah elemen n. Di dalam fungsi, akses elemen memakai sintaks mk[i].sks—secara teknis mk adalah pointer, tetapi indeks [i] bekerja seperti pada array biasa (karena mk[i] setara dengan *(mk + i)). Loop filter di main mencari elemen dengan semester == 3 dan mencetak detailnya.