Array bisa menyimpan tipe compound apa pun, termasuk struct. Saat kita perlu mengelola kumpulan entitas terstruktur (daftar mahasiswa, daftar buku, daftar titik koordinat), array of structures menjadi solusi alami. Setiap elemen array adalah satu struct lengkap dengan semua field-nya, dan kita bisa mengakses field tertentu melalui operator . (titik). Pada chapter ini kita akan menelusuri deklarasi array of structs, akses field, dan beberapa operasi umum seperti pencarian nilai maksimum atau perhitungan total.

Mendeklarasikan Array of Structures #

Bentuk umum deklarasi array of struct adalah struct NamaType nama_arr[ukuran];. Setiap elemen nama_arr[i] adalah struct NamaType lengkap, dan field-nya diakses dengan nama_arr[i].field. Inisialisasi bisa memakai nested braces—tiap inner brace merepresentasikan satu struct.

Array of Struct Titik dan Mahasiswa #

Contoh berikut mendefinisikan dua struct (Titik dan Mahasiswa), membuat array berisi masing-masing struct, lalu melakukan iterasi dan pencarian.

c
#include <stdio.h>

/* Definisi struct Titik */
struct Titik {
    int x;
    int y;
};

/* Definisi struct Mahasiswa */
struct Mahasiswa {
    char nama[20];
    int  nilai;
};

int main(void) {
    /* Array of struct Titik */
    struct Titik titik[3] = {
        {2, 5},
        {7, 1},
        {4, 9}
    };

    /* Array of struct Mahasiswa */
    struct Mahasiswa mhs[3] = {
        {"Budi", 85},
        {"Siti", 92},
        {"Andi", 78}
    };

    /* Akses field via titik[.] */
    printf("Daftar titik:\n");
    for (int i = 0; i < 3; i++) {
        printf("  titik[%d] = (%d, %d)\n", i, titik[i].x, titik[i].y);
    }

    printf("\nDaftar mahasiswa:\n");
    for (int i = 0; i < 3; i++) {
        printf("  %s: nilai %d\n", mhs[i].nama, mhs[i].nilai);
    }

    /* sizeof untuk array of struct */
    printf("\nsizeof(struct Titik) = %zu\n", sizeof(struct Titik));
    printf("sizeof(titik)        = %zu\n", sizeof(titik));
    printf("Jumlah elemen titik  = %zu\n", sizeof(titik) / sizeof(titik[0]));

    /* Cari nilai tertinggi */
    int idx_max = 0;
    for (int i = 1; i < 3; i++) {
        if (mhs[i].nilai > mhs[idx_max].nilai) {
            idx_max = i;
        }
    }
    printf("\nNilai tertinggi: %s (%d)\n", mhs[idx_max].nama, mhs[idx_max].nilai);

    return 0;
}

Output yang Dihasilkan:

text
Daftar titik:
  titik[0] = (2, 5)
  titik[1] = (7, 1)
  titik[2] = (4, 9)

Daftar mahasiswa:
  Budi: nilai 85
  Siti: nilai 92
  Andi: nilai 78

sizeof(struct Titik) = 8
sizeof(titik)        = 24
Jumlah elemen titik  = 3

Nilai tertinggi: Siti (92)

Mari kita telaah baris-baris kode di atas:

  1. Baris 4-7 (struct Titik { int x; int y; };): definisi tipe struct Titik dengan dua field int. Karena kedua field bertipe int dan tidak ada alignment problem, sizeof(struct Titik) = 8 byte.
  2. Baris 10-13 (struct Mahasiswa { char nama[20]; int nilai; };): definisi struct Mahasiswa dengan array char[20] dan int. sizeof(struct Mahasiswa) = 24 byte (20 byte array + 4 byte int, tanpa padding karena alignment-nya cocok).
  3. Baris 16-20 (struct Titik titik[3] = {{2,5}, {7,1}, {4,9}};): deklarasi array 3 elemen struct Titik. Setiap inner brace menginisialisasi satu struct.
  4. Baris 23-27 (struct Mahasiswa mhs[3] = {...};): deklarasi array 3 elemen struct Mahasiswa. Inisialisasi string literal {"Budi", 85} otomatis menyalin "Budi" ke field nama.
  5. Baris 31-33 (titik[i].x dan titik[i].y): akses field melalui operator .. Ekspresi titik[i].x artinya “akses field x dari struct ke-i di array titik”.
  6. Baris 38-40 (titik[i].y dst.): iterasi field juga memakai operator ..
  7. Baris 43-45 (sizeof(titik) / sizeof(titik[0]) = 3): idiom standar untuk menghitung jumlah elemen. sizeof(titik) = 24 byte, sizeof(titik[0]) = 8 byte (satu struct Titik). Hasil: 3 elemen.
  8. Baris 48-53 (pencarian nilai maksimum): algoritma klasik—simpan indeks kandidat maks (idx_max = 0), lalu loop dari indeks 1 sampai akhir. Bila ditemukan nilai lebih besar, perbarui idx_max. Setelah loop, mhs[idx_max] adalah struct Mahasiswa dengan nilai tertinggi.

Array of Struct Buku dengan Pengisian Bertahap #

Tidak semua array of struct diinisialisasi langsung. Kadang kita perlu mengisi field satu per satu, terutama bila data berasal dari input atau perhitungan. Contoh berikut mendeklarasikan array kosong lalu mengisi setiap field melalui strcpy dan assignment.

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

struct Buku {
    char judul[30];
    int  tahun;
    float harga;
};

int main(void) {
    struct Buku rak[3];

    /* Isi data satu per satu */
    strcpy(rak[0].judul, "Belajar C");
    rak[0].tahun = 2020;
    rak[0].harga = 95000.0f;

    strcpy(rak[1].judul, "Algoritma Pemrograman");
    rak[1].tahun = 2022;
    rak[1].harga = 120000.0f;

    strcpy(rak[2].judul, "Struktur Data");
    rak[2].tahun = 2021;
    rak[2].harga = 87000.0f;

    /* Cetak dengan format kolom */
    printf("%-25s %-6s %-10s\n", "Judul", "Tahun", "Harga");
    printf("------------------------------------------\n");
    for (int i = 0; i < 3; i++) {
        printf("%-25s %-6d Rp%-9.2f\n",
               rak[i].judul, rak[i].tahun, rak[i].harga);
    }

    /* Hitung total harga */
    float total = 0;
    for (int i = 0; i < 3; i++) {
        total += rak[i].harga;
    }
    printf("------------------------------------------\n");
    printf("Total: Rp%.2f\n", total);

    return 0;
}

Output yang Dihasilkan:

text
Judul                     Tahun  Harga
------------------------------------------
Belajar C                 2020   Rp95000.00
Algoritma Pemrograman     2022   Rp120000.00
Struktur Data             2021   Rp87000.00
------------------------------------------
Total: Rp302000.00

Pada contoh di atas, array rak dideklarasikan tanpa inisialisasi (isi acak). Field judul bertipe array char[30]—kita tidak bisa menulis rak[0].judul = "Belajar C"; (array tidak bisa di-assign), sehingga harus memakai strcpy. Field tahun dan harga bertipe skalar dan bisa di-assignment langsung. Format %-25s mencetak string rata kiri dengan lebar minimal 25 karakter—membuat tabel yang rapi.