Menu

Fungsi di C: deklarasi, pemanggilan, dan nilai kembalian

Cara mendefinisikan dan memanggil fungsi di C: tipe kembalian, parameter, nilai kembalian, fungsi void, kenapa memecah program itu penting, dan contoh lengkap yang dibangun dari bagian kecil yang diberi nama.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Kenapa perlu fungsi

Sejauh ini semuanya ada di dalam main. Itu masih jalan selama program hanya melakukan satu hal. Begitu lebih dari itu, tiga masalah datang sekaligus: blok kode yang sama tersalin ke tiga tempat, main jadi terlalu panjang untuk diingat, dan tidak ada cara untuk memberi nama tujuan sepotong kode.

Fungsi menyelesaikan ketiganya. Fungsi memberi nama pada sebuah blok kode, variabel lokalnya sendiri, daftar input, dan satu nilai untuk dikembalikan.

square ditulis sekali dan dipanggil tiga kali, termasuk sekali pada hasilnya sendiri. Sebenarnya kamu sudah memanggil fungsi dari tadi: printf adalah fungsi, begitu juga main.

Anatomi sebuah fungsi

returnType name(parameterList) {
    // body
    return value;
}

Ada empat bagian:

  • Tipe kembalian: tipe nilai yang dikembalikan fungsi. Bisa int, double, char, tipe pointer, atau void untuk "tidak ada".
  • Nama: aturannya sama dengan nama variabel, dan sebaiknya menjelaskan apa yang fungsi lakukan atau hasilkan.
  • Daftar parameter: input-inputnya, masing-masing dengan tipenya sendiri, dipisahkan koma. (void) berarti fungsi tidak menerima input.
  • Badan fungsi: pernyataan-pernyataan di dalam kurung kurawal, diakhiri return kecuali tipe kembaliannya void.

Perhatikan bahwa pi() tetap butuh tanda kurung kosong saat dipanggil: itulah yang membuatnya jadi pemanggilan, bukan sekadar menyebut namanya. Lalu printBanner(20); berdiri sendiri sebagai pernyataan, karena tidak menghasilkan nilai yang bisa dipakai.

Tulis (void), bukan (), untuk fungsi tanpa parameter. Di C keduanya berarti hal yang berbeda, dan () adalah versi yang longgar. Penjelasannya sebentar lagi.

Memanggil dan mengembalikan nilai

Pemanggilan memindahkan kendali ke dalam fungsi, menjalankan badannya, lalu kembali membawa nilai yang menggantikan pemanggilan itu di ekspresi sekitarnya.

return melakukan dua hal sekaligus: memberikan nilai dan langsung mengakhiri fungsi di tempat itu. Apa pun setelah return di jalur yang sama tidak pernah dijalankan. Karena itulah gaya return lebih awal di larger bisa bekerja: else tidak diperlukan, karena sampai di baris terakhir sudah berarti a > b bernilai salah.

Satu fungsi boleh punya beberapa pernyataan return, tapi dalam satu pemanggilan hanya satu yang dijalankan.

Fungsi void

Fungsi yang ada untuk efeknya, bukan nilainya, punya tipe kembalian void: mencetak, mengubah sesuatu lewat pointer, menggambar.

Di dalam fungsi void, return; tanpa nilai berarti keluar lebih awal. return someValue; di sana adalah error kompilasi, begitu juga memakai pemanggilannya di dalam ekspresi: int x = printTable(7, 5); tidak akan bisa dikompilasi, dan itu memang tugas sistem tipe.

Dekomposisi: inti sebenarnya

Fungsi bukan terutama soal menghindari pengulangan. Fungsi itu soal mengubah satu prosedur panjang menjadi beberapa langkah yang diberi nama, sehingga main terbaca seperti deskripsi program, bukan implementasinya.

Sekarang main hanya berisi empat baris output dan satu perhitungan. Setiap fungsi pembantu melakukan satu hal, punya nama yang menjelaskan hal itu, dan bisa diuji sendiri. Perhatikan bahwa panjang array dikirim sebagai parameter kedua: begitu array dikirim ke sebuah fungsi, trik sizeof tidak lagi bekerja di sana, karena array berubah (decay) menjadi pointer.

Tiga pedoman untuk membagi pekerjaan ke dalam fungsi:

  • Satu tugas per fungsi. Kalau namanya butuh kata "dan", kemungkinan itu sebenarnya dua fungsi.
  • Terima yang kamu butuhkan, kembalikan yang kamu hasilkan. Fungsi yang membaca state global lebih sulit dipahami dan tidak mungkin diuji secara terpisah.
  • Cukup pendek untuk dilihat sekaligus. Tidak ada jumlah baris ajaib, tapi fungsi yang tidak muat di satu layar biasanya menyembunyikan fungsi yang lebih kecil di dalamnya.

Fungsi yang memanggil fungsi lain

Sebuah fungsi bisa memanggil fungsi apa pun yang sudah dideklarasikan, termasuk fungsi yang kamu tulis sendiri:

main memanggil report, yang memanggil sumEvens, yang memanggil isEven di dalam sebuah loop. Setiap pemanggilan mendapat sekumpulan variabel lokal yang baru, ditumpuk di atas milik pemanggilnya, dan dibuang saat fungsi itu selesai.

Definisi di atas disusun sesuai urutan ketergantungan, isEven sebelum sumEvens sebelum report, karena C mengharuskan fungsi dideklarasikan sebelum dipanggil. Panggil fungsi yang letaknya lebih bawah di file, dan compiler akan mengeluh soal deklarasi implisit. Solusi umumnya adalah prototipe di dekat bagian atas file, sehingga kamu bebas mengatur urutan definisi. Fungsi yang memanggil dirinya sendiri juga sah dan berguna; itulah rekursi.

main juga sebuah fungsi

main adalah fungsi biasa yang dipanggil runtime untukmu. Tipe kembaliannya, int, adalah status keluar program: 0 berarti berhasil, selain nol berarti gagal, dan skrip shell serta alat build membacanya.

int main(void) {
    /* ... */
    return 0;
}

Sejak C99, sampai di akhir main tanpa return otomatis mengembalikan 0. Ini aturan khusus yang hanya berlaku untuk main. Setiap fungsi non-void lain yang berakhir tanpa mengembalikan nilai menghasilkan undefined behavior saat pemanggil memakai hasilnya.

Bentuk standar lainnya adalah int main(int argc, char *argv[]), yang menerima argumen baris perintah. Keduanya benar; void main() tidak benar, apa pun kata tutorial lama.

Kesalahan umum

  • Lupa return di fungsi non-void. Pemanggil lalu membaca nilai sampah. gcc -Wall akan memberi peringatan.
  • Mendeklarasikan variabel dengan nama yang sama seperti parameter di dalam badan fungsi. Variabel itu menutupi parameternya, dan penugasan yang kamu maksudkan untuk input tidak sampai ke mana-mana.
  • Mengira fungsi bisa mengubah argumennya. C mengirim semuanya berdasarkan nilai (by value), jadi fungsi menerima salinan. void reset(int x) { x = 0; } tidak mengubah apa pun di tempat pemanggilan. Ini topik halaman berikutnya.
  • Tidak menulis tanda kurung saat memanggil. printBanner; adalah ekspresi sah yang menghitung alamat fungsi lalu membuangnya. Kode itu bisa dikompilasi, tidak melakukan apa-apa, dan -Wall menandainya.
  • Menulis () alih-alih (void). Sah, tapi mematikan pemeriksaan argumen di dialek C yang lebih lama.

Pertanyaan yang sering diajukan

Bagaimana cara mendeklarasikan fungsi di C?

Tulis tipe kembalian, nama, dan daftar parameter di dalam tanda kurung, lalu badan fungsi di dalam kurung kurawal: int add(int a, int b) { return a + b; }. Fungsi yang tidak menerima apa pun memakai (void), dan fungsi yang tidak mengembalikan apa pun punya tipe kembalian void.

Apa fungsi return di dalam fungsi C?

Return langsung mengakhiri fungsi dan menyerahkan sebuah nilai ke pemanggil. Tipe nilai itu harus cocok dengan tipe kembalian yang dideklarasikan fungsi. Di fungsi void kamu bisa menulis return; saja untuk keluar lebih awal, atau tidak menulisnya sama sekali dan membiarkan fungsi berakhir di kurung kurawal penutup.

Kenapa main di C mengembalikan int?

Nilai kembalian main adalah status keluar program, yang bisa dibaca sistem operasi dan skrip shell. return 0; berarti berhasil dan nilai selain nol berarti gagal. Sejak C99, sampai di akhir main tanpa pernyataan return otomatis mengembalikan 0.

Bisakah fungsi C mengembalikan lebih dari satu nilai?

Tidak secara langsung: return menghasilkan tepat satu nilai. Cara yang biasa dipakai adalah mengembalikan struct yang berisi beberapa field, atau mengirim pointer sebagai parameter lalu membiarkan fungsi menulis hasil tambahannya lewat pointer itu.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai