Eksplorasi Fungsi
Pada Bab 5, Anda telah belajar
bagaimana menggunakan fungsi-fungsi penghasil nilai. Pada bab ini, Anda akan
mengeksplorasi fungsi terdefinisi-pengguna secara umum dan, secara khusus,
fungsi yang tidak memiliki tipe data, yang dikenal dengan fungsi kosong.
Fungsi Kosong
Fungsi kosong dan fungsi penghasil
nilai memiliki struktur yang sama. Keduanya memiliki kepala dan tubuh. Seperti
fungsi penghasil nilai, Anda dapat menempatkan fungsi kosong
terdefinisi-pengguna sebelum atau sesudah fungsi main. Namun, eksekusi program selalu diawali dengan statemen
pertama di dalam fungsi main. Jika
Anda menempatkan fungsi kosong terdefinisi-pengguna setelah fungsi main, Anda sebaiknya menempatkan
prototipe fungsi sebelum fungsi main.
Fungsi kosong tidak memiliki tipe data.
Oleh karena itu, tipeFungsi, yaitu
tipe nilai balik, di dalam kepala fungsi dan statemen return di dalam tubuh fungsi kosong tidak ada artinya. Tetapi, di
dalam sebuah fungsi kosong, Anda dapat menggunakan statemen return tanpa nilai, yang secara umum
dipakai untuk keluar dari fungsi. Seperti fungsi penghasil nilai, fungsi kosong
dapat memiliki parameter formal.
Karena fungsi kosong tidak memiliki
tipe data, ia tidak digunakan (dipanggil) di dalam sebuah ekspresi. Pemanggilan
terhadap fungsi kosong merupakan statemen yang berdiri sendiri. Jadi, untuk
memanggil sebuah fungsi kosong, Anda menggunakan nama fungsi disertai dengan
parameter aktual (jika ada) pada suatu statemen yang berdiri sendiri. Sebelum
contoh fungsi kosong disajikan, sebelumnya akan diberika sintaks dari sebuah
fungsi kosong.
Definisi
Fungsi
Definisi fungsi dari fungsi kosong yang
memiliki parameter memiliki sintaks berikut:
void namaFungsi(daftar parameter formal)
{
statemen-statemen
}
dimana di dalamnya statemen-statemen biasanya merupakan statemen deklarasi dan/atau
statemen tereksekusikan (executable).
Daftar parameter format bisa kosong, dan pada kasus itu, kurung kosong tetap
dibutuhkan pada kepala fungsi.
Daftar
Parameter Formal
Daftar parameter formal memiliki
sintaks berikut:
tipeData& variabel, tipeDataa&
variabel, ...
Anda harus menspesifikasi kedua tipe
data dan nama variabel di dalam daftar parameter formal. Simbol & yang ditempatkan setelah tipeData memiliki makna spesial; ia
hanya digunakan untuk parameter formal tertentu dan akan didiskusikan nanti
pada bab ini.
Pemanggilan
Fungsi
Pemanggilan fungsi mempunyai sintaks
berikut:
namaFungsi(daftar
parameter aktual);
Daftar
Parameter Aktual
Daftar parameter aktual mempunyai
sintaks berikut:
ekspresi atau
variabel, ekspresi atau variabel, ...
dimana di dalamnya ekspresi dapat memuat nilai konstanta tunggal. Seperti fungsi
penghasil nilai, pada pemanggilan fungsi, jumlah parameter aktual berikut
dengan tipe datanya masing-masing harus cocok dengan parameter formal dengan
urutan yang sesuai. Parameter aktual dan parameter formal memiliki relasi
satu-ke-satu. Pemanggilan fungsi menyebabkan eksekusi terhadap tubuh fungsi
terpanggil. (Fungsi dengan parameter default akan didiskusikan nanti di akhir
bab ini).
Contoh 6.1 menunjukkan sebuah fungsi
kosong dengan parameter.
Contoh 6.1
|
void fungEksp(int a, double b, char c, int x)
{
.
.
.
}
Fungsi fungEksp memiliki empat parameter.
Parameter memfasilitasi komunikasi
antara fungsi pemanggil (seperti main) dengan fungsi terpanggil. Parameter
memampukan fungsi untuk memanipulasi pelbagai data setiap kali ia dipanggil.
Secara umum, ada dua jenis parameter formal: parameter nilai dan parameter
referensi.
Parameter nilai: Parameter formal
yang menerima sebuah salinan isi dari parameter aktual terkait.
Parameter referensi: Parameter formal
yang menerima lokasi (alamat memori) dari parameter aktual terkait.
Ketika Anda membubuhkan simbol & setelah tipeData di dalam
daftar parameter formal, variabel yang berada setelah tipeData menjadi parameter referensi.
Contoh 6.2 menunjukkan sebuah fungsi
kosong yang memiliki parameter nilai dan parameter referensi.
Contoh 6.2
|
void ekspFung(int satu, int& dua, char
tiga, double& empat)
{
.
.
.
}
Fungsi ekspFung memiliki empat parameter: (1) satu, sebuah parameter nilai bertipe int; (2) dua, sebuah
parameter referensi bertipe int; (3)
tiga, sebuah parameter nilai bertipe
char; dan (4) empat, sebuah parameter referensi bertipe double.
Contoh 6.3
|
Anda akan menuliskan sebuah program
untuk menampilkan pola berikut:
*
* *
* * *
* * * *
Baris pertama memiliki satu bintang
dengan beberapa spasi sebelum bintang, baris kedua memiliki dua bintang,
beberapa spasi sebelum bintang dan sebuah spasi di antara bintang, dan
seterusnya. Selanjutnya, akan dituliskan metode tampilBintang yang memiliki dua parameter, sebuah parameter untuk
menspesifikasi jumlah spasi sebelum bintang pada sebuah baris dan sebuah
parameter kedua untuk menetapkan jumlah bintang pada sebuah baris. Agar lebih
spesifik, definisi atas metode tampilBintang
adalah:
void tampilBintang(int spasi, int bintangPdBaris)
{
int hitung;
//menampilkan jumlah spasi
sebelum bintang pada sebuah baris
for (hitung = 1; hitung <= spasi; hitung++)
cout << ' ';
//menampilkan jumlah bintang
dengan sebuah spasi di antaranya
for (hitung = 1; hitung <= bintangPdBaris; hitung++)
cout << "
*";
cout << endl;
} //akhir tampilBintang
Parameter pertama, spasi, menentukan berapa banyak spasi yang akan ditampilkan sebelum
bintang (atau beberapa bintang); parameter kedua, bintangPdBaris, menentukan berapa banyak bintang yang akan
ditampilkan pada sebuah baris. Jika nilai dari parameter spasi adalah 30, misalnya, maka loop for pertama di dalam metode tampilBintang
akan dieksekusi sebanyak 30 kali dan menampilkan 30 spasi. Juga, karena Anda
ingin menampilkan sebuah spasi di antara bintang, setiap iterasi dari loop for kedua di dalam metode tampilBintang akan menampilkan string “
*”, yaitu sebuah spasi yang diikuti
dengan sebuah bintang.
Selanjutnya, perhatikan beberapa
statemen berikut:
int jumlahBaris = 15;
int jumlahSpasi = 30;
for (kounter = 1; kounter <= jumlahBaris; kounter++)
{
tampilBintang(jumlahSpasi, kounter);
jumlahSpasi--;
}
Loop for memanggil fungsi tampilBintang.
Setiap iterasi dari loop for ini
menspesifikasi jumlah spasi yang diikuti dengan jumlah bintang yang akan
ditampilkan pada sebuah baris, menggunakan variabel jumlahSpasi dan kounter.
Setiap pemanggilan terhadap fungsi tampilBintang
menerima jumlah spasi yang lebih sedikit satu dan jumlah bintang yang lebih
banyak satu dari pemanggilan sebelumnya. Sebagai contoh, iterasi pertama dari
loop for di dalam metode main menetapkan 30 spasi dan 1 bintang
(yang dilewatkan sebagai parameter jumlahSpasi
dan kounter kepada fungsi tampilBintang). Loop for kemudian mendekremen jumlah spasi
sebesar 1 dengan mengeksekusi statemen jumlahSpasi--;. Di akhir loop for,
jumlah bintang diinkremen sebesar 1 untuk iterasi berikutnya. Ini dilakukan
dengan mengeksekusi statemen pembaruan kounter++
di dalam statemen for, yang
menginkremen nilai dari variabel kounter
sebesar 1. Dengan kata lain, pemanggilan kedua terhadap fungsi tampilBintang menerima 29 spasi dan 2
bintang sebagai parameter.
//Program:
Menampilkan pola segitiga bintang
#include <iostream>
using namespace std;
void tampilBintang(int spasi, int bintangPdBaris);
int main()
{
int
jumlahBaris; //variabel untuk
menyimpan jumlah baris
int
kounter; //variabel kendali loop for
int
jumlahSpasi; //variabel untuk
menyimpan jumlah spasi
cout << "Masukkan jumlah baris bintang (1 sampai 20) "
<< "yang akan ditampilkan "; //Baris
1
cin >> jumlahBaris; //Baris 2
while
(jumlahBaris < 0 || jumlahBaris > 20) //Baris
3
{
cout << "Jumlah baris bintang harus "
<< "antara 1 dan 20" << endl; //Baris 4
cout << "Masukkan jumlah baris bintang "
<< "(1 sampai 20) yang akan ditampilkan: "; //Baris 5
cin >> jumlahBaris; //Baris
6
}
cout << endl << endl; //Baris 7
jumlahSpasi = 30; //Baris 8
for
(kounter = 1; kounter <= jumlahBaris; kounter++) //Baris 9
{
tampilBintang(jumlahSpasi, kounter); //Baris 10
jumlahSpasi--; //Baris 11
}
return
0; //Baris
12
}
void tampilBintang(int spasi, int bintangPdBaris)
{
int
hitung;
for
(hitung = 1; hitung <= spasi; hitung++) //Baris
13
cout << ' '; //Baris
14
for
(hitung = 1; hitung <= bintangPdBaris; hitung++) //Baris 15
cout << " * "; //Baris
16
cout << endl;
}
Keluaran Program:
Masukkan jumlah baris bintang (1 sampai 20) yang akan
ditampilkan 15
*
* *
* * *
* *
* *
* *
* * *
* * * *
* *
* *
* * *
* *
* * *
* * *
* *
* * *
* * *
* * *
* * *
* * *
* * * *
* * *
* * *
* * *
* *
* * *
* * *
* * *
* * *
* * *
* * *
* * *
* * * *
* * *
* * *
* * *
* * *
* *
* * *
* * *
* * *
* * *
* * *
Pada fungsi main, pengguna pertama-tama diminta untuk menetapkan berapa banyak
baris bintang yang akan ditampilkan (baris 1). Pada program ini, pengguna
dibatasi dengan 20 baris karena 20 baris cocok untuk ditampilkan pada layar.
Karena program dibatasi menjadi hanya 20 baris, loop while pada baris 3 sampai baris 6 memastikan bahwa program hanya
menampilkan 1 sampai 20 baris bintang.
Parameter Nilai
Bagian sebelumnya telah mendefinisikan
dua tipe parameter, yaitu parameter nilai dan parameter referensi. Contoh 6.3
menunjukkan sebuah program yang menggunakan sebuah fungsi dengan parameter.
Sebelum mempelajari contoh-contoh lain dari fungsi kosong dengan parameter,
Anda perlu mengamati parameter nilai dan parameter referensi. Ketika sebuah
fungsi dipanggil, nilai dari parameter aktual disalin ke parameter formal
terkait. Jika parameter formal merupakan parameter nilai, maka setelah
penyalinan nilai dari parameter aktual, tidak ada lagi hubungan antara
parameter formal dan parameter aktual; jadi, parameter formal memiliki salinan
data sendiri. Oleh karena itu, selama eksekusi program, parameter formal
memanipulasi data yang disimpan di ruang memorinya sendiri. Program pada contoh
6.4 lebih lanjut mengilustrasikan bagaimana sebuah parameter nilai bekerja.
Contoh 6.4
|
Program berikut menunjukkan bagaimana
sebuah parameter formal dari tipe data primitif bekerja.
//Contoh 6.4
//Program mengilustrasikan bagaimana sebuah parameter
nilai bekerja.
#include
<iostream>
using namespace
std;
void fungsiNilaiParam(int
angka);
int main()
{
int bilangan = 6; //Baris
1
cout
<< "Baris 2: Sebelum
memanggil fungsi "
<< "fungsiNilaiParam,
bilangan = " << bilangan
<< endl; //Baris
2
fungsiNilaiParam(bilangan); //Baris
3
cout
<< "Baris 4: Setelah
memanggil fungsi "
<< "fungsiNilaiParam,
bilangan = " << bilangan
<< endl; //Baris 4
return 0;
}
void fungsiNilaiParam(int
angka)
{
cout
<< "Baris 5: Di dalam fungsi
fungsiNilaiParam, "
<< "sebelum pengubahan, angka = " << angka
<< endl; //Baris
5
angka = 15; //Baris 6
cout
<< "Baris 7: Di dalam fungsi
fungsiNilaiParam, "
<< "setelah
pengubahan, angka = " << angka
<< endl; //Baris
7
}
Keluaran Program:
Baris 2: Sebelum memanggil fungsi fungsiNilaiParam,
bilangan = 6
Baris 5: Di dalam fungsi fungsiNilaiParam, sebelum
pengubahan, angka = 6
Baris 7: Di dalam fungsi fungsiNilaiParam, setelah
pengubahan, angka = 15
Baris 4: Setelah memanggil fungsi fungsiNilaiParam,
bilangan = 6
Program ini bekerja sebagai berikut.
Eksekusi dimulai pada fungsi main.
Statemen pada baris 1 mendeklarasikan dan menginisialisasi variabel int, bilangan. Statemen pada baris 2 menampilkan nilai dari bilangan sebelum pemanggilan fungsi fungsiNilaiParam; statemen pada baris 3
memanggil fungsi fungsiNilaiParam.
Nilai dari variabel bilangan
kemudian dilewatkan kepada parameter formal angka. Kendali program sekarang beralih ke fungsi fungsiNilaiParam.
Statemen pada baris 5 menampilkan nilai
dari angka sebelum pengubahan
nilainya. Statemen pada baris 6 mengubah nilai dari angka menjadi 15; statemen pada baris 7 menampilkan nilai dari angka. Setelah statemen ini dieksekusi,
fungsi fungsiNilaiParam keluar dan
kendali program kembali kepada fungsi main.
Statemen pada baris 4 menampilkan nilai
dari bilangan setelah pemanggilan
fungsi fungsiNilaiParam. Contoh
keluaran program menunjukkan bahwa nilai dari bilangan (baris 2 dan baris 4) tetap sama meskipun nilai dari
parameter formal terkaitnya, angka,
berubah di dalam fungsi fungsiNilaiParam.
Keluaran menunjukkan urutan dimana
statemen-statemen dieksekusi.
Setelah penyalinan data, sebuah
parameter nilai tidak lagi memiliki koneksi dengan parameter aktual, jadi
parameter nilai tidak dapat melewatkan sembarang hasil kembali kepada fungsi
pemanggil. Ketika fungsi dieksekusi, apapun perubahan yang dilakukan terhadap
parameter formal tidak akan berpengaruh terhadap parameter aktual. Parameter
aktual tidak lagi ada hubungan dengan apa yang terjadi pada parameter formal.
Jadi, parameter nilai memberikan hubungan satu-arah antara parameter aktual dan
parameter formal. Inilah mengapa dikatakan bahwa fungsi dengan parameter nilai
memiliki keterbatasan.
Variabel Referensi sebagai
Parameter
Program pada contoh 6.4
mengilustrasikan bagaimana sebuah parameter nilai bekerja. Di sisi lain,
dimisalkan bahwa parameter formal merupakan sebuah parameter referensi. Karena
parameter referensi menerima alamat (lokasi memori) dari parameter aktual, ia
dapat melewatkan satu atau lebih nilai dari sebuah fungsi dan dapat mengubah
nilai dari parameter aktual.
Parameter referensi berguna dalam tiga
situasi:
·
Ketika nilai dari parameter aktual
perlu diubah.
·
Ketika Anda ingin menghasilkan satu
atau lebih nilai balik dari sebuah fungsi.
·
Ketika pelewatan alamat dapat
menghemat ruang memori dan waktu komputasi pada kasus pemrosesan data besar.
Ingat bahwa ketika Anda membubuhi & yang ditempatkan setelah tipeData
di dalam daftar parameter formal pada sebuah fungsi, variabel yang ditempatkan
setelah tipeData menjadi parameter
referensi.
Contoh 6.5
|
Menghitung
Nilai
Program berikut mengambil skor sebuah
matakuliah sebagai argumen (sebuah nilai dari 0 dan 100) dan menentukan nilai
matakuliah seorang mahasiswa. Program ini mempunyai tiga fungsi: main, dapatSkor, dan tampilNilai,
sebagai berikut:
1.
main
a.
Mendapatkan skor matakuliah.
b.
Menampilkan nilai matakuliah.
2.
dapatSkor
a.
Meminta pengguna untuk memberikan
masukan.
b.
Membaca masukan.
c.
Menampilkan skor mahasiswa.
3.
tampilNilai
a.
Menghitung nilai matakuliah.
b.
Menampilkan nilai matakuliah.
Program utuh adalah sebagai berikut:
//Program ini membaca skor matakuliah dan menampilkan
//nilai matakuliah terkait.
#include
<iostream>
using namespace
std;
void dapatSkor(int&
skor);
void tampilNilai(int
skor);
int main()
{
int skorMtKuliah;
cout
<< "Baris 1: Berdasarkan pada
skor matakuliah, \n"
<< " program ini menghitung "
<< "nilai matakuliah." << endl; //Baris 1
dapatSkor(skorMtKuliah); //Baris
2
tampilNilai(skorMtKuliah); //Baris
3
return 0;
}
void dapatSkor(int&
skor)
{
cout
<< "Baris 4: Masukkan skor
matakuliah: "; //Baris
4
cin >>
skor; //Baris
5
cout
<< endl << "Baris 6:
Skor matakuliah adalah "
<< skor << endl; //Baris
6
}
void tampilNilai(int
cSkor)
{
cout
<< "Baris 7: Nilai Anda untuk matakuliah ini adalah
"; //Baris 7
if (cSkor >= 90) //Baris
8
cout
<< "A." <<
endl;
else if (cSkor >= 80)
cout
<< "B." <<
endl;
else if(cSkor >= 70)
cout
<< "C." <<
endl;
else if (cSkor >= 60)
cout << "D." << endl;
else
cout
<< "F." <<
endl;
}
Keluaran Program:
Baris 1: Berdasarkan pada
skor matakuliah,
program ini menghitung
nilai matakuliah.
Baris 4: Masukkan skor
matakuliah: 85
Baris 6: Skor matakuliah
adalah 85
Baris 7: Nilai Anda untuk
matakuliah ini adalah B.
Program ini bekerja sebagai berikut.
Program mulai dieksekusi pada baris 1, yang menampilkan baris pertama dari
keluaran (lihat contoh keluaran program). Statemen pada baris 2 memanggil
fungsi dapatSkor dengan parameter
aktual skorMtKuliah (sebuah variabel
yang dideklarasikan di dalam main).
Karena parameter formal, skor, dari
fungsi dapatSkor merupakan parameter
referensi, alamat (yaitu, lokasi memori dari variabel skorMtKuliah) yang dilewatkan kepada skor. Jadi, kedua skor dan skorMtKuliah menunjuk ke lokasi memori yang sama. Lihat Gambar 6.1.
Apapun perubahan yang dilakukan
terhadap skor akan mengubah nilai
dari skorMtKuliah.
Kendali kemudian beralih ke fungsi getSkor, dan statemen pada baris 4
dieksekusi, menampilkan baris kedua pada keluaran. Statemen ini meminta
pengguna untuk memasukkan skor
matakuliah. Statemen pada baris 5 membaca dan menyimpan nilai yang dimasukkan
oleh pengguna (85 pada contoh keluaran program) di dalam skor, yang sebenarnya adalah skorMtKuliah
(karena skor merupakan parameter
referensi). Jadi, pada titik ini, nilai dari variabel skor dan skorMtKuliah
adalah 85 (lihat Gambar 6.2).
Selanjutnya, statemen pada baris 6
menampilkan nilai dari skor seperti
yang ditunjukkan pada baris ketiga dari contoh keluaran program. Setelah baris
6 dieksekusi, kendali program kembali kepada fungsi main (lihat Gambar 6.3).
Gambar 6.3 Variabel skorMtKuliah
setelah statemen pada baris 6 dieksekusi dan kendali program kembali kepada main
Statemen pada baris 3 dieksekusi
berikutnya. Ia merupakan sebuah pemanggilan terhadap fungsi tampilNilai dengan parameter aktual skorMtKuliah. Karena parameter formal cSkor dari fungsi tampilNilai adalah sebuah parameter nilai, parameter cSkor menerima nilai dari parameter
aktual terkait, skorMtKuliah. Jadi,
nilai dari cSkor adalah 85. Setelah
penyalinan nilai dari skorMtKuliah
ke dalam cSkor, tidak ada lagi
komunikasi antara cSkor dan skorMtKuliah. (Lihat Gambar 6.4).
Program kemudian mengeksekusi statemen
pada baris 7, yang menampilkan baris keempat keluaran. Statemen if...else pada baris 8 menentukan dan
menampilkan nilai matakuliah. Karena statemen keluaran pada baris 7 tidak
memuat karakter garis-baru atau manipulator endl, keluaran dari statemen if...else
merupakah bagian dari baris keempat pada keluaran program. Setelah statemen if...else dieksekusi, kendali kembali
ke fungsi main. Karena statemen
berikutnya yang akan dieksekusi di dalam fungsi main adalah statemen terakhir pada fungsi tersebut, program
berhenti.
Pada program ini, fungsi main pertama-tama memanggil fungsi dapatSkor untuk mendapatkan skor
matakuliah dari pengguna. Fungsi main
kemudian memanggil fungsi tampilNilai
untuk menghitung dan menampilkan nilai berdasarkan skor matakuliah. Skor
matakuliah didapatkan melalui fungsi dapatSkor;
kemudian, skor matakuliah ini dipakai oleh fungsi tampilNilai. Karena nilai yang didapatkan oleh fungsi dapatSkor digunakan nanti pada program,
fungsi dapatSkor harus melewatkan
nilai ini ke luar. Jadi, parameter formal yang menampung nilai ini harus berupa
parameter referensi.
Parameter Nilai dan Parameter
Referensi: Alokasi Memori
Ketika sebuah fungsi dipanggil, memori untuk
tiap parameter formal dan variabelnya yang dideklarasikan di dalam tubuh fungsi
(disebut juga dengan variabel lokal) dialokasikan di dalam area data fungsi.
Ingat bahwa pada kasus parameter nilai, nilai dari parameter aktual disalin ke
dalam sel memori dari parameter formal terkait. Pada kasus parameter referensi,
alamat dari parameter aktual dilewatkan kepada parameter formal. Yaitu, isi
dari parameter formal adalah sebuah alamat. Selama manipulasi data, isi dari
parameter formal memerintahkan komputer untuk memanipulasi data di dalam sel
memori yang diindikasikan oleh isi parameter formal. Jadi, pada kasus parameter
referensi, baik parameter aktual maupun parameter formal menunjuk ke lokasi
memori yang sama. Konsekuensinya, selama eksekusi program, perubahan apapun
yang dilakukan terhadap parameter formal akan mengubah nilai dari parameter
aktual.
Karena pelewatan parameter merupakan
hal yang fundamental dalam bahasa pemrograman, contoh 6.6 dan contoh 6.7 lebih
lanjut akan mengilustrasikan konsep ini. Setiap contoh merangkum skenario yang
berbeda.
Contoh 6.6
|
Program berikut menunjukkan bagaimana
parameter referensi dan parameter nilai bekerja.
//Contoh 6.6:
Parameter referensi dan parameter nilai
#include <iostream>
using namespace std;
void fungsiSatu(int a, int& b, char v);
void fungsiDua(int& x, int y, char& w);
int main()
{
int
angka1, angka2;
char
ch;
angka1 = 10; //Baris 1
angka2 = 15; //Baris 2
ch = 'A'; //Baris
3
cout << "Baris 4: Di dalam main: angka1 = " << angka1
<< ", angka2 = " << angka2 << ", dan ch = "
<< ch << endl; //Baris 4
fungsiSatu(angka1, angka2, ch); //Baris 5
cout << "Baris 6: Setelah fungsiSatu: angka1 = " << angka1
<< ", angka2 = " << angka2 << ", dan ch = "
<< ch << endl; //Baris 6
fungsiDua(angka2, 25, ch); //Baris 7
cout << "Baris 8: Setelah fungsiDua: angka1 = " << angka1
<< ", angka2 = " << angka2 << ", dan ch = "
<< ch << endl; //Baris 8
return
0;
}
void fungsiSatu(int a, int& b, char v)
{
int
satu;
satu = a; //Baris
9
a++; //Baris
10
b = b * 2; //Baris
11
v = 'B'; //Baris
12
cout << "Baris 13: Di dalam fungsiSatu: a = " << a
<<
", b = " << b
<< ", v = " <<
v
<< ", dan satu = " << satu << endl; //Baris 13
}
void fungsiDua(int& x, int y, char& w)
{
x++; //Baris
14
y = y * 2; //Baris
15
w = 'G'; //Baris 16
cout << "Baris 17: Di dalam fungsiDua: x = " << x
<< ", y = " << y << ", dan w = " << w
<< endl; //Baris 17
}
Keluaran Program:
Baris 4: Di dalam main: angka1 = 10, angka2 = 15, dan
ch = A
Baris 13: Di dalam fungsiSatu: a = 11, b = 30, v = B,
dan satu = 10
Baris 6: Setelah fungsiSatu: angka1 = 10, angka2 = 30,
dan ch = A
Baris 17: Di dalam fungsiDua: x = 31, y = 50, dan w =
G
Baris 8: Setelah fungsiDua: angka1 = 10, angka2 = 31,
dan ch = G
Sekarang akan dijejak program ini untuk
meningkatkan pemahaman Anda. Setiap nilai variabel ditunjukkan sebelum dan/atau
sesudah tiap statemen dieksekusi.
Tepat sebelum statemen pada baris 1
dieksekusi, memori dialokasikan hanya untuk variabel-variabel dari fungsi main; memori ini tidak diinisialisasi.
Setelah statemen pada baris 3 dieksekusi, tiap variabel tersebut ditunjukkan
pada Gambar 6.5.
Statemen pada baris 4 menghasilkan
keluaran berikut:
Baris 4: Di dalam main: angka1 = 10, angka2 = 15, dan
ch = A
Statemen pada baris 5 merupakan sebuah
pemanggilan terhadap fungsi fungsiSatu.
Sekarang, fungsi fungsiSatu memiliki
tiga parameter dan satu variabel lokal. Memori untuk ketiga parameter dan
variabel lokal pada fungsi fungsiSatu
dialokasikan. Karena parameter formal b
adalah parameter referensi, maka ia menerima alamat (lokasi memori) dari
parameter aktual terkait, pada kasus ini angka2.
Dua parameter yang lain adalah parameter nilai, jadi keduanya menerima salinan
nilai dari dua parameter aktual terkait. Tepat sebelum statemen pada baris 9
dieksekusi, tiap variabel ditampilkan pada Gambar 6.6.
Setelah statemen pada baris 9
dieksekusi, satu = a;, dieksekusi,
tiap variabel ditunjukkan pada Gambar 6.7.
Setelah statemen pada baris 10, a++;, dieksekusi, tiap variabel ditunjukkan
pada Gambar 6.8.
Setelah statemen pada baris 11, b = b * 2;, dieksekusi, tiap variabel
ditunjukkan pada Gambar 6.9. (Perhatikan bahwa variabel b mengubah nilai dari angka2).
Setelah statemen pada baris 12, v = ‘B’;, dieksekusi, tiap variabel
ditunjukkan pada Gambar 6.10.
Statemen pada baris 13 menghasilkan
keluaran berikut:
Baris 13: Di dalam fungsiSatu: a = 11, b = 30, v = B,
dan satu = 10
Setelah statemen pada baris 13
dieksekusi, kendali program kembali ke baris 6 dan memori yang teralokasi untuk
tiap variabel pada fungsi fungsiSatu
didealokasi (dibebaskan). Gambar 6.11 menunjukkan nilai tiap variabel dari
fungsi main.
Baris 6 menghasilkan keluaran:
Baris 6: Setelah fungsiSatu: angka1 = 10, angka2 = 30,
dan ch = A
Statemen pada baris 7 merupakan sebuah
pemanggilan terhadap fungsi fungsiDua.
Sekarang, fungsiDua memiliki tiga
parameter: x, y, dan w. Selain itu, x dan w merupakan parameter referensi, dan y adalah sebuah parameter nilai. Jadi, x menerima alamat dari parameter aktual terkait, yaitu angka2, dan w menerima alamat dari parameter aktual terkait, yaitu ch. Variabel y menyalin nilai 25 ke dalam sel memorinya. Gambar 6.12 menunjukkan
nilai tiap variabel sebelum statemen pada baris 14 dieksekusi.
Setelah statemen pada baris 14, x++;, dieksekusi, tiap variabel
ditampilkan pada Gambar 6.13. (Perhatikan bahwa variabel x mengubah nilai dari angka2).
Setelah statemen pada baris 15, y = y * 2;, dieksekusi, tiap variabel
ditunjukkan pada Gambar 6.14.
Setelah statemen pada baris 16, w = ‘G’;, dieksekusi, tiap variabel
ditampilkan pada Gambar 6.15. (Perhatikan bahwa variabel w mengubah nilai dari ch).
Baris 17 menghasilkan keluaran berikut:
Baris 17: Di dalam fungsiDua: x = 31, y = 50, dan w =
G
Setelah statemen pada baris 17
dieksekusi, kendali program kendali ke baris 8. Memori yang dialokasikan untuk
tiap variabel dari fungsi fungsiDua
didealokasikan (dibebaskan). Nilai tiap variabel pada fungsi main ditunjukkan pada Gambar 6.16.
Statemen pada baris 8 menghasilkan
keluaran berikut:
Baris 8: Setelah fungsiDua: angka1 = 10, angka2 = 31,
dan ch = G
Setelah statemen pada baris 8 dieksekusi,
program berhenti.
Contoh 6.7
|
Contoh ini juga menunjukkan bagaimana
parameter referensi memanipulasi parameter aktual.
//Contoh 6.7:
Parameter referensi dan parameter nilai.
//Program: Membuat
Anda berpikir.
#include <iostream>
using namespace std;
void tambahPertama(int& pertama, int& kedua);
void gandaPertama(int satu, int dua);
void kuadratPertama(int& ref, int nil);
int main()
{
int
angka = 5;
cout << "Baris 1: Di dalam main: angka = " << angka
<< endl; //Baris 1
tambahPertama(angka, angka); //Baris 2
cout << "Baris 3: Di dalam main setelah tambahPertama:"
<< " angka = " <<
angka << endl; //Baris
3
gandaPertama(angka, angka); //Baris 4
cout << "Baris 5: Di dalam main setelah "
<< "gandaPertama: angka =
" << angka << endl; //Baris
5
kuadratPertama(angka, angka); //Baris 6
cout << "Baris 7: Di dalam main setelah "
<< "kuadratPertama: angka =
" << angka << endl; //Baris
7
return
0;
}
void tambahPertama(int& pertama, int& kedua)
{
cout << "Baris 8: Di dalam tambahPertama: pertama = "
<< pertama << ", kedua = " << kedua << endl; //Baris 8
pertama = pertama + 2; //Baris 9
cout << "Baris 10: Di dalam tambahPertama: pertama = "
<< pertama << ", kedua = " << kedua <<
endl; //Baris 10
kedua = kedua * 2; //Baris 11
cout << "Baris 12: Di dalam tambahPertama: pertama = "
<< pertama << ", kedua = " << kedua <<
endl; //Baris
12
}
void gandaPertama(int satu, int dua)
{
cout << "Baris 13: Di dalam gandaPertama: satu = "
<< satu << ", dua = " << dua <<
endl; //Baris 13
satu = satu * 2; //Baris 14
cout << "Baris 15: Di dalam gandaPertama: satu = "
<< satu << ", dua = " << dua <<
endl; //Baris 15
dua = dua + 2; //Baris 16
cout << "Baris 17: Di dalam gandaPertama: satu = "
<< satu << ", dua = " << dua <<
endl; //Baris 17
}
void kuadratPertama(int& ref, int nil)
{
cout << "Baris 18: Di dalam kuadratPertama: ref = "
<< ref << ", nil = " << nil <<
endl; //Baris 18
ref = ref * ref; //Baris 19
cout << "Baris 20: Di dalam kuadratPertama: ref = "
<< ref << ", nil = " << nil <<
endl; //Baris 20
nil = nil + 2; //Baris 21
cout << "Baris 22: Di dalam kuadratPertama: ref = "
<< ref << ", nil = " << nil <<
endl; //Baris 22
}
Keluaran Program:
Baris 1: Di dalam main: angka = 5
Baris 8: Di dalam tambahPertama: pertama = 5, kedua =
5
Baris 10: Di dalam tambahPertama: pertama = 7, kedua =
7
Baris 12: Di dalam tambahPertama: pertama = 14, kedua
= 14
Baris 3: Di dalam main setelah tambahPertama: angka =
14
Baris 13: Di dalam gandaPertama: satu = 14, dua = 14
Baris 15: Di dalam gandaPertama: satu = 28, dua = 14
Baris 17: Di dalam gandaPertama: satu = 28, dua = 16
Baris 5: Di dalam main setelah gandaPertama: angka =
14
Baris 18: Di dalam kuadratPertama: ref = 14, nil = 14
Baris 20: Di dalam kuadratPertama: ref = 196, nil = 14
Baris 22: Di dalam kuadratPertama: ref = 196, nil = 16
Baris 7: Di dalam main setelah kuadratPertama: angka =
196
Kedua parameter dari fungsi tambahPertama adalah parameter
referensi, dan kedua parameter dari fungsi gandaPertama
adalah parameter nilai. Statemen:
tambahPertama(angka, angka);
di dalam fungsi main (baris 2) melewatkan referensi dari angka kepada kedua parameter formal pertama dan kedua dari
fungsi tambahPertama, karena kedua
parameter aktual terkait untuk kedua parameter formal tersebut adalah sama.
Yaitu, variabel pertama dan kedua merujuk ke lokasi memori yang
sama, yaitu angka. Gambar 6.17
mengilustrasikan situasi ini.
Sembarang perubahan yang dilakukan pertama terhadap nilainya akan mengubah
nilai dari kedua dan angka. Sama halnya, apapun perubahan
yang dilakukan kedua terhadap
nilainya akan mengubah nilai dari pertama
dan angka, karena ketiga variabel
merujuk ke lokasi memori yang sama. (Perhatikan bahwa angka diinisialisasi dengan 5).
Tiap parameter formal pada gandaPertama merupakan parameter nilai.
Jadi statemen:
gandaPertama(angka, angka);
di dalam fungsi main (baris 4) menyalin nilai dari angka ke dalam satu dan dua karena kedua parameter aktual untuk kedua parameter formal
adalah sama. Gambar 6.18 mengilustrasikan skenario ini.
Karena kedua satu dan dua merupakan
parameter nilai, apapun perubahan yang dilakukan satu terhadap nilainya tidak akan berpengaruh terhadap nilai satu dan angka. Sama halnya, apapun perubahan yang dilakukan dua terhadap nilainya tidak akan
berpengaruh terhadap satu dan angka. (Perhatikan bahwa nilai dari angka sebelum fungsi gandaPertama dieksekusi adalah 14).
Parameter formal ref dari fungsi kuadratPertama
adalah sebuah parameter referensi, dan parameter formal nil adalah sebuah variabel nilai. Variabel ref menerima alamat dari parameter aktual terkaitnya, yaitu angka, dan variabel nil menyalin nilai dari parameter
aktual terkaitnya, yang juga angka.
Jadi, kedua angka dan ref merujuk ke lokasi memori yang sama,
yaitu angka. Gambar 6.19
mengilustrasikan situasi ini.
Sembarang perubahan yang dilakukan ref akan mengubah angka. Sembarang perubahan yang dilakukan nil tidak mempengaruhi angka. (Perhatikan bahwa nilai dari angka sebelum fungsi kuadratPertama dieksekusi adalah 14).
Skop Pengenal
Beberapa bagian terdahulu dan Bab 5
telah menyajikan beberapa contoh program dengan fungsi-fungsi
terdefinisi-pengguna. Pengenal dideklarasikan di dalam sebuah kepala fungsi, di
dalam suatu blok, atau di suatu luar blok. Pertanyaan umum yang diajukan
adalah: Apakah Anda diijinkan untuk mengakses sembarang pengenal di mana saja
di dalam program? Jawabannya adalah tidak. Anda harus mengikut beberapa aturan
dalam mengakses sebuah pengenal. Skop sebuah pengenal berkaitan dengan di mana
di dalam program sebuah pengenal dapat diakses (visibel atau dikenali). Ingat
bahwa sebuah pengenal adalah nama sesuatu di dalam C++, seperti nama variabel
atau nama fungsi.
Bagian ini akan memeriksa skop sebuah
pengenal. Pertama, didefinisikan dua istilah berikut:
Pengenal lokal: Pengenal yang
didefinisikan di dalam sebuah fungsi (atau blok).
Pengenal lokal tidak dapat diakses atau
tidak dikenali di luar fungsi (blok).
Pengenal global: Pengenal yang
dideklarasikan di luar setiap definisi fungsi.
Selain itu, C++ juga tidak mengijinkan
fungsi bersarang. Yaitu, Anda tidak boleh mencantumkan definisi sebuah fungsi
di dalam tubuh fungsi lain.
Secara umum, beberapa aturan berikut
diterapkan ketika sebuah pengenal diakses:
1. Pengenal global
(seperti variabel) dapat diakses oleh sebuah fungsi atau sebuah blok jika:
a.
Pengenal tersebut dideklarasikan
sebelum definisi fungsi (blok).
b.
Nama fungsi berbeda dari pengenal
tersebut.
c.
Semua parameter pada fungsi memiliki
nama berbeda dari nama pengenal tersebut.
d.
Semua pengenal lokal (seperti
variabel lokal) memiliki nama berbeda dari nama pengenal tersebut.
2. (Blok bersarang) Sebuah pengenal yang
dideklarasikan di dalam sebuah blok dapat diakses:
a.
hanya di dalam blok dimulai dari
titik di mana ia dideklarasikan sampai akhir blok tersebut.
b.
Oleh blok-blok yang bersarang di
dalam blok tersebut jika blok bersarang tidak memiliki pengenal dengan nama
sama.
3. Skop dari nama
fungsi sama dengan skop pengenal yang dideklarasikan di luar sembarang blok.
Jadi, skop dari nama fungsi sama dengan skop variabel global.
Sebelum mempelajari contoh untuk
menjelaskan aturan-aturan skop, pertama-tama Anda perlu memperhatikan skop dari
pengenal yang dideklarasikan di dalam statemen for. C++ mengijinkan programer untuk mendeklarasikan sebuah
variabel di dalam statemen inisialisasi pada statemen for. Sebagai contoh, statemen for
berikut:
for (int hitung = 1; hitung <
10; hitung++)
cout << hitung << endl;
mendeklarasikan variabel hitung dan menginisialisasinya dengan
1. Skop dari variabel hitung
dibatasi hanya di dalam tubuh loop for.
Program C++ berikut membantu
mengilustrasikan aturan-aturan skop:
#include
<iostream>
using namespace
std;
const double
LAJU = 10.50;
int z;
double t;
void satu(int
x, char y);
void dua(int
a, int b, char x);
void tiga(int
satu, double y, int z);
int main()
{
int angka, pertama;
double x, y, z;
char nama, akhir;
.
.
.
return 0;
}
void satu(int
x, char y)
{
.
.
.
}
int w;
void two(int
a, int b, char x)
{
int hitung;
.
.
.
}
void tiga(int
satu, double y, int z)
{
char ch;
int a;
.
.
.
//Blok
empat
{
int x;
char a;
.
.
}//akhir
blok empat
.
.
.
}
Perhatikan bahwa fungsi tiga tidak dapat memanggil fungsi satu, karena fungsi tiga memiliki parameter formal bernama satu. Sama halnya, blok yang ditandai empat di dalam fungsi tiga tidak dapat menggunakan variabel int, a, yang dideklarasikan di dalam fungsi tiga, karena blok empat
memiliki sebuah pengenal bernama a.
Sebelum menutup diskusi pada bagian ini, akan dicatat beberapa hal tentang
variabel global:
1. Bab 1 telah
menyatakan bahwa C++ tidak secara otomatis menginisialisasi variabel. Namun,
beberapa kompiler menginisialisasi variabel global dengan nilai defaultnya.
Sebagai contoh, jika sebuah variabel global yang tidak diinisialisasi adalah
bertipe int, char, atau double, maka
ia akan diinisialisasi dengan nol.
2. Dalam C++, ::
disebut dengan operator resolusi skop. Dengan menggunakan operator resolusi
skop, sebuah variabel global yang berada sebelum definisi sebuah fungsi (blok)
dapat diakses oleh fungsi (atau blok) bahkan jika fungsi (atau blok) memiliki
sebuah pengenal dengan nama sama dengan variabel global tersebut. Dalam program
sebelumnya, dengan menggunakan operator resolusi skop, fungsi main dapat merujuk variabel global
sebagai ::z. Sama halnya, dimisalkan
bahwa sebuah variabel global t
dideklarasikan sebelum definisi fungsi, katakanlan, fungsiContoh. Maka, fungsiContoh
dapat mengakses variabel t
menggunakan operator resolusi skop bahkan jika fungsiContoh memiliki sebuah pengenal t. Dengan menggunakan operator resolusi skop, fungsiContoh dapat merujuk variabel global t sebagai ::t. Selain
itu, dalam program sebelumnya, dengan menggunakan operator resolusi skop,
fungsi tiga dapat memanggil fungsi satu.
3. C++ menyediakan
sebuah cara dalam mengakses variabel global yang dideklarasikan setelah definisi
sebuah fungsi. Pada kasus ini, fungsi harus tidak memuat sembarang pengenal
dengan nama sama dengan variabel global tersebut. Pada program sebelumnya,
variabel global w dideklarasikan
setelah definisi fungsi satu. Fungsi
satu tidak memuat sembarang pengenal
bernama w. Oleh karena itu, w dapat diakses oleh fungsi satu jika Anda mendeklarasikan w sebagai variabel eksternal di dalam fungsi satu. Untuk mendeklarasikan w
sebagai variabel eksternal di dalam fungsi satu,
fungsi satu harus memuat statemen berikut:
extern int w;
Dalam C++, extern merupakan katakunci. Kata extern pada statemen tersebut mengumumkan bahwa w adalah sebuah variabel global yang
dideklarasikan di suatu tempat. Jadi, ketika fungsi satu dipanggil, tidak ada memori yang dideklarasikan untuk w.
Variabel Global dan Konstanta
Bernama
Sebuah program C++ dapat memuat
variabel global. Penggunaan variabel global dapat menyebabkan efek samping.
Jika lebih dari satu fungsi menggunakan variabel global yang sama dan masalah
terjadi, maka akan menjadi sulit untuk menemukan apa yang terjadi dan di mana.
Masalah yang disebabkan oleh variabel global pada suatu tempat di dalam program
dapat disalahpahami sebagai masalah yang disebabkan di tempat lain.
Sebagai contoh, perhatikan program
berikut:
//Variabel global
#include
<iostream>
using namespace
std;
int t;
void fungsiSatu(int&
a);
int main()
{
t = 15; //Baris
1
cout
<< "Baris 2: Di dalam main: t
= " << t << endl; //Baris
2
fungsiSatu(t); //Baris
3
cout
<< "Baris 4: di dalam main
setelah fungsiSatu: "
<< " t = " << t << endl; //Baris 4
return 0; //Baris 5
}
void fungsiSatu(int&
a)
{
cout
<< "Baris 6: Di dalam
fungsiSatu: a = " << a
<< " dan t =
" << t << endl; //Baris
6
a = a + 12; //Baris
7
cout
<< "Baris 8: Di dalam
fungsiSatu: a = " << a
<< " dan t =
" << t << endl; //Baris
8
t = t + 13; //Baris
9
cout
<< "Baris 10: Di dalam
fungsiSatu: a = " << a
<< " dan t =
" << t << endl; //Baris
10
}
Keluaran Program:
Baris 2: Di dalam main: t = 15
Baris 6: Di dalam fungsiSatu: a = 15 dan t = 15
Baris 8: Di dalam fungsiSatu: a = 27 dan t = 27
Baris 10: Di dalam fungsiSatu: a = 40 dan t = 40
Baris 4: di dalam main setelah fungsiSatu: t = 40
Program ini memiliki sebuah variabel t yang dideklarasikan sebelum definisi
atas sembarang fungsi. Karena tidak ada fungsi yang memiliki pengenal t, variabel t dapat diakses di mana saja di dalam program. Selain itu, program
memuat sebuah fungsi kosong dengan sebuah parameter referensi.
Pada baris 3, fungsi main memanggil fungsi fungsiSatu, dan parameter aktual yang dilewatkan
kepada fungsiSatu adalah t. Jadi, a, parameter formal dari fungsiSatu,
menerima alamat dari t. Apapun
perubahan yang dilakukan oleh a
terhadap nilainya akan mengubah t.
Karena t dapat secara langsung
diakses di mana saja di dalam program, pada baris 9, fungsi fungsiSatu mengubah nilai dari t menggunakan t sendiri. Jadi, Anda dapat memanipulasi nilai dari t menggunakan sebuah parameter
referensi atau lewat dirinya sendiri.
Pada program tersebut, jika nilai
terakhir dari t tidak benar, maka
akan menjadi sulit untuk menentukan apa yang telah terjadi dan di mana masalah
terjadi. Direkomendasikan bahwa Anda tidak menggunakan variabel global.
Contoh 6.8
|
Berikut merupakan sebuah contoh program
menu-driven. Ketika program dieksekusi, ia memberikan pengguna sebuah
daftar pilihan untuk dipilih. Program ini lebih lanjut akan mengilustrasikan
bagaimana parameter nilai dan parameter referensi bekerja. Program ini
mengkonversi panjang dari kaki dan inci ke dalam meter dan sentimeter dan
sebaliknya. Program memuat tiga fungsi: tampilPilihan,
kakiDanInciKeMeterDanSenti, dan meterDanSentiKe-KakiDanInci. Fungsi tampilPilihan
menginformasikan pengguna tentang bagaimana menggunakan program.
//Program
menu-driven.
#include <iostream>
using namespace std;
const double KONVERSI = 2.54;
const int INCI_DALAM_KAKI = 12;
const int SENTIMETER_DALAM_METER = 100;
void tampilPilihan();
void
kakiDanInciKeMeterDanSenti(int f, int in, int& mt, int&
ct);
void meterDanSentiKeKakiDanInci(int mt, int ct, int& f, int& in);
int main()
{
int
kaki, inci;
int
meter, sentimeter;
int
pilihan;
do
{
tampilPilihan();
cin >> pilihan;
cout << endl;
switch
(pilihan)
{
case
1:
cout << "Masukkan kaki dan inci: ";
cin >> kaki >> inci;
cout << endl;
kakiDanInciKeMeterDanSenti(kaki,
inci, meter, sentimeter);
cout << kaki << " kaki, "
<< inci << " inci = "
<< meter << "
meter, "
<< sentimeter <<
" sentimeter." <<
endl;
break;
case
2:
cout << "Masukkan meter dan sentimeter: ";
cin >> meter >>
sentimeter;
cout << endl;
meterDanSentiKeKakiDanInci(meter,
sentimeter, kaki, inci);
cout << meter << "
meter, "
<< sentimeter <<
" sentimeter = "
<< kaki << " kaki, "
<< inci << " inci."
<< endl;
break;
case
99:
break;
default:
cout << "Masukan tak-valid." << endl;
}
}
while
(pilihan != 99);
return
0;
}
void tampilPilihan()
{
cout << "Tekan--" << endl;
cout << "1: Untuk mengkonversi dari kaki dan inci ke meter "
<< "dan sentimeter."
<< endl;
cout << "2: Untuk mengkonversi dari meter dan sentimeter ke
kaki "
<< "dan inci." <<
endl;
cout << "99: Untuk keluar program."
<< endl;
}
void
kakiDanInciKeMeterDanSenti(int f, int in, int& mt, int&
ct)
{
int
inci;
inci = f * INCI_DALAM_KAKI + in;
ct = static_cast<int>(inci * KONVERSI);
mt = ct / SENTIMETER_DALAM_METER;
ct = ct % SENTIMETER_DALAM_METER;
}
void
meterDanSentiKeKakiDanInci(int mt, int ct, int& f, int& in)
{
int sentimeter;
sentimeter = mt * SENTIMETER_DALAM_METER +
ct;
in = static_cast<int>(sentimeter /
KONVERSI);
f = in / INCI_DALAM_KAKI;
in = in % INCI_DALAM_KAKI;
}
Keluaran Program:
Tekan--
1: Untuk mengkonversi dari kaki dan inci ke meter dan
sentimeter.
2: Untuk mengkonversi dari meter dan sentimeter ke
kaki dan inci.
99: Untuk keluar program.
2
Masukkan meter dan sentimeter: 4 25
4 meter, 25 sentimeter = 13 kaki, 11 inci.
Tekan--
1: Untuk mengkonversi dari kaki dan inci ke meter dan
sentimeter.
2: Untuk mengkonversi dari meter dan sentimeter ke
kaki dan inci.
99: Untuk keluar program.
1
Masukkan kaki dan inci: 15 8
15 kaki, 8 inci = 4 meter, 77 sentimeter.
Tekan--
1: Untuk mengkonversi dari kaki dan inci ke meter dan
sentimeter.
2: Untuk mengkonversi dari meter dan sentimeter ke
kaki dan inci.
99: Untuk keluar program.
99
Variabel Statis dan Variabel
Otomatis
Variabel-variabel yang dideklarasikan
sejauh ini memiliki dua aturan sederhana:
1. Memori untuk
variabel global tetap teralokasi sepanjang program dieksekusi.
2. Memori untuk
variabel yang dideklarasikan di dalam sebuah blok dialokasikan saat kendali
program memasuki blok dan didealokasikan (dibebaskan) saat kendali program
keluar dari blok. Sebagai contoh, memori untuk parameter formal dan variabel
lokal pada sebuah fungsi dialokasikan ketika fungsi dipanggil dan
didealokasikan ketika fungsi keluar atau berhenti.
Sebuah variabel pada aturan 2 disebut
dengan variabel otomatis. Sebuah variabel pada aturan 1 disebut dengan variabel
statis. Variabel global adalah variabel
statis, dan secara default, variabel yang dideklarasikan di dalam sebuah blok
adalah variabel otomatis. Anda dapat mendeklarasikan sebuah variabel statis
di dalam sebuah blok menggunakan katakunci static.
Sintaks untuk mendeklarasikan sebuah variabel statis adalah:
static tipeData
pengenal;
Statemen:
static int x;
mendeklarasikan x sebagai sebuah variabel statis bertipe int.
Variabel statis yang dideklarasikan di
dalam sebuah blok bersifat lokal di dalam blok tersebut, dan skopnya sama
dengan pengenal lokal yang lain di dalam blok tersebut.
Kebanyakan kompiler menginisialisasi
variabel static dengan nilai
defaultnya. Sebagai contoh, variabel static
int diinisialisasi dengan 0. Tetapi, akan lebih baik bila Anda sendiri yang
menginisialisasi variabel static.
Pada kasus ini, variabel static
diinisialisasi ketika ia dideklarasikan. Statemen:
static int x = 0;
mendeklarasikan x sebagai sebuah variabel statis bertipe int dan menginisialisasinya dengan 0.
Contoh 6.9
|
Program berikut menunjukkan bagaimana
variabel statis dan variabel otomatis bekerja.
//Program: Variabel statis dan variabel otomatis
#include
<iostream>
using namespace
std;
void test();
int main()
{
int hitung;
for (hitung = 1; hitung <= 5;
hitung++)
test();
return 0;
}
void test()
{
static int x = 0;
int y = 10;
x = x + 2;
y = y + 1;
cout
<< "Di dalam test x =
" << x << " dan y
= "
<<
y << endl;
}
Keluaran Program:
Di dalam test x = 2 dan y = 11
Di dalam test x = 4 dan y = 11
Di dalam test x = 6 dan y = 11
Di dalam test x = 8 dan y = 11
Di dalam test x = 10 dan y = 11
Pada fungsi test, x merupakan sebuah
variabel static yang diinisialisasi
dengan 0, dan y adalah sebuah
variabel otomatis yang diinisialisasi dengan 0. Fungsi main memanggil fungsi test
sebanyak lima kali. Memori untuk variabel y
dialokasikan setiap kali fungsi test
dipanggil dan didealokasi ketika kendali program keluar dari fungsi tersebut.
Jadi, setiap kali test dipanggil, ia
akan menampilkan nilai yang sama untuk y.
Namun, karena x adalah variabel
statis, memori untuk x tetap
teralokasi sepanjang program dieksekusi. Variabel x diinisialisasi dengan 0. Pemanggilan beruntun terhadap fungsi test menggunakan nilai terkini dari x.
Pengoverloadan Fungsi: Pengenalan
Dalam sebuah program C++, beberapa
fungsi bisa memiliki nama sama. Ini
disebut dengan pengoverloadan fungsi. Sebelum dijelaskan beberapa aturan dalam
mengoverload sebuah fungsi, akan didefinisikan beberapa hal berikut:
Dua fungsi dikatakan memiliki daftar
parameter formal berbeda jika kedua fungsi memiliki:
·
Jumlah parameter formal yang berbeda
atau
·
Jika jumlah parameter formal sama,
maka tipe data dari parameter formal harus berbeda sedikitnya satu parameter
formal.
Sebagai contoh, perhatikan beberapa
kepala fungsi berikut:
void fungsiSatu(int x)
void fungsiDua(int x, double y)
void fungsiTiga(double y, int x)
int fungsiEmpat(char ch, int x, double y)
int fungsiLima(char ch, int x, string nama)
Semua fungsi tersebut memiliki daftar
parameter formal yang berbeda.
Sekarang, perhatikan beberapa kepala
fungsi berikut:
void fungsiEnam(int x, double y, char ch)
void fungsiTujuh(int satu, double u, char chPertama)
Fungsi fungsiEnam dan fungsiTujuh
keduanya memiliki tiga parameter formal, dan tipe data dari tiap parameter
terkait sama. Oleh karena itu, kedua fungsi ini memiliki daftar parameter
formal.
Pengoverloadan fungsi: Menciptakan beberapa
fungsi dengan nama sama.
Sidik sebuah fungsi terdiri-dari nama
fungsi dan daftar parameter formalnya. Dua fungsi memiliki sidik berbeda jika
keduanya memiliki nama sama atau memiliki daftar parameter formal yang berbeda.
(Perhatikan bahwa sidik sebuah fungsi tidak mencakup tipe fungsi (tipe nilai
balik)).
Jika sebuah fungsi dioverload, maka semua fungsi teroverload
dan fungsi dioverload akan memiliki nama sama. Oleh karena itu, semua fungsi yang bernama sama akan
memiliki sidik berbeda jika masing-masing memiliki daftar parameter formal yang
berbeda. Jadi, beberapa kepala fungsi berikut secara tepat mengoverload fungsiXYZ:
void fungsiXYZ()
void fungsiXYZ(int x, double y)
void fungsiXYZ(double satu, int y)
void fungsiXYZ(int x, double y, char ch)
Perhatikan beberapa kepala fungsi
berikut yang dipakai untuk mengoverload fungsiABC:
void fungsiABC(int x, double y)
int fungsiABC(int x, double y)
Kedua kepala fungsi memiliki nama sama
dan daftar parameter formal sama. Oleh karena itu, kedua kepala fungsi yang
dipakai untuk mengoverlod fungsi fungsiABC adalah tidak benar. Pada kasus ini,
kompiler akan membangkitkan error sintaks. (Perhatikan bahwa tipe nilai balik
dari tiap fungsi berbeda).
Jika sebuah fungsi dioverload, maka di dalam sebuah pemanggilan
terhadap fungsi tersebut, sidik fungsi (daftar parameter formal) menentukan
fungsi mana yang akan dieksekusi.
Dimisalkan bahwa Anda perlu menuliskan
sebuah fungsi untuk menentukan yang terbesar dari dua item. Kedua item bisa
integer, angka titik-mengambang, karakter, atau string. Anda dapat menuliskan
beberapa fungsi sebagai berikut:
int terbesarInt(int x, int y);
char terbesarChar(char pertama, char kedua);
double terbesarDouble(double u, double v);
string terbesarString(string pertama, string kedua);
Fugsi terbesarInt menentukan terbesar dari dua integer; fungsi terbesarChar menentukan terbesar dari
dua karakter; dan seterusnya. Semua fungsi ini melakukan operasi yang sama.
Daripada harus memberikan nama yang berbeda
untuk tiap fungsi tersebut, Anda dapat
menggunakan nama sama untuk semua fungsi, katakanlah terbesar. Pada kasus ini, Anda dapat mengoverload fungsi terbesar. Jadi, Anda dapat menuliskan
beberapa prototipe fungsi tersebut menjadi:
int terbesar(int x, int y);
char terbesar(char pertama, char kedua);
double terbesar(double u, double v);
string terbesar(string pertama, string kedua);
Jika pemanggilan adalah terbesar(5, 3), misalnya, maka fungsi
pertama yang dieksekusi. Jika pemanggilan adalah terbesar(‘A’, ‘9’), maka fungsi kedua yang dieksekusi, dan
seterusnya.
Fungsi dengan Parameter Default
Bagian ini akan mendiskusikan fungsi
dengan parameter default. Ingat bahwa ketika sebuah fungsi dipanggil, jumlah
parameter aktual dan parameter formal harus sama. C++ melonggarkan kondisi ini
untuk fungsi dengan parameter formal. Anda menspesifikasi nilai dari sebuah
parameter default ketika nama fungsi muncul di dalam program untuk pertama
kalinya, seperti di dalam prototipe. Secara umum, aturan-aturan berikut diterapkan
terhadap fungsi dengan parameter default:
·
Jika Anda tidak menspesifikasi nilai
dari sebuah parameter default, maka nilai default akan dipakai untuk parameter
tersebut.
·
Semua parameter default harus berupa
parameter far-right dari fungsi.
·
Dimisalkan bahwa sebuah fungsi
memiliki lebih dari satu parameter default. Dalam sebuah pemanggilan fungsi,
jika nilai dari sebuah parameter default tidak dispesifikasi, maka Anda harus
mengabaikan semua argumen yang ada di kanannya.
·
Nilai default dapat berupa konstanta,
variabel global, atau pemanggilan fungsi.
·
Anda tidak dapat menugaskan sebuah
nilai konstanta sebagai nilai default kepada parameter referensi.
Perhatikan prototipe fungsi berikut:
void fungsiEksp(int x, int y, double t, char z = 'A', int u =
67,
char v = 'G', double w = 78.34);
Fungsi fungsiEksp memiliki tujuh parameter. Parameter z, u, v, dan w adalah parameter default. Jika tidak ada nilai yang dispesifikasi
untuk z, u, v, dan w di dalam sebuah pemanggilan terhadap
fungsi fungsiEksp, maka nilai-nilai
defaultnya digunakan.
Dimisalkan bahwa Anda memiliki beberapa
statemen berikut:
int a, b;
char ch;
double
d;
Beberapa pemanggilan fungsi berikut
adalah benar:
fungsiEksp(a, b, d);
fungsiEksp(a, 15, 34.6, 'B', 87, ch);
fungsiEksp(b, a, 14.56, 'D');
Pada statemen 1, nilai default dari z, u,
v, dan w digunakan. Pada statemen 2, nilai default dari z diganti dengan ‘B’, nilai default dari u
digantikan dengan 87, nilai default dari v
digantikan dengan nilai dari ch, dan
nilai default dari w digunakan. Pada
statemen 3, nilai default dari z
digantikan dengan ‘D’, dan nilai
default dari u, v, dan w digunakan.
Beberapa pemanggilan fungsi berikut
adalah tidak benar:
1. fungsiEksp(a, 15,
34.6, 46.7);
2.
fungsiEksp(b, 25, 48.76, 'D', 4567, 78.34);
Pada statemen 1, karena nilai dari z diabaikan, maka semua nilai default
lainnya harus diabaikan. Pada statemen 2, karena nilai dari v diabaikan, maka nilai dari w harus diabaikan pula.
Berikut merupakan beberapa prototipe
fungsi ilegal dengan parameter default:
1.
void fungsiSatu(int
x, double z = 23.45, char ch, int u = 45);
2.
int fungsiDua(int panjang = 1, int lebar, int tinggi = 1);
3.
void fungsiTiga(int
x, int& y = 16, double z = 34);
Pada statemen 1, karena parameter kedua
z adalah parameter default, semua parameter yang berada setelah z harus parameter default. Pada
statemen 2, karena parameter pertama adalah parameter default, semua parameter
lain harus parameter default. Pada statemen 3, nilai konstanta tidak bisa
ditugaskan kepada y karena y adalah parameter referensi.
Contoh 6.10 lebih lanjut
mengilustrasikan beberapa fungsi dengan parameter default.
Contoh 6.110
|
#include <iostream>
#include <iomanip>
using namespace std;
int volume(int l = 1, int w = 1, int h = 1);
void fungsiSatu(int& x, double y = 12.34, char z
= 'B');
int main()
{
int
a = 23;
double
b = 48.78;
char
ch = 'M';
cout << fixed << showpoint;
cout << setprecision(2);
cout << "Baris 1: a = " << a << ", b = "
<< b << ", ch = " << ch << endl; //Baris 1
cout << "Baris 2: Volume = " << volume()
<< endl; //Baris 2
cout << "Baris 3: Volume = " << volume(5, 4)
<< endl; //Baris 3
cout << "Baris 4: Volume = " << volume(34)
<< endl; //Baris 4
cout << "Baris 5: Volume = "
<< volume(6, 4, 5) <<
endl; //Baris
5
fungsiSatu(a); //Baris 6
fungsiSatu(a, 42.68); //Baris 7
fungsiSatu(a, 34.65, 'Q'); //Baris 8
cout << "Baris 9: a = " << a << ", b = "
<< b << ", ch =
" << ch << endl; //Baris
9
return
0;
}
int volume(int l, int w, int h)
{
return
l * w * h; //Baris
10
}
void fungsiSatu(int& x, double y, char z)
{
x = 2 * x; //Baris
11
cout << "Baris 12: x = " << x << ", y = "
<< y << ", z = " << z << endl; //Baris 12
}
Keluaran Program:
Baris 1: a = 23, b = 48.78, ch = M
Baris 2: Volume = 1
Baris 3: Volume = 20
Baris 4: Volume = 34
Baris 5: Volume = 120
Baris 12: x = 46, y = 12.34, z = B
Baris 12: x = 92, y = 42.68, z = B
Baris 12: x = 184, y = 34.65, z = Q
Baris 9: a = 184, b = 48.78, ch = M
CONTOH PEMROGRAMAN: Klasifikasi
Angka
Pada contoh ini, akan digunakan
beberapa fungsi untuk menulis-ulang program yang menentukan angka genap dan
angka ganjil atas sederet integer yang diberikan. Program ini telah dituliskan
pada Bab 4. Algoritma utama tetap sama:
1. Menginisialisasi
variabel nol, ganjil, dan genap dengan
0.
2. Membaca sebuah
angka.
3. Jika angka
genap, maka genap diinkremen, dan jika angka nol, maka nol diinkremen;
sebaliknya, ganjil diinkremen.
4. Mengulangi
langkah 2 dan 3 untuk setiap angka di dalam daftar.
Bagian-bagian utama program adalah:
menginisialisasi variabel, membaca dan mengklasifikasi angka, dan kemudian
menampilkan hasil. Untuk menyederhanakan fungsi main dan lebih lanjut mengilustrasikan pelewatan parameter, program
mencakup:
·
Sebuah fungsi inisialisasi untuk menginisialisasi variabel, seperti nol, ganjil, dan genap.
·
Sebuah fungsi dapatAngka untuk mendapatkan angka.
·
Sebuah fungsi klasifikasiAngka untuk menentukan apakah angka ganjil atau genap
(dan apakah ia juga nol).
·
Sebuah fungsi tampilHasil untuk menampilkan hasil.
Selanjutnya, akan didiskusikan tiap
fungsi ini.
Fungsi
inisialisasi
Fungsi inisialisasi dipakai untuk
menginisialisasi variabel dengan nilai default. Variabl-variabel yang perlu
diinisialisasi adalah nol, ganjil, dan genap. Seperti sebelumnya, semua nilai awalnya adalah nol. Jelaslah
bahwa fungsi ini memiliki tiga parameter. Karena nilai dari tiap parameter
formal yang menginisialisasi tiap variabel ini harus dilewatkan ke luar fungsi,
ketiga parameter formal ini harus berupa parameter referensi. Fungsi ini
didefinisikan sebagai berikut:
void inisialisasi(int& hitungNol, int& hitungGanjil, int& hitungGenap)
{
hitungNol = 0;
hitungGanjil = 0;
hitungGenap = 0;
}
Fungsi
dapatAngka
Fungsi dapatAngka membaca sebuah angka dan kemudian melewatkan angka ini
kepada fungsi main. Karena Anda hanya perlu melewatkan satu angka, fungsi ini
hanya memiliki satu parameter. Parameter formal fungsi ini harus berupa
parameter referensi karena angka yang dibaca dilewatkan ke luar fungsi. Fungsi
ini didefinisikan sebagai berikut:
void dapatAngka(int& angka)
{
cin >> angka;
}
Anda dapat pula menuliskan fungsi dapatAngka sebagai fungsi penghasil
nilai.
Fungsi
klasifikasiAngka
Fungsi klasifikasiAngka menentukan apakah angka berupa angka ganjil atau
angka genap, dan jika angka genap, ia juga memeriksa apakah angka itu nol.
Fungsi ini juga memperbarui nilai dari beberapa variabel nol, ganjil, dan genap. Fungsi ini perlu mengetahui
angka yang akan dianalisa; oleh karena itu, angka harus dilewatkan sebagai
parameter. Karena fungsi ini juga menginkremen penghitungan tertentu, beberapa
variabel (variabel nol, ganjil, dan genap yang dideklarasikan di dalam main) yang memuat penghitungan harus dideklarasikan sebagai
parameter kepada fungsi ini. Jadi, fungsi ini memiliki empat parameter.
Karena angka hanya akan dianalisa, Anda
hanya perlu melewatkan nilainya. Jadi, parameter formal yang terkait dengan
variabel ini adalah parameter nilai. Setelah menganalisa angka, fungsi ini
menginkrmen nilai dari tiap variabel, nol,
ganjil, dan genap. Oleh karena itu, tiap parameter formal yang berkaitan dengan
variabel ini harus berupa parameter referensi. Algoritma untuk menganalisa
angka dan menginkremen penghitungan tertentu sama seperti sebelumnya. Fungsi
ini didefinisikan sebagai berikut:
void klasifikasiAngka(int angka, int& hitungNol, int& hitungGanjil,
int& hitungGenap)
{
switch (angka % 2)
{
case 0:
hitungGenap++;
if (angka == 0)
hitungNol++;
break;
case 1:
case -1:
hitungGanjil++;
} //akhir switch
} //akhir klasifikasiAngka
Fungsi
tampilHasil
Fungsi tampilHasil menampilkan hasil akhir. Untuk menampilkan hasil
(yaitu, jumlah nol, jumlah genap, dan jumlah ganjil), fungsi ini harus memiliki
akses terhadap tiap variabel nol, ganjil, dan genap yang dideklarasikan di dalam fungsi main. Oleh karena itu, fungsi ini memiliki tiga parameter. Karena
fungsi ini hanya menampilkan tiap nilai variabel, tiap parameter adalah
parameter nilai. Fungsi ini didefinisikan sebagai berikut:
void tampilHasil(int hitungNol, int hitungGanjil, int hitungGenap)
{
cout << "Terdapat " << hitungGenap <<
" genap, "
<< "yang mencakup " << hitungNol << " nol"
<< endl;
cout << "Jumlah angka ganjil adalah: " << hitungGanjil
<< endl;
} //akhir tampilHasil
Algoritma
Utama
1. Memanggil
fungsi inisialisasi untuk menginisialisasi variabel-variabel.
2. Meminta
pengguna untuk memasukkan 20 angka.
3. Untuk tiap
angka di dalam daftar:
a.
Memanggil fungsi dapatAngka untuk membaca sebuah angka.
b.
Menampilkan angka.
c.
Memanggil fungsi klasifikasiAngka untuk mengklasifikasi
angka dan menginkremen penghitungan tertentu.
4.
Memanggil fungsi tampilHasil untuk menampilkan hasil
akhir.
Program
Utuh
//******************************************************************
// Program:
Klasifikasi Angka
// Program ini
membaca 20 angka dan menampilkan jumlah angka nol,
// ganjil, dan
genap.
//******************************************************************
#include <iostream>
#include <iomanip>
using namespace std;
const int N = 20;
//Prototipe fungsi
void inisialisasi(int& hitungNol, int& hitungGanjil, int& hitungGenap);
void dapatAngka(int& angka);
void klasifikasiAngka(int angka,
int& hitungNol, int& hitungGanjil, int& hitungGenap);
void tampilHasil(int hitungNol, int hitungGanjil, int
hitungGenap);
int main()
{
//Deklarasi variabel
int
kounter; //variabel kendali loop
int
angka; //variabel untuk menyimpan
angka baru
int
nol; //variabel untuk menyimpan
jumlah angka nol
int
ganjil; //variabel untuk menyimpan
jumlah angka ganjil
int
genap; //variabel untuk menyimpan
jumlah angka genap
inisialisasi(nol, ganjil, genap); //Langkah 1
cout << "Masukkan sebanyak " << N << " integer."
<< endl; //Langkah 2
cout << "Angka-Angka yang Anda masukkan adalah: "
<< endl;
for
(kounter = 1; kounter <= N; kounter++) //Langkah
3
{
dapatAngka(angka); //Langkah 3a
cout << angka << "
"; //Langkah
3b
klasifikasiAngka(angka, nol, ganjil,
genap); //Langkah 3c
} // akhir loop for
cout << endl;
tampilHasil(nol, ganjil, genap); //Langkah 4
return
0;
}
void inisialisasi(int& hitungNol, int& hitungGanjil, int& hitungGenap)
{
hitungNol = 0;
hitungGanjil = 0;
hitungGenap = 0;
}
void dapatAngka(int& angka)
{
cin >> angka;
}
void klasifikasiAngka(int angka, int& hitungNol, int&
hitungGanjil,
int& hitungGenap)
{
switch
(angka % 2)
{
case
0:
hitungGenap++;
if (angka == 0)
hitungNol++;
break;
case
1:
case
-1:
hitungGanjil++;
} //akhir switch
} //akhir
klasifikasiAngka
void tampilHasil(int hitungNol, int hitungGanjil, int
hitungGenap)
{
cout << "Terdapat " << hitungGenap << " genap, "
<< "yang mencakup "
<< hitungNol << " nol"
<< endl;
cout << "Jumlah angka ganjil adalah:
" << hitungGanjil
<< endl;
} //akhir
tampilHasil
Keluaran Program:
Masukkan sebanyak 20 integer.
Angka-Angka yang Anda masukkan adalah:
0 0 12 34 -3 -9 -57 89 48 65 78 0 0 23 32 0 0 0 21 45
0 0 12 34 -3 -9 -57 89 48 65 78 0 0 23 32 0 0 0 21 45
Terdapat 12 genap, yang mencakup 7 nol
Jumlah angka ganjil adalah: 8
No comments:
Post a Comment