IF221106 · Algoritma dan Pemrograman
Pertemuan 12–14 — Fungsi dalam Bahasa C
Eka Prakarsa Mandyartha, ST., M.Kom.
Prodi Informatika · UPN Veteran Jawa Timur
Materi Kuliah · Pertemuan 12 – 14
Fungsi
Pemrograman Modular dalam Bahasa C
Memecah program menjadi unit-unit kecil yang terkelola — dari pengenalan fungsi, forward & backward declaration, rekursif, hingga pengiriman by value dan by reference.
📄 8 Halaman ⚙ 3 Jenis Deklarasi 💻 Bahasa C
Progres Belajar
Halaman 1 dari 8
Pengantar
Mengapa Fungsi Dibutuhkan?

Bayangkan program kalkulator yang menghitung luas segitiga di 5 tempat berbeda. Tanpa fungsi, rumus 0.5 * alas * tinggi harus ditulis di kelima tempat itu. Jika rumusnya keliru, harus diperbaiki di lima tempat. Dengan fungsi, cukup tulis sekali — perbaiki sekali, berlaku di semua tempat.

Definisi

Fungsi adalah blok kode yang diberi nama, dapat menerima input (parameter), menjalankan serangkaian instruksi, dan mengembalikan output (nilai kembalian). Fungsi dipanggil dari manapun dalam program menggunakan namanya.

Manfaat utama fungsi:

  • Reusability — tulis sekali, panggil berkali-kali dari mana saja
  • Modularitas — program besar dipecah menjadi unit-unit kecil yang mudah dikelola
  • Keterbacaan — nama fungsi menjelaskan apa yang dilakukan blok kode tersebut
  • Kemudahan debug — jika ada bug, cukup periksa satu fungsi, bukan seluruh program
🔗 Sudah kenal sejak hari pertama

main() adalah fungsi pertama yang kita kenal. printf() dan scanf() juga fungsi — hanya saja sudah disediakan oleh pustaka standar C. Di topik ini, kita belajar membuat fungsi kita sendiri.

Anatomi Fungsi
Bagian-bagian Sebuah Fungsi
Struktur Penulisan Fungsi
int hitungLuas(int panjangint lebar) {
    return panjang * lebar;
}
int
Tipe Return
Tipe data nilai yang dikembalikan fungsi. Gunakan void jika tidak mengembalikan nilai.
hitungLuas
Nama Fungsi
Identifier unik untuk memanggil fungsi. Sebaiknya deskriptif dan menggunakan kata kerja.
panjang, lebar
Parameter Formal
Variabel input yang diterima fungsi. Nilainya diisi saat fungsi dipanggil.
return
Nilai Kembalian
Nilai yang dikirimkan kembali ke pemanggil. Tipenya harus cocok dengan tipe return.
Fungsi pertama kita — dengan dan tanpa nilai kembalianC
#include <stdio.h>

/* Fungsi DENGAN nilai kembalian (return type: int) */
int hitungLuas(int panjang, int lebar) {
    return panjang * lebar;   // mengembalikan hasil perkalian
}

/* Fungsi TANPA nilai kembalian (void) */
void cetakGaris() {
    printf("========================\n");
    // tidak ada return (atau: return; tanpa nilai)
}

int main() {
    int luas = hitungLuas(5, 3); // 5 dan 3 = argumen/parameter aktual
    cetakGaris();
    printf("Luas = %d\n", luas);    // Luas = 15
    cetakGaris();
    return 0;
}
Parameter formal vs parameter aktual:
Parameter formal adalah nama variabel di dalam definisi fungsi: int panjang, int lebar.
Parameter aktual (argumen) adalah nilai nyata yang dikirim saat fungsi dipanggil: hitungLuas(5, 3) — di sini 5 dan 3 adalah argumennya.
Jenis Deklarasi 1 dari 3
Fungsi Backward — Definisi Sebelum Pemanggil

Fungsi backward adalah pola di mana fungsi didefinisikan di atas fungsi yang memanggilnya dalam file kode. Disebut "backward" karena fungsi pembantu ditulis lebih awal dari fungsi utama. Ini adalah cara paling sederhana — compiler sudah mengetahui seluruh detail fungsi sebelum menemukannya dipanggil.

Prinsip Kerja Compiler C

Compiler C membaca kode dari atas ke bawah, satu baris per satu baris. Ketika menemukan pemanggilan fungsi, ia harus sudah mengetahui fungsi tersebut — tipe return-nya, nama, dan parameternya. Jika definisi fungsi belum ditemukan saat titik pemanggilan tercapai, compiler akan error.

backward_function.c — fungsi pembantu di atas main()C
#include <stdio.h>

/* ① Definisi fungsi di ATAS main() */
/* Compiler sudah tahu fungsi ini saat membaca main() */

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

float rataRata(int a, int b, int c) {
    return (float)(a + b + c) / 3;
}

void cetakHasil(int n, int hasil) {
    printf("Kuadrat %d = %d\n", n, hasil);
}

/* ② main() dipanggil TERAKHIR — semua fungsi sudah dikenal */
int main() {
    int n = 7;
    int k = kuadrat(n);         // ✓ compiler sudah kenal kuadrat()
    cetakHasil(n, k);            // ✓ compiler sudah kenal cetakHasil()

    float avg = rataRata(80, 90, 70);
    printf("Rata-rata = %.1f\n", avg);
    return 0;
}
/* Output:
   Kuadrat 7 = 49
   Rata-rata = 80.0   */
Urutan Pembacaan Compiler
1
Baca kuadrat() → simpan: "ada fungsi bernama kuadrat, return int, terima int x"
2
Baca rataRata() → simpan: "ada fungsi bernama rataRata, return float, terima 3 int"
3
Baca cetakHasil() → simpan: "ada fungsi bernama cetakHasil, void, terima 2 int"
4
Baca main() → menemukan kuadrat(n) → ✓ sudah dikenal → OK
💡 Kapan pakai backward: Cocok untuk program kecil–menengah. Urutan penulisan bergantung pada urutan ketergantungan — fungsi yang digunakan oleh fungsi lain ditulis lebih atas.
Jenis Deklarasi 2 dari 3
Fungsi Forward — main() Ditulis Dulu, Fungsi Lain di Bawah

Fungsi forward adalah pola di mana main() atau fungsi pemanggil ditulis di atas, sedangkan definisi fungsi yang dipanggil berada di bawahnya. Nama "forward" merujuk pada forward declaration (prototipe) — deklarasi pendahulu yang memberitahu compiler tentang keberadaan fungsi sebelum definisi lengkapnya ditemukan.

⚠ Tanpa prototipe — ERROR!
Jika main() memanggil fungsi yang belum dikenal compiler (definisinya ada di bawah dan tidak ada prototipe), compiler akan mengeluarkan warning atau error: "implicit declaration of function" atau "undefined reference".
Solusi Wajib
Prototipe Fungsi (Function Prototype)

Prototipe adalah deklarasi singkat yang hanya memberitahu compiler: "akan ada fungsi dengan nama, tipe return, dan parameter seperti ini." Prototipe ditulis di atas sebelum main(), sedangkan definisi lengkapnya bisa di mana saja sesudah itu.

❌ TANPA prototipe — ERROR
#include <stdio.h>

/* TIDAK ada prototipe */

int main() {
    /* kuadrat() belum dikenal! */
    int k = kuadrat(5);
    printf("%d\n", k);
    return 0;
}

/* definisi ada di bawah */
int kuadrat(int x) {
    return x * x;
}
error: implicit declaration
of function 'kuadrat'
✅ DENGAN prototipe — OK
#include <stdio.h>

/* ① PROTOTIPE — deklarasi pendahulu */
int kuadrat(int x);

int main() {
    /* kuadrat() sudah dikenal! */
    int k = kuadrat(5);
    printf("%d\n", k);   // 25
    return 0;
}

/* ② Definisi lengkap di bawah */
int kuadrat(int x) {
    return x * x;
}
Output: 25 ✓
forward_function.c — pola lengkap dengan banyak prototipeC
#include <stdio.h>
#include <math.h>

/* ============================================
   PROTOTIPE — semua fungsi dideklarasikan di atas
   Sintaks: tipe_return nama_fungsi(tipe param, ...);
   ============================================ */
int    kuadrat(int x);
float  luasLingkaran(float r);
void   cetakHeader(char *judul);
int    faktorial(int n);

/* ============================================
   main() — bisa langsung gunakan semua fungsi
   ============================================ */
int main() {
    cetakHeader("KALKULATOR SEDERHANA");

    printf("Kuadrat 8    = %d\n",   kuadrat(8));
    printf("Luas r=7     = %.2f\n", luasLingkaran(7));
    printf("Faktorial 5  = %d\n",   faktorial(5));
    return 0;
}

/* ============================================
   DEFINISI LENGKAP — bisa ditulis di mana saja
   (bahkan di file .c terpisah)
   ============================================ */
int kuadrat(int x) {
    return x * x;
}

float luasLingkaran(float r) {
    return 3.14159 * r * r;
}

void cetakHeader(char *judul) {
    printf("===== %s =====\n", judul);
}

int faktorial(int n) {
    if (n <= 1) return 1;
    return n * faktorial(n - 1);
}
/* Output:
   ===== KALKULATOR SEDERHANA =====
   Kuadrat 8    = 64
   Luas r=7     = 153.94
   Faktorial 5  = 120                */
Perbedaan Prototipe vs Definisi
PROTOTIPE (deklarasi)
int kuadrat(int x);
Hanya "janji" ke compiler. Tidak ada badan. Diakhiri titik koma. Nama parameter boleh dihilangkan: int kuadrat(int);
DEFINISI (implementasi)
int kuadrat(int x) {
  return x*x;
}
Implementasi lengkap. Ada badan {}. Tidak diakhiri titik koma. Hanya ada satu definisi per fungsi.
💡 Mengapa forward lebih umum digunakan profesional? Dalam proyek nyata, prototipe dikumpulkan di file .h (header file), sedangkan definisi di file .c terpisah. Dengan begitu, fungsi bisa dibagi-pakai antar banyak file sumber tanpa menduplikasi kode.
Jenis Deklarasi 3 dari 3
Fungsi Rekursif — Fungsi yang Memanggil Dirinya Sendiri

Rekursif adalah teknik di mana sebuah fungsi memanggil dirinya sendiri untuk menyelesaikan masalah yang lebih kecil. Setiap pemanggilan menyelesaikan sebagian masalah, lalu meneruskan sisa masalah ke dirinya sendiri dengan input yang lebih sederhana, hingga mencapai kondisi berhenti.

Dua Komponen Wajib Rekursif

① Base case (kondisi dasar) — kondisi berhenti yang menghentikan rekursif. Tanpa ini, fungsi memanggil dirinya selamanya (stack overflow!).

② Recursive case — pemanggilan fungsi itu sendiri dengan argumen yang semakin mendekati base case.

Contoh Klasik — Faktorial
Memahami Rekursif dari Faktorial n!

Faktorial didefinisikan: n! = n × (n-1) × (n-2) × ... × 1, dan 0! = 1 (base case). Sifat ini alami untuk rekursif: n! = n × (n-1)!

Versi Iteratif (dengan loop)
int faktorialLoop(int n) {
    int hasil = 1;
    for(int i=1; i<=n; i++)
        hasil *= i;
    return hasil;
}
// 5! = 1*2*3*4*5 = 120
Versi Rekursif
int faktorial(int n) {
    if (n <= 1)         // base case
        return 1;
    return n * faktorial(n-1);
    // recursive case
}
Jejak Eksekusi: faktorial(5)
faktorial(5)5 * faktorial(4)
  faktorial(4)4 * faktorial(3)
    faktorial(3)3 * faktorial(2)
      faktorial(2)2 * faktorial(1)
        faktorial(1)return 1 ← BASE CASE! berhenti di sini
Fase balik (return naik ke atas):
        faktorial(1) = 1
      faktorial(2) = 2 × 1 = 2
    faktorial(3) = 3 × 2 = 6
  faktorial(4) = 4 × 6 = 24
faktorial(5) = 5 × 24 = 120 ✓
Call Stack: Setiap pemanggilan rekursif membuat frame baru di memori (call stack). Untuk faktorial(5), ada 5 frame aktif sekaligus sebelum base case tercapai. Ini mengapa rekursif terlalu dalam bisa menyebabkan stack overflow.
Contoh Rekursif Lain
Fibonacci dan Pangkat
rekursif.c — fibonacci dan pangkatC
#include <stdio.h>

/* Fibonacci: fib(n) = fib(n-1) + fib(n-2) */
/* Base case: fib(0)=0, fib(1)=1           */
int fibonacci(int n) {
    if (n == 0) return 0;   // base case 1
    if (n == 1) return 1;   // base case 2
    return fibonacci(n-1) + fibonacci(n-2); // recursive
}

/* Pangkat: pangkat(base, exp) = base * pangkat(base, exp-1) */
int pangkat(int base, int exp) {
    if (exp == 0) return 1;             // base case: x^0 = 1
    return base * pangkat(base, exp-1); // recursive
}

int main() {
    printf("Fibonacci ke-8 = %d\n", fibonacci(8)); // 21

    printf("Deret Fibonacci: ");
    for(int i=0; i<10; i++)
        printf("%d ", fibonacci(i)); // 0 1 1 2 3 5 8 13 21 34
    printf("\n");

    printf("2^10 = %d\n", pangkat(2, 10)); // 1024
    return 0;
}
⚠ Perhatian fibonacci rekursif: fibonacci(n) rekursif murni sangat tidak efisien — fibonacci(40) melakukan sekitar 300 juta pemanggilan! Untuk nilai besar, gunakan pendekatan iteratif atau memoization. Fungsi fibonacci di sini bertujuan menunjukkan konsep, bukan untuk produksi.
⚠ Stack Overflow — Rekursif Tanpa Base Case: Jika base case tidak pernah tercapai (misalnya karena argumen tidak pernah mengecil), fungsi terus memanggil dirinya hingga memori habis → program crash dengan pesan segmentation fault atau stack overflow.
Cakupan Variabel (Scope)
Variabel Lokal, Global, dan Statis

Tidak semua variabel bisa diakses dari mana saja. Scope (cakupan) menentukan di mana sebuah variabel dapat dilihat dan digunakan. Ini penting dipahami agar tidak terjadi konflik nama dan bug yang susah dilacak.

JenisDideklarasikanDapat diaksesUmur hidup
Lokal Di dalam fungsi atau blok {} Hanya dalam fungsi/blok itu Dibuat saat fungsi dipanggil, dihapus saat fungsi selesai
Global Di luar semua fungsi, biasanya di atas Dari semua fungsi dalam file yang sama Sejak program mulai hingga program berakhir
Statis (lokal) Di dalam fungsi, dengan kata kunci static Hanya dalam fungsi itu Tidak dihapus saat fungsi selesai — nilainya dipertahankan
scope_demo.c — perbedaan lokal, global, statisC
#include <stdio.h>

int hitungan = 0;  /* ← GLOBAL: diakses semua fungsi */

void demoLokal() {
    int x = 10;   /* ← LOKAL: hanya ada di dalam demoLokal() */
    x++;
    printf("Lokal x = %d\n", x);
    /* x dihapus dari memori saat fungsi ini selesai */
}

void demoStatis() {
    static int count = 0;  /* ← STATIS: inisialisasi hanya sekali! */
    count++;
    printf("Static count = %d\n", count);
    /* count TIDAK dihapus saat fungsi selesai */
}

void tambahHitungan() {
    hitungan++;   /* akses variabel global */
}

int main() {
    demoLokal();   // x = 11
    demoLokal();   // x = 11 lagi! x selalu dimulai dari 10

    printf("---\n");
    demoStatis(); // count = 1
    demoStatis(); // count = 2  ← nilai dipertahankan!
    demoStatis(); // count = 3

    printf("---\n");
    tambahHitungan();
    tambahHitungan();
    printf("Global hitungan = %d\n", hitungan); // 2
    return 0;
}
/* Output:
   Lokal x = 11
   Lokal x = 11
   ---
   Static count = 1
   Static count = 2
   Static count = 3
   ---
   Global hitungan = 2   */
Konflik Nama
Ketika Variabel Lokal dan Global Bernama Sama

Jika variabel lokal dan global memiliki nama yang sama, variabel lokal mengalahkan (menutupi) variabel global di dalam fungsi tersebut. Ini disebut variable shadowing dan bisa menyebabkan bug yang sulit dilacak.

shadowing.c — konflik nama variabelC
#include <stdio.h>

int nilai = 100;   /* variabel GLOBAL */

void contohShadow() {
    int nilai = 50;   /* variabel LOKAL — menutupi yang global! */
    printf("Di dalam fungsi: nilai = %d\n", nilai);
    // Ini mencetak 50 (lokal), bukan 100 (global)
}

int main() {
    printf("Di main (sebelum): nilai = %d\n", nilai); // 100
    contohShadow();
    printf("Di main (sesudah): nilai = %d\n", nilai); // 100 — global tidak berubah!
    return 0;
}
⚠ Best practice: Hindari menggunakan nama yang sama untuk variabel lokal dan global. Variabel global sebaiknya diberi awalan tertentu (misal: g_nilai) agar mudah dibedakan dan tidak sengaja ditimpa. Gunakan variabel global secara hemat — lebih banyak gunakan parameter dan return value.
Pengiriman Argumen
By Value vs By Reference — Perbedaan yang Kritis

Ketika memanggil fungsi dengan argumen, ada dua cara nilai dikirim: by value (kirim salinan) atau by reference (kirim alamat aslinya). Pilihan ini menentukan apakah perubahan di dalam fungsi berdampak pada variabel asli di luar fungsi.

Call by Value
Fungsi Menerima SALINAN — variabel asli tidak berubah

Secara default, semua pengiriman argumen di C menggunakan by value. Fungsi menerima salinan nilai, bukan variabel aslinya. Perubahan apapun di dalam fungsi tidak mempengaruhi variabel di pemanggil.

by_value.cC
#include <stdio.h>

void cobaUbah(int x) {   // x adalah SALINAN dari a
    x = x * 10;
    printf("Di dalam fungsi: x = %d\n", x); // 50
    // perubahan pada x tidak memengaruhi variabel luar
}

int main() {
    int a = 5;
    printf("Sebelum: a = %d\n", a);   // 5
    cobaUbah(a);                         // kirim nilai 5, bukan variabel a
    printf("Sesudah: a = %d\n", a);   // 5 — tidak berubah!
    return 0;
}
🔍 Apa yang Terjadi di Memori — By Value
① Sebelum pemanggilan — di main()
int a
5
alamat: 0x1000
salin NILAI (bukan variabelnya)
② Di dalam cobaUbah() — salinan di lokasi berbeda
int x
5
alamat: 0x2000 ← BERBEDA!
x = x * 10 → x berubah jadi 50 di alamat 0x2000
int x
50
alamat: 0x2000
fungsi selesai → x dihapus dari stack
③ Kembali ke main() — a tidak tersentuh sama sekali
int a
5
alamat: 0x1000 ← TIDAK BERUBAH ✓
Call by Reference
Fungsi Menerima ALAMAT — variabel asli BISA diubah

Dengan by reference, yang dikirim ke fungsi bukan nilainya melainkan alamat memori variabel asli (menggunakan pointer). Fungsi langsung memanipulasi variabel asli melalui alamat tersebut.

Sintaks pointer: int *ptr — deklarasi pointer. &a — ambil alamat variabel a. *ptr — akses nilai di alamat tersebut (dereference).

by_reference.cC
#include <stdio.h>

/* Parameter bertipe pointer: int *px */
/* Artinya: px menyimpan ALAMAT variabel int */
void ubahNilai(int *px) {
    *px = *px * 10;   // *px: akses nilai di alamat yang ditunjuk px
    printf("Di dalam: *px = %d\n", *px); // 50
}

/* Fungsi swap klasik — hanya bisa dengan by reference */
void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    int a = 5;
    printf("Sebelum: a = %d\n", a);   // 5
    ubahNilai(&a);                       // kirim ALAMAT a, bukan nilainya
    printf("Sesudah: a = %d\n", a);   // 50 — berubah!

    printf("---\n");
    int x = 10, y = 20;
    printf("Sebelum swap: x=%d y=%d\n", x, y); // 10 20
    swap(&x, &y);
    printf("Sesudah swap: x=%d y=%d\n", x, y); // 20 10
    return 0;
}
🔍 Apa yang Terjadi di Memori — By Reference
① Di main() — variabel asli
int a
5
alamat: 0x1000
kirim ALAMAT 0x1000 (bukan nilainya!)
② Di dalam ubahNilai() — pointer menyimpan alamat
int *px
0x1000
px menyimpan alamat a
*px = *px * 10
→ dereference: langsung akses isi alamat 0x1000
③ Nilai di alamat 0x1000 langsung berubah
int a
50
alamat: 0x1000 ← BERUBAH!
fungsi selesai → kembali ke main()
④ Kembali ke main() — a sudah berubah permanen
int a
50
alamat: 0x1000 ← BERUBAH PERMANEN ✓
Pengiriman Array ke Fungsi
Array Selalu Dikirim By Reference

Ketika array dikirim ke fungsi, yang dikirim bukan salinan seluruh array — melainkan pointer ke elemen pertama (by reference secara implisit). Artinya: perubahan pada array di dalam fungsi akan berdampak pada array asli, berbeda dengan variabel biasa.

array_fungsi.cC
#include <stdio.h>

/* Parameter array: int arr[] atau int *arr — sama saja */
/* Ukuran N dikirim terpisah karena fungsi tidak tahu ukuran array */
void isiArray(int arr[], int n) {
    for(int i=0; i<n; i++)
        arr[i] = i * 10;   // mengubah array ASLI
}

int jumlahArray(int arr[], int n) {
    int total = 0;
    for(int i=0; i<n; i++)
        total += arr[i];
    return total;
}

void cetakArray(int arr[], int n) {
    for(int i=0; i<n; i++)
        printf("%d ", arr[i]);
    printf("\n");
}

int main() {
    int data[5];          // array belum terisi
    isiArray(data, 5);   // isi array melalui fungsi
    cetakArray(data, 5); // 0 10 20 30 40

    printf("Jumlah = %d\n", jumlahArray(data, 5)); // 100
    return 0;
}
⚠ Ukuran array tidak ikut terbawa! Fungsi yang menerima array tidak bisa mengetahui ukurannya secara otomatis. Selalu kirim ukuran array sebagai parameter terpisah (int n), atau gunakan konstanta global.
Ringkasan Perbandingan
Forward, Backward, Rekursif — Kapan Masing-masing Digunakan?
AspekBackwardForwardRekursif
Posisi definisi Di atas pemanggil Di mana saja (ada prototipe) Memanggil dirinya sendiri
Perlu prototipe? Tidak Wajib ada Tidak (tapi bisa pakai)
Cocok untuk Program kecil, fungsi pembantu sederhana Program besar, multi-file, library Masalah yang bisa dipecah menjadi sub-masalah serupa
Kelebihan Sederhana, tidak perlu prototipe Fleksibel, standar profesional Kode elegan untuk masalah rekursif alami
Kekurangan Urutan penulisan bergantung ketergantungan Harus ingat menulis prototipe Boros memori (stack), bisa stack overflow
Contoh kasus Fungsi utilitas, konversi satuan Proyek nyata, header file Faktorial, Fibonacci, traversal pohon
Latihan Terpadu
Kalkulator Modular — Menggabungkan Semua Konsep

Program berikut menggunakan prototipe (forward), variabel lokal, by value, by reference, dan array — semua dalam satu program terstruktur.

kalkulator_modular.cC
#include <stdio.h>
#include <math.h>

/* ===== PROTOTIPE (Forward Declaration) ===== */
int    faktorial(int n);
float  rataRata(int arr[], int n);
void   statistik(int arr[], int n, int *maks, int *min);
void   cetakMenu();

/* ===== PROGRAM UTAMA ===== */
int main() {
    /* Uji faktorial rekursif */
    printf("5! = %d\n", faktorial(5));

    /* Uji array + by reference */
    int data[] = {45, 82, 17, 93, 60};
    int n = 5, maks, min;

    printf("Rata-rata: %.1f\n", rataRata(data, n));

    statistik(data, n, &maks, &min); // by reference
    printf("Maks=%d  Min=%d\n", maks, min);
    return 0;
}

/* ===== DEFINISI FUNGSI ===== */
int faktorial(int n) {         // REKURSIF
    if (n <= 1) return 1;
    return n * faktorial(n-1);
}

float rataRata(int arr[], int n) {  // array by ref implisit
    int total = 0;
    for(int i=0; i<n; i++) total += arr[i];
    return (float)total / n;
}

void statistik(int arr[], int n,
               int *maks, int *min) { // by reference
    *maks = *min = arr[0];
    for(int i=1; i<n; i++) {
        if(arr[i] > *maks) *maks = arr[i];
        if(arr[i] < *min)  *min  = arr[i];
    }
}
/* Output:
   5! = 120
   Rata-rata: 59.4
   Maks=93  Min=17   */
Ringkasan Pertemuan 12 – 14
Yang Telah Kita Pelajari
3
Jenis Deklarasi Fungsi
3
Jenis Variabel (lokal/global/statis)
2
Cara Kirim Argumen (value/ref)
  • Fungsi = blok kode bernama yang dapat dipanggil berulang kali; memiliki tipe return, parameter, dan badan
  • Backward: definisi di atas pemanggil — tidak perlu prototipe, mudah untuk program kecil
  • Forward: main() di atas, definisi di bawah — wajib ada prototipe sebelum main(); standar profesional
  • Rekursif: fungsi memanggil dirinya sendiri; wajib punya base case agar tidak stack overflow
  • Variabel lokal hanya hidup di fungsinya; global hidup sepanjang program; static nilainya dipertahankan antar pemanggilan
  • By value: kirim salinan — variabel asli tidak berubah; by reference: kirim alamat (&var) — variabel asli bisa diubah
  • Array selalu dikirim by reference secara implisit; ukuran array harus dikirim sebagai parameter terpisah
🎓 Selamat!
Anda telah menyelesaikan seluruh topik IF221106 Algoritma dan Pemrograman
Dari Computational Thinking, tipe data, operator, seleksi kondisi, perulangan, array, hingga fungsi — fondasi pemrograman yang solid ini menjadi bekal untuk mata kuliah lanjutan: Struktur Data, Pemrograman Berorientasi Objek, dan Algoritma.