Dalam pembahasan fungsi, dua istilah yang sering dipertukarkan adalah parameter dan argument. Padahal keduanya merujuk pada konsep yang berbeda: parameter adalah variabel yang dideklarasikan pada definisi fungsi (sisi penerima), sedangkan argument adalah nilai aktual yang dilewatkan pemanggil saat memanggil fungsi (sisi pengirim). Membedakan kedua istilah ini penting karena beberapa aturan C—seperti default argument promotions dan konversi tipe—hanya berlaku pada argument, bukan pada parameter. Pada chapter ini kita akan menelusuri mekanisme parameter, promosi tipe default, serta cara melewatkan array sebagai argument.

Parameter Formal vs Argument Aktual #

Dalam literatur C, kita sering menemukan istilah formal parameter (parameter formal) dan actual argument (argument aktual). Parameter formal adalah variabel yang muncul di header definisi fungsi—variabel ini hanya hidup selama fungsi dieksekusi. Argument aktual adalah nilai (atau ekspresi) yang dilewatkan pemanggil pada titik pemanggilan; nilai tersebut dipetakan ke parameter formal sesuai urutan.

c
#include <stdio.h>

/* Parameter formal: a, b, c */
int jumlah_tiga(int a, int b, int c) {
    return a + b + c;
}

int main(void) {
    int x = 5, y = 10, z = 15;
    /* Argument aktual: x, y, z yang dilewatkan saat pemanggilan */
    int total = jumlah_tiga(x, y, z);
    printf("Total: %d\n", total);

    /* Boleh juga melewatkan literal atau ekspresi sebagai argument */
    int total2 = jumlah_tiga(1, 2, 3) + jumlah_tiga(4, 5, 6);
    printf("Total gabungan: %d\n", total2);
    return 0;
}

Output yang Dihasilkan:

text
Total: 30
Total gabungan: 21

Mari kita telaah baris-baris kode di atas:

  1. Baris 4 (int jumlah_tiga(int a, int b, int c)): parameter formal adalah a, b, dan c, ketiganya bertipe int. Parameter formal ini hanya hidup selama pemanggilan fungsi; setelah fungsi selesai, variabel-variabel tersebut hilang.
  2. Baris 9 (int total = jumlah_tiga(x, y, z);): argument aktual adalah x, y, z (variabel lokal di main). Nilai x (yaitu 5) dipetakan ke a, y (10) ke b, z (15) ke c. Pemetaan dilakukan berdasarkan urutan posisi, bukan nama.
  3. Baris 13 (int total2 = jumlah_tiga(1, 2, 3) + jumlah_tiga(4, 5, 6);): argument aktual tidak harus berupa variabel—literal 1, 2, 3 juga valid. Bahkan hasil pemanggilan fungsi (yang mengembalikan int) dapat dipakai sebagai operand + di sisi kanan assignment.

Default Argument Promotions #

Saat melewatkan argument ke fungsi yang belum diprototype-kan secara penuh (misalnya gaya K&R atau fungsi variadic), compiler C menerapkan default argument promotions:

  1. float dipromosikan menjadi double.
  2. char, short, dan tipe integer kecil lainnya dipromosikan menjadi int (atau unsigned int bila int tidak dapat menampung semua nilai).

Walaupun pada pemanggilan fungsi dengan prototype lengkap promosi ini umumnya tidak terjadi (karena compiler tahu tipe parameter), promosi tetap berlaku untuk argumen di bawah ... pada fungsi variadic. Inilah sebabnya %f pada printf menerima float maupun double—keduanya diperlakukan sebagai double di sisi penerima.

c
#include <stdio.h>

/* Promosi tipe default: float -> double, char/short -> int */
void cetak_info(double d, int i) {
    printf("double = %.3f, int = %d\n", d, i);
}

int main(void) {
    /* float otomatis dipromosikan ke double */
    float pi = 3.14159f;
    /* char dan short otomatis dipromosikan ke int */
    char kategori = 7;
    short kode = 42;

    cetak_info(pi, kategori);
    cetak_info(2.71f, kode);
    return 0;
}

Output yang Dihasilkan:

text
double = 3.142, int = 7
double = 2.710, int = 42

Pada contoh di atas, argument pi bertipe float dikonversi ke double sebelum diterima parameter d. Argument kategori bertipe char dikonversi ke int. Karena fungsi cetak_info punya prototype lengkap, compiler dapat menjalankan konversi ini secara aman—bila tipe tidak kompatibel, compiler akan mengeluarkan warning.

Melewatkan Array sebagai Argument #

Array di C tidak dapat dilewatkan “secara nilai” (menyalin seluruh elemen). Yang sebenarnya dilewatkan adalah pointer ke elemen pertama array—sebuah decay dari int[5] menjadi int *. Karena itu, fungsi yang menerima array juga biasanya menerima parameter terpisah berupa jumlah elemen.

c
#include <stdio.h>

/* Parameter array: ukuran dikirim terpisah */
int jumlah_array(const int arr[], int n) {
    int total = 0;
    for (int i = 0; i < n; i++) {
        total += arr[i];
    }
    return total;
}

int main(void) {
    int data[] = {10, 20, 30, 40, 50};
    int n = sizeof(data) / sizeof(data[0]);
    int total = jumlah_array(data, n);
    printf("Total array: %d\n", total);

    /* Argument berupa ekspresi kompleks */
    int total2 = jumlah_array(data, n) - jumlah_array(data, 2);
    printf("Total setelah dikurangi: %d\n", total2);
    return 0;
}

Output yang Dihasilkan:

text
Total array: 150
Total setelah dikurangi: 120

Pada contoh di atas, parameter arr ditulis sebagai const int arr[], tetapi pada kenyataannya compiler mengubah notasi ini menjadi const int *arr. Notasi [] di parameter hanyalah gula sintaksis untuk menyatakan bahwa fungsi menerima pointer. Karena itu, sizeof(arr) di dalam fungsi akan menghasilkan ukuran pointer (8 byte pada x86-64), bukan ukuran array asli—alasan utama mengapa jumlah elemen n harus dilewatkan secara terpisah.

Argument Berupa Ekspresi #

Argument aktual tidak terbatas pada variabel atau literal—segala ekspresi yang menghasilkan tipe kompatibel dapat dipakai sebagai argument. Misalnya jumlah_tiga(x+1, y*2, jumlah_tiga(z, 0, 0)) adalah pemanggilan valid yang melewatkan hasil ekspresi x+1, y*2, dan pemanggilan rekursif jumlah_tiga(z, 0, 0) sebagai argument. Urutan evaluasi argument tidak dijamin oleh standar C (kecuali ada sequence point), sehingga hindari menulis argument dengan side effect yang saling bergantung, misalnya f(i++, i++)—perilaku seperti itu undefined behavior dan akan dibahas lebih jauh pada chapter ekspresi.

Dengan pemahaman parameter dan argument ini, kita siap melangkah ke chapter Return Value untuk membahas bagaimana fungsi mengirim hasil balik ke pemanggil—baik melalui nilai langsung maupun melalui pointer output.