Setiap kali kita mendeklarasikan variabel struct, kata kunci struct wajib ditulis ulang: struct Mahasiswa mhs;, struct Buku daftar[10];. Pada program besar, pengulangan kata struct ribuan kali terasa berisik dan membebani pembacaan. C menyediakan typedef untuk membuat alias tipe baru, sehingga Mahasiswa_t bisa langsung dipakai tanpa awalan struct. Pada chapter ini kita akan membandingkan penulisan dengan dan tanpa typedef, memahami tiga pola umum yang dipakai di industri, dan melihat bagaimana typedef juga bekerja pada enum dan union.

Apa Itu typedef #

typedef adalah kata kunci C yang membuat nama alias untuk tipe yang sudah ada. Bentuk umumnya: typedef <tipe_asli> <nama_alias>;. Setelah itu, <nama_alias> bisa dipakai seperti tipe bawaan—tanpa perlu menulis struct, enum, atau union lagi. typedef tidak membuat tipe baru; Mahasiswa_t dan struct Mahasiswa (jika keduanya mengacu ke definisi yang sama) adalah tipe yang sama dengan nama berbeda.

Mekanisme kerja typedef di balik layar: compiler menyimpan pemetaan nama alias ke tipe asli. Ketika compiler melihat Mahasiswa_t, compiler mencari pemetaan dan menggantinya dengan tipe asli yang dimaksud sebelum melakukan type-checking. Karena itu, semua operasi yang berlaku pada tipe asli juga berlaku pada alias.

Tiga Pola typedef pada struct #

Ada tiga pola yang sering muncul di kode nyata. Pertama, tanpa typedef—kita harus selalu menulis struct Mahasiswa. Kedua, anonymous struct + typedef—definisi struct tidak punya tag, dan typedef langsung membuat alias. Ketiga, tag + typedef—kita memberi tag sekaligus alias, sehingga keduanya bisa dipakai.

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

/* Tanpa typedef: harus menulis "struct Mahasiswa" */
struct Mahasiswa {
    char nama[50];
    int umur;
};

/* Dengan typedef: alias tipe "Mahasiswa_t" */
typedef struct {
    char nama[50];
    int umur;
    float ipk;
} Mahasiswa_t;

/* Pola umum: tag + typedef agar keduanya bisa dipakai */
typedef struct Dosen {
    char nama[50];
    int nidn;
} Dosen;

int main(void) {
    struct Mahasiswa m1;
    strcpy(m1.nama, "Budi");
    m1.umur = 21;

    Mahasiswa_t m2 = {"Siti", 22, 3.85f};

    Dosen d1 = {"Dr. Andi", 12345};

    printf("m1: %s, %d tahun\n", m1.nama, m1.umur);
    printf("m2: %s, %d tahun, IPK %.2f\n", m2.nama, m2.umur, m2.ipk);
    printf("d1: %s, NIDN %d\n", d1.nama, d1.nidn);

    /* Bandingkan ukuran tipe */
    printf("sizeof(struct Mahasiswa) = %zu\n", sizeof(struct Mahasiswa));
    printf("sizeof(Mahasiswa_t)      = %zu\n", sizeof(Mahasiswa_t));
    printf("sizeof(Dosen)             = %zu\n", sizeof(Dosen));

    return 0;
}

Output yang Dihasilkan:

text
m1: Budi, 21 tahun
m2: Siti, 22 tahun, IPK 3.85
d1: Dr. Andi, NIDN 12345
sizeof(struct Mahasiswa) = 56
sizeof(Mahasiswa_t)      = 60
sizeof(Dosen)             = 56

Mari kita telaah baris-baris kode di atas:

  1. Baris 6-9 (struct Mahasiswa { ... };): pendefinisian tipe dengan tag Mahasiswa, tanpa typedef. Untuk memakainya kita harus menulis struct Mahasiswa (lihat baris 22). Ini adalah cara klasik yang paling eksplisit.
  2. Baris 12-16 (typedef struct { ... } Mahasiswa_t;): anonymous struct (tanpa tag) yang langsung diberi alias Mahasiswa_t melalui typedef. Karena tidak ada tag, kita tidak bisa menulis struct Mahasiswa_t—itu akan jadi compile error. Yang benar adalah langsung Mahasiswa_t (lihat baris 26).
  3. Baris 19-22 (typedef struct Dosen { ... } Dosen;): pendefinisian tipe dengan tag Dosen sekaligus alias Dosen. Sejak baris ini, baik struct Dosen maupun Dosen merujuk ke tipe yang sama. Pola ini populer di pustaka standar C (misalnya di <stdio.h> untuk tipe FILE).
  4. Baris 30-32 (sizeof(...)): tiga pemanggilan sizeof menunjukkan ukuran masing-masing tipe. struct Mahasiswa (50 + 4 + padding = 56) berbeda dari Mahasiswa_t (50 + 4 + 4 + padding = 60) karena keduanya memang struct berbeda dengan member berbeda. Dosen (50 + 4 + padding = 56) sama dengan struct Dosen karena keduanya merujuk ke definisi yang sama.

typedef Berlaku untuk enum dan union Juga #

typedef tidak terbatas pada struct. Kita bisa memakai pola yang sama untuk enum dan union. Hal ini membuat deklarasi variabel konstanta terhitung dan data union lebih ringkas.

c
#include <stdio.h>

/* typedef pada struct primitif yang sering dipakai */
typedef struct {
    int x;
    int y;
} Point;

typedef struct {
    Point start;
    Point end;
} LineSegment;

/* typedef juga bekerja pada enum dan union */
typedef enum { MERAH, HIJAU, BIRU } Warna;

/* Fungsi yang memakai alias */
void tampilkan_titik(Point p) {
    printf("(%d, %d)", p.x, p.y);
}

int main(void) {
    LineSegment garis = {{0, 0}, {5, 5}};
    Warna c = HIJAU;

    printf("Garis dari ");
    tampilkan_titik(garis.start);
    printf(" ke ");
    tampilkan_titik(garis.end);
    printf("\nWarna indeks: %d\n", c);

    return 0;
}

Output yang Dihasilkan:

text
Garis dari (0, 0) ke (5, 5)
Warna indeks: 1

Pada contoh di atas, Point adalah alias untuk anonymous struct berisi dua int. LineSegment punya dua member bertipe Point—disebut nested struct, yang akan kita bahas lebih lanjut di chapter tersendiri. Warna adalah alias untuk enum dengan tiga konstanta: MERAH = 0, HIJAU = 1, BIRU = 2. Karena c = HIJAU, indeks yang tercetak adalah 1.