Saat compiler C membaca source dari atas ke bawah, compiler perlu mengetahui signature sebuah fungsi sebelum fungsi tersebut dipanggil. Tanpa informasi itu, compiler tidak dapat memeriksa kesesuaian tipe argument atau jumlah parameter, dan akan mengeluarkan error. Function declaration (juga disebut prototype) adalah cara kita memberitahu compiler tentang nama fungsi, return type, dan daftar parameter—sebelum definisi lengkap fungsi tersebut ditulis. Pada chapter ini kita akan menelusuri bentuk umum deklarasi, perbedaan deklarasi vs definisi, serta jebakan implicit declaration yang sering menjebak pemula.

Bentuk Umum Function Declaration #

Sebuah function declaration memiliki bentuk:

text
return_type nama_fungsi(tipe_parameter1, tipe_parameter2, ...);

Yang membedakan deklarasi dengan definisi adalah titik koma di akhir—deklarasi tidak memiliki body { }. Nama parameter boleh ditulis atau dihilangkan; compiler hanya peduli pada tipe. Contoh berikut menunjukkan deklarasi yang ditempatkan di atas main, sementara definisi fungsi berada di bawah main.

c
#include <stdio.h>

/* Function declaration (prototype) - memberitahu compiler signature */
int kuadrat(int x);

int main(void) {
    int n = 6;
    int hasil = kuadrat(n);
    printf("Kuadrat dari %d adalah %d\n", n, hasil);
    return 0;
}

/* Function definition - implementasi sebenarnya */
int kuadrat(int x) {
    return x * x;
}

Output yang Dihasilkan:

text
Kuadrat dari 6 adalah 36

Mari kita telaah baris-baris kode di atas:

  1. Baris 4 (int kuadrat(int x);): function declaration (prototype). Titik koma di akhir menandakan bahwa baris ini hanya memberitahu compiler signature kuadrat, bukan mendefinisikannya.
  2. Baris 6 (int main(void)): titik awal eksekusi. Compiler sudah tahu bahwa kuadrat(int) ada karena deklarasi pada baris 4 sudah dibaca sebelumnya.
  3. Baris 8 (int hasil = kuadrat(n);): pemanggilan fungsi. Compiler memverifikasi bahwa argument n bertipe int cocok dengan parameter int x pada deklarasi—jika tidak cocok, compiler akan mengeluarkan warning atau error.
  4. Baris 13 (int kuadrat(int x)): function definition. Di sinilah body fungsi kuadrat benar-benar ditulis. Tanda kurawal { } mengawali dan mengakhiri body.
  5. Baris 14 (return x * x;): implementasi fungsi—mengembalikan kuadrat dari x.

Declaration vs Definition #

Perbedaan utama antara deklarasi dan definisi di C:

  • Declaration memberitahu compiler bahwa sebuah fungsi ada, beserta signature-nya. Declaration tidak mengalokasikan memori untuk fungsi.
  • Definition menyediakan body fungsi—kode aktual yang akan dikompilasi menjadi instruksi mesin. Definition sekaligus berperan sebagai declaration.

Satu fungsi boleh dideklarasikan berkali-kali (selama signature-nya konsisten), tetapi hanya boleh didefinisikan satu kali dalam seluruh program (One Definition Rule). Pada program besar yang terbagi ke banyak file .c, deklarasi biasanya ditempatkan di file header (.h) yang di-#include oleh beberapa file .c, sementara definisi ditulis di satu file .c saja.

Contoh Multi-File dengan Header #

Kita akan membuat tiga file: matematika.h berisi deklarasi, matematika.c berisi definisi, dan main.c yang memanggil fungsi-fungsi tersebut.

matematika.h:

c
#ifndef MATEMATIKA_H
#define MATEMATIKA_H

/* Deklarasi fungsi (prototype) */
int kuadrat(int x);
int pangkat_tiga(int x);
double rata_rata(int a, int b, int c);

#endif

matematika.c:

c
#include "matematika.h"

/* Definisi fungsi */
int kuadrat(int x) {
    return x * x;
}

int pangkat_tiga(int x) {
    return x * x * x;
}

double rata_rata(int a, int b, int c) {
    return (a + b + c) / 3.0;
}

main.c:

c
#include <stdio.h>
#include "matematika.h"

int main(void) {
    printf("kuadrat(5)     = %d\n", kuadrat(5));
    printf("pangkat_tiga(4)= %d\n", pangkat_tiga(4));
    printf("rata_rata(70, 80, 90) = %.2f\n", rata_rata(70, 80, 90));
    return 0;
}

Compile ketiga file dengan satu perintah:

bash
gcc -std=c11 -Wall -Wextra matematika.c main.c -o demo_multi
./demo_multi

Output yang Dihasilkan:

text
kuadrat(5)     = 25
pangkat_tiga(4)= 64
rata_rata(70, 80, 90) = 80.00

File matematika.h berperan sebagai “kontrak publik”: setiap file .c yang meng-#include header tersebut tahu signature fungsi kuadrat, pangkat_tiga, dan rata_rata tanpa perlu melihat implementasinya. File matematika.c adalah satu-satunya tempat definisi fungsi tersebut ditulis. Pemisahan ini membuat kode lebih modular dan kompilasi lebih cepat karena perubahan di file .c tidak memaksa file .c lain untuk di-compile ulang.

Jebakan Implicit Declaration #

Bila kita memanggil fungsi yang belum dideklarasikan sama sekali, compiler modern akan menolak kompilasi. Pada C89 era lama, compiler justru mengasumsikan signature default int f() (implicit declaration)—perilaku berbahaya yang akhirnya dihapus dari standar C99 dan kini menjadi hard error di C11/C23.

c
#include <stdio.h>

int main(void) {
    /* Memanggil fungsi tanpa deklarasi sebelumnya */
    int hasil = hitung_qty(7);  /* tidak dideklarasikan di sini */
    printf("Hasil: %d\n", hasil);
    return 0;
}

int hitung_qty(int x) {
    return x + 10;
}

Output compiler (kode sengaja dipublikasikan untuk menunjukkan galat):

text
test_decl3_implicit.c: In function 'main':
test_decl3_implicit.c:5:17: error: implicit declaration of function 'hitung_qty' [-Wimplicit-function-declaration]
    5 |     int hasil = hitung_qty(7);  /* tidak dideklarasikan di sini */
      |                 ^~~~~~~~~~

Compiler menolak melanjutkan kompilasi karena hitung_qty tidak dikenal pada baris 5. Solusinya adalah menambahkan deklarasi int hitung_qty(int x); sebelum main, atau memindahkan definisi hitung_qty ke atas main.

Dengan pondasi deklarasi ini, chapter berikutnya akan membahas function definition secara lebih rinci—termasuk aturan penulisan body, parameter, dan return statement.