Menu

Parameter Fungsi C++: Pass by Value, Reference, Const

Cara argumen masuk ke fungsi C++: pass by value vs pass by reference, referensi const untuk akses read-only yang murah, argumen default, pointer, dan jebakan biaya salinan yang diam-diam memperlambat program.

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

Parameter vs Argumen

Parameter sebuah fungsi adalah variabel bernama di definisinya; argumen adalah nilai sebenarnya yang kamu berikan saat memanggilnya. Halaman sebelumnya menunjukkan cara mendefinisikan dan memanggil fungsi. Halaman ini membahas bagaimana nilai-nilai itu benar-benar masuk, karena C++ menyediakan beberapa cara dan pilihanmu memengaruhi kebenaran sekaligus kecepatan program.

Default di C++ adalah pass by value: fungsi menerima sebuah salinan.

Di dalam addTen, n adalah variabel terpisah yang diinisialisasi dari score. Mengisi ulang n hanya menyentuh salinan itu, jadi score di main tetap utuh. Cara ini aman dan bisa ditebak: fungsi tidak bisa tidak sengaja merusak datamu, dan justru karena itulah cara ini menjadi default.

Pass by Reference: Membiarkan Fungsi Mengubah Milik Pemanggil

Kadang kamu ingin fungsi mengubah variabel milik pemanggil. Tambahkan & pada tipe parameternya, dan parameter itu menjadi referensi: alias untuk variabel aslinya, bukan salinan:

Satu-satunya perbedaan dari contoh pertama adalah &, tetapi sekarang n dan score adalah objek yang sama. Ini cara standar untuk "mengembalikan" lebih dari satu nilai atau memperbarui sesuatu di tempat. Pemakaian klasiknya adalah menukar dua variabel:

Tanpa &, swapValues akan menukar dua salinan dan main tidak akan melihat perubahan apa pun. Ini bug pemula yang sangat umum.

Referensi Const: Akses Read-Only yang Murah

Pass by value menyalin argumen. Untuk int biayanya nol, tetapi menyalin string atau vector yang besar di setiap pemanggilan adalah kerja sia-sia yang nyata. Solusinya adalah referensi const (const T&): kamu mendapat kecepatan referensi (tanpa salinan) plus janji yang ditegakkan compiler bahwa argumen tidak akan diubah.

Patokan yang praktis: kirim tipe bawaan yang kecil (int, double, char, bool, pointer) by value, dan kirim objek besar yang hanya perlu kamu baca lewat referensi const. Simpan T& non-const biasa untuk kasus ketika kamu memang berniat mengubah objek milik pemanggil.

Jebakan yang halus: int& n biasa tidak bisa mengikat nilai sementara atau literal. addTen(5) dari contoh pertama akan gagal dikompilasi kalau parameternya int&, karena 5 bukan variabel yang bisa dijadikan alias. const int& bisa mengikat 5, satu alasan lagi kenapa referensi const begitu banyak dipakai.

Argumen Default

Kamu bisa memberi parameter nilai cadangan sehingga pemanggil boleh tidak menuliskannya. Kalau argumennya tidak ada, nilai default yang dipakai:

Dua aturan sering menjebak. Pertama, nilai default harus berada di belakang: begitu satu parameter punya nilai default, setiap parameter sesudahnya juga harus punya. Kamu tidak bisa menulis void f(int a = 1, int b) karena tidak ada cara memberikan b sambil melewati a. Kedua, kalau fungsi dideklarasikan di header dan didefinisikan di tempat lain, tulis nilai default hanya di deklarasi, jangan pernah mengulangnya di definisi, karena mengulangnya adalah compile error.

Mengirim Array dan Vector

Array mentah meluruh menjadi pointer saat dikirim, sehingga fungsi kehilangan informasi ukurannya. Kamu hampir selalu mengirim panjangnya bersama array itu:

Karena array berubah menjadi pointer, sizeof(arr) di dalam sum akan memberikan ukuran pointer, bukan ukuran array. Ini bug yang terkenal. Di C++ modern, utamakan std::vector (atau std::span di C++20) yang dikirim lewat referensi const, yang membawa ukurannya sendiri:

Perhatikan const&-nya: hilangkan itu, dan setiap pemanggilan menyalin seluruh vector. Untuk vector berisi empat elemen itu tidak masalah, tetapi untuk sejuta elemen itu jadi penguras performa yang diam-diam.

Parameter Pointer

Kamu juga bisa mengirim pointer (T*). Seperti referensi, ini membuat fungsi bisa menjangkau data milik pemanggil, tetapi pointer bisa diarahkan ulang atau bernilai null. Karena itu pointer adalah alat yang tepat saat "tidak ada nilai" adalah pilihan yang sah:

Pemanggil mengirim &value untuk berbagi alamatnya, dan fungsi menulis lewat *out. Perbedaan utamanya dari referensi: pointer bisa bernilai nullptr, jadi fungsi yang menerimanya sebaiknya mengecek dulu sebelum melakukan dereference. Melewatkan pengecekan itu lalu melakukan dereference pada null pointer adalah undefined behavior, biasanya berakhir crash. Kalau "tidak ada nilai" tidak pernah masuk akal, referensi lebih rapi karena sejak awal ia tidak bisa null.

Berikutnya: Referensi

Parameter adalah tempat referensi paling terasa manfaatnya, tetapi referensi adalah fitur tersendiri: alias yang bisa kamu buat untuk variabel apa pun, tidak hanya di dalam signature fungsi. Halaman berikutnya membahas cara kerja referensi secara mandiri: cara mendeklarasikannya, kenapa ia harus langsung diinisialisasi, perbedaan antara lvalue reference dan referensi const, serta cara-cara halus sebuah referensi bisa berakhir dangling.

Pertanyaan yang sering diajukan

Apa perbedaan pass by value dan pass by reference di C++?

Pass by value menyalin argumen ke parameter, jadi perubahan di dalam fungsi tidak memengaruhi pemanggil. Pass by reference (int&) menjadikan parameter sebagai alias untuk variabel milik pemanggil, jadi perubahannya terlihat di luar. Pakai void f(int x) untuk menyalin dan void f(int& x) untuk mengubah nilai aslinya.

Kapan sebaiknya memakai parameter referensi const di C++?

Pakai const T& saat kamu ingin membaca objek besar tanpa menyalinnya dan tanpa membiarkan fungsi mengubahnya, misalnya void print(const string& s). Cara ini memberimu kecepatan pass by reference dengan keamanan pass by value. Untuk tipe kecil seperti int atau char, pass by value biasa sama cepatnya.

Apa itu argumen default di C++?

Argumen default membuat sebuah parameter memakai nilai cadangan saat pemanggil tidak memberikannya, misalnya void greet(string name = "there"). Nilai default harus berada di parameter paling belakang (paling kanan), dan kamu hanya menuliskannya di deklarasi, bukan di definisi, kalau keduanya terpisah.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai