• Tidak ada hasil yang ditemukan

Pernyataan: Background Cover ini menunjukkan Keaslian Ebook ini yang sesuai / sama dengan Cover CD depan aslinya. Dan bila background / Cover setiap

N/A
N/A
Protected

Academic year: 2021

Membagikan "Pernyataan: Background Cover ini menunjukkan Keaslian Ebook ini yang sesuai / sama dengan Cover CD depan aslinya. Dan bila background / Cover setiap"

Copied!
151
0
0

Teks penuh

(1)

Pernyataan:

(2)

Mahir dan

Professional

Pemograman C++

vize@telkom.net

IlmuKomputer.Com

Mahir dan professional

Pemograman C++

Penulis : Muhammad Syahrizal

(3)

Kutipan Pasal 44, Ayat 1 dan 2, Undang-Undang Republik Indonesia tentang HAK CIPTA:

Tentang Sanksi Pelanggaran Undang-Undang Nomor 6 Tahun 1982 tentang HAK CIPTA, sebgaimana telah diubah dengan Undang-Undang No.7 Tahun 1987 jo. Undang-Undang No.12 Tahun 1997, bahwa:

1. Barangsiapa dengan sengaja dan tanpa hak mengumumkan atau Memperbanyak suatu ciptaan atau memberi izin untuk itu, dipidana dengan pidana penjara paling lama 7 (tujuh) tahun dan/atau denda paling banyak Rp.100.000.000,- (seratus juta rupiah).

2. Barangsiapa dengan sengaja menyiarkan, memamerkan,

mengedarkan, atau menjual kepada umum suatu ciptaan atau barang hasil pelanggaran Hak Cipta sebagaimana dimaksud dalam ayat (1), dipidana dengan pidana penjara paling lama 5 (lima) tahun dan/atau denda paling banyak Rp.50.000.000,- (lima puluh juta rupiah).

(4)

Mahir dan Professional

Pemograman C++

Muhammad Syahrizal

©2007, Gratech Media Perkasa, Medan Hak cipta dilindungi undang-undang Diterbitkan pertama kali oleh

Penerbit Gratech Media Perkasa

Dilarang keras menerjemahkan, memfotokopi, atau memperbanyak sebagian atau seluruh isi buku ini tanpa izin tertulis dari penerbit.

(5)

Algoritma

dalam

Bahasa C

Apa Itu Algoritma

Kata algoritma, mungkin bukan sesuatu yang asing bagi kita.

Penemunya adalah seorang ahli matematika dari Uzbekistan yang bernama Abu Abdullah Muhammad Ibn Musa al- Khwarizmi (770-840). Di literatur barat dia lebih terkenal

dengan sebutan Algorizm. Panggilan inilah yang kemudian dipakai untuk menyebut konsep algorithm yang ditemukannya.

Dalam bahasa Indonesia kita kemudian menyebutkannya sebagai algoritma.

Algoritma adalah kunci dari bidang ilmu komputer, karena banyak bidang di bawah ilmu komputer yang lahir berdasarkan konsep algoritma ini. Pada hakekatnya algoritma juga adalah kunci dari kehidupan kita. Cara membuat masakan (resep masakan) adalah juga sebuah contoh nyata dari algoritma.

Definisi Algoritma

Kita bisa mendefinisikan algoritma seperti dibawah:

Algoritma adalah logika, metode dan tahapan (urutan) sistematis yang digunakan untuk memecahkan suatu permasalahan.

Kamus besar bahasa Indonesia (Balai Pustaka 1988) secara formal mendefinisikan algoritma sebagai:

Algoritma adalah urutan logis pengambilan putusan untuk pemecahan masalah.

Beda Algoritma dan Program

Program adalah kompulan instruksi komputer, sedangkan metode dan tahapan sistematis dalam program adalah algoritma. Program ini ditulis dengan menggunakan bahasa pemrograman. Jadi bisa kita sebut bahwa program adalah suatu implementasi dari bahasa pemrograman.

Beberapa pakar memberi formula bahwa: program = struktur data + algoritma

(6)

Bagaimanapun juga struktur data dan algoritma berhubungan sangat erat pada sebuah program. Algoritma yang baik tanpa pemilihan struktur data yang tepat akan membuat program menjadi kurang baik, semikian juga sebaliknya.

Struktur data disini bisa berupa list, tree, graph, dsb. Akan dibahas secara mendetail pada bab-bab mendatang.

Menilai Sebuah Algoritma

Ketika manusia berusaha memecahkan masalah, metode atau teknik yang digunakan untuk memecahkan masalah itu ada kemungkinan bisa banyak (tidak hanya satu). Dan kita memilih mana yang terbaik diantara teknik-teknik itu. Hal ini sama juga dengan algoritma, yang memungkinkan suatu permasalahan dipecahkan dengan metode dan logika yang berlainan.

Lalu bagaimana mengukur mana algoritma yang terbaik ?

Beberapa persyaratan untuk menjadi algoritma yang baik adalah:

• Tingkat kepercayaannya tinggi (realibility). Hasil yang diperoleh dari proses harus berakurasi tinggi dan benar.

• Pemrosesan yang efisien (cost rendah). Proses harus diselesaikan secepat mungkin dan frekuensi kalkulasi yang sependek mungkin.

• Sifatnya general. Bukan sesuatu yang hanya untuk menyelesaikan satu kasus saja, tapi juga untuk kasus lain yang lebih general.

• Bisa Dikembangkan (expandable). Haruslah sesuatu yang dapat kita kembangkan lebih jauh berdasarkan perubahan requirement yang ada.

• Mudah dimengerti. Siapapun yang melihat, dia akan bisa memahami algoritma anda. Susah dimengertinya suatu program akan membuat susah di maintenance (kelola).

• Portabilitas yang tinggi (Portability). Bisa dengan mudah diimplementasikan di berbagai platform komputer.

Contoh Algoritma dan Implementasinya

Sebagai contoh sederhana, mari kita berlatih melihat permasalahan, mencoba menyusun algoritma, dan meng-implementasi-kan dalam bahasa C.

Permasalahan

Anda adalah seorang guru SD yang ingin membuat rangking dari nilai ujian dari 9 orang murid anda. Nilai ujian murid anda adalah sebagai berikut:

Bagaimana algoritma dalam pembuatan rangking nilai tersebut ?

Untuk memecahkan masalah diatas, kita bisa susun algoritma seperti dibawah: 1. Buat satu variable (misalnya rangking)

2. Set variable rangking = 1

3. Ambil satu nilai sebagai data yang ke a, misalnya 56

4. Chek nilai dari paling depan (56) sampai paling belakang (32) (b=0-8). Apabila nilai tersebut lebih tinggi daripada nilai ke a (56), maka set variable rangking = ranking + 1.

(7)

Kemudian mari kita implementasikan algoritma diatas dalam program bahasa C.

Program: Rangking Nilai Ujian

#include <stdio.h> #define banyaknya_nilai 9 main(){

static int nilai[]={56, 78, 43, 96, 67, 83, 51, 74, 32}; int rangking[banyaknya_nilai]; int a,b; for (a=0;a<banyaknya_nilai;a++){ rangking[a]=1; for (b=0;b<banyaknya_nilai;b++){ if (nilai[a]>nilai[b]) rangking[a]++; } }

printf("Nilai Ujian \t Rangking\n"); for (a=0;a<banyaknya_nilai;a++){ printf("%d \t\t %d\n",nilai[a], rangking[a]); }

}

Hasil

Nilai Ujian Rangking 56 4 78 7 43 2 96 9 67 5 83 8 51 3 74 6 32 1

(8)

Membilang dalam Bahasa

Indonesia

Dalam aplikasi yang berhubungan dengan uang , kadang – kadang diperlukan pernyataan nilai nominal tidak hanya dengan angka , tapi juga diperlukan pernyataan dalam bentuk terbilangnya. Tentu saja jika dibandingkan dengan pernyataan dengan angka , pernyataan dengan membilang lebih banyak membutuhkan ruang . Tapi disamping itu pernyataan dengan membilang bisa meminimkan jumlah kesalahan yang terjadi karena faktor kesalahan pembacaan .

Untuk itu dalam kesempatan ini kita akan membuat sebuah fungsi yang dapat digunakan untuk merubah nilai menjadi bentuk terbilangnya. Di internet , tentunya sudah sangat banyak sekali source code yang di publish untuk keperluan ini , bahkan dengan listing yang cukup pendek. Tapi tentunya sebagai programer kita akan lebih tertantang jika mampu membuat fungsi tersebut sendiri . Untuk akan saya bahas alur / logika

pemrogramannya , sehingga mudah untuk di translasikan dalam bahasa pemrograman lain.

Untuk bisa membuat fungsi membilang dalam bahasa Indonesia kita harus tahu dulu , cara manusia membilang bilangan . Untuk itu mari kita analisa proses tersebut !!!!! Bilangan satuan

0 -> nol 1 -> satu 9 -> sembilan

Ket : “->” berarti “dibaca”

Untuk proses membilang bilangan satuan tentunya tidak terlalu susah jika di

implementasikan dalam bahasa C . Anda bisa menggunakan seleksi untuk masing masing bilangan . Tapi penulis akan menggunakan bantuan array

Berikut ialah potongan source codenya fungsi untuk membilang bilangan satuan char StrBilangan[10][10] =

{"nol","satu","dua","tiga","empat","lima","enam","tujuh","delapan","sembi lan"};

void SaySatuan(char nilai) //0..9 { printf("%s",StrBilangan[nilai]); } Bilangan puluhan 10 -> sepuluh 11 -> sebelas 12 -> dua belas 13 -> tiga belas 19 -> sembilan belas 20 -> dua puluh

(9)

21 -> dua puluh satu 45 -> empat puluh lima 99 -> sembilan puluh delapan

Secara umum untuk membilang bilangan puluhan bisa dilakukan dengan cara membilang puluhannya secara satuan dan kemudian diikuti dengan “puluh” dan dilanjutkan dengan membilang satuannya jika nilaisatuannya bukan 0.

Untuk lebih jelas mari kita perhatikan contoh berikut Contoh : Kita akan membilang nilai 35

Kita ambil puluhannya dahulu . Untuk mengambil nilai puluhannya bisa didapat dengan membaginya dengan 10 .

NilaiPuluhan = 35 / 10 = 3

Nilai Satuan bisa didapat dengan mengambil sisa pembagian dengan bilangan 10 NilaiSatuan = 35 % 10 = 5

Nah setelah dapat kita tinggal menggunakan cara diatas :

SaySatuan(NilaiPuluhan) + “puluh” + SaySatuan(NilaiSatuan)*SaySatuan ialah fungsi untuk mencetak nilai satuan .Maka akan terbentuk tiga puluh lima Contoh berikutnya kita ambil 40

NilaiPuluhan = 4 NilaiSatuan = 0

Karena nilai satuan sama dengan 0 untuk itu kita tidak perlu membilang nilai satuannya jadi cukup dengan :

SaySatuan(NilaiPuluhan) + “puluh” Maka akan didapat hasil “empat puluh"

Jadi jelaslah maksud kata jika nilainya bukan 0 , yaitu untuk menghindari terjadinya (pada kasus 40) tercetak empat puluh nol Cara diatas memang benar untuk sebagian besar nilai puluhan tapi ada beberapa nilai yang perlu perkecualian . Dari contoh data analisa diatas dapat dilihat bahwa nilai 10,11,12 .. 19 tidak memenuhi cara diatas. Tapi jika dianalisa lebih lanjut bilangan 12..19 ternyata memiliki pola yang sama yaitu : membilang satuan dan diikuti dengan kata belas Untuk contoh saya ambil 14. NilaiSatuan = 4 .

Maka dengan menggunakan cara diatas : SaySatuan(NilaiSatuan) + “belas”

Untuk 10 dan 11 anda bisa gunakan seleksi biasa .

Berikut ialah source code untuk membilang bilangan puluhan . void SayPuluhan(char nilai) // 10..99

{

if (nilai < 10) // seleksi , jika lebih kecil dari 10

SaySatuan(nilai); // tentunya masuk ke fungsi SaySatuan else

{

if (nilai == 10) printf("sepuluh");

(10)

if (nilai == 11) printf("sebelas");

if (nilai >= 12 && nilai <= 19)//Cetak satuan diikuti dengan belas {

SaySatuan(nilai % 10); // Satuan bisa dicari dengan memodulo printf("belas"); // bilangan dengan 10 ( mencari hasil sisa } // pembagian

if (nilai >= 20 && nilai <= 99) //Cetak puluhan diikuti kata puluh { // kemudian cetak satuan

SaySatuan(nilai / 10); // Nilai Puluhan bisa dicari dengan printf(" puluh "); // membaginya dengan 10

SaySatuan(nilai % 10); } } } Bilangan ratusan 100 -> seratus 101 -> seratus satu 110 -> seratus sepuluh

189 -> seratus delapan puluh sembilan 200 -> dua ratus

201 -> dua ratus satu

999 -> sembilan ratus sembilan puluh sembilan

Dapat dilihat bilangan ratusan juga memilik pola yang secara umum hampir sama yaitu : membilang nilai ratusannya diikuti kata ratus dan dilanjutkan dengan membilang nilai puluhannya jika nilai puluhannya bukan 0.

Kita ambil contoh 223 NilaiRatusan = 223 / 100= 2 NilaiPuluhan = 223 % 100 = 23 Dengan cara diatas didapat :

SaySatuan(NilaiRatusan) + “ratus” + SayPuluhan(NilaiPuluhan) Tentunya jika fungsi SayPuluhan anda benar akan tercetak : dua ratus dua puluh tiga

Untuk perkecualian yaitu bilangan antara 100..199 . Untuk bilangan tersebut dapat dibilang dengan rumus Cetak “seratus” diikuti dengan membilang bilanga puluhannya Berikut ialah cuplikan SourceCodenya dalam C

void SayRatusan(int nilai) // 100..999 {

if (nilai < 100)

SayPuluhan(nilai); // seleksi , jika puluhan else

{

if(nilai >= 100 && nilai <= 199) // jika dibawah 200 gunakan kata printf("seratus "); // seratus

(11)

if (nilai >= 200 && nilai <= 999) // jika diatasnya , bilang nilai { // ratusannya diikuti dengan kata

SaySatuan(nilai / 100); printf(" ratus "); // ratus }

if(nilai % 100 != 0) //Hindari jika kelipatan 100 SayPuluhan(nilai % 100); //Bilang nilai puluhannya }

}

Bilangan ribuan 1.000 -> seribu

1.100 -> seribu seratus

2.111 -> dua ribu seratus sebelas 10.000 -> sepuluh ribu

25.250 -> dua puluh lima ribu dua ratus lima puluh 130.750 -> seratus tiga puluh ribu , tujuh ratus lima puluh

999.999 -> sembilan ratus sembilan puluh sembilan ribu , sembilan ratus sembilan puluh sembilan

Jika diperhatikan ternyata untuk mencetak bilangan ribuan caranya sama sampai

mencetak bilangan ratusan ribu yaitu : bilang nilai ribuannya diikuti dengan kata “ribu” dan dilanjutkan dengan bilang nilai ratusannya jika nilai ratusannya bukan 0.

Sebagai contoh saya akan ambil 256.750 NilaiRibuan = 256.750 / 1000 = 256 NilaiRatusan = 256.750 % 1000 = 750 Dengan menggunakan cara diatas :

SayRatusan(NilaiRibuan) + “ribu” + SayRatusan(NilaiRibuan) Tentunya jika Fungsi SayRatusan anda benar akan tercipta : dua ratus lima puluh enam ribu tujuh ratus lima puluh

Dan seperti biasa perkecualian terdapat pada bilangan antara 1000..1999 , yaitu cukup dengan mencetak “seribu” diikuti dengan membilang nilai ratusannya jika tidak 0

void SayRibuan(unsigned long nilai) //1000...999999 {

if (nilai < 1000)

SayRatusan(nilai); //Seleksi jika ratusan else

{

if (nilai >= 1000 && nilai <= 1999) //Seleksi nilai dibawah 2000 printf("Seribu ");

if (nilai >= 2000 && nilai <= 999999) {

SayRatusan(nilai/1000); //Cetak digit ribuan secara Ratusan printf(" ribu "); // diikuti kata ribu

}

if (nilai % 1000 != 0) // seleksi kelipatan 1000

SayRatusan(nilai % 1000); // diikuti dengan mencetak digit sisanya }

(12)

Begitu pula halnya untuk bilangan diatas 999.999 . Tidak terlalu susah bukan ? Ternyata untuk membuat fungsi membilang anda hanya perlu operator bagi (/) dan modulus (%), dan tentunya sedikit analisa Sebenarnya program diatas masih cukup panjang dan tentunya masih bisa dipendekkan dan dioptimasi lagi. Nah untuk tugas ini saya serahkan sepenuhnya kepada pembaca saja .

Berikut ialah source code lengkap program membilang tersebut #include <stdio.h>

char StrBilangan[10][10] =

{"nol","satu","dua","tiga","empat","lima","enam","tujuh","delapan","sembi lan"};

void SaySatuan(char nilai) //0..9 {

printf("%s",StrBilangan[nilai]); }

void SayPuluhan(char nilai) // 10..99 { if (nilai < 10) SaySatuan(nilai); else { if (nilai == 10) printf("sepuluh"); if (nilai == 11) printf("sebelas");

if (nilai >= 12 && nilai <= 19) {

SaySatuan(nilai % 10); printf("belas");

}

if (nilai >= 20 && nilai <= 99) { SaySatuan(nilai / 10); printf(" puluh "); SaySatuan(nilai % 10); } } }

void SayRatusan(int nilai) // 100..999 {

if (nilai < 100) SayPuluhan(nilai); else

{

if(nilai >= 100 && nilai <= 199) printf("seratus ");

if (nilai >= 200 && nilai <= 999) {

SaySatuan(nilai / 100); printf(" ratus ");

}

if(nilai % 100 != 0) //untuk menghindari seratus nol SayPuluhan(nilai % 100);

(13)

}

void SayRibuan(unsigned long nilai) //1000...999999 {

if (nilai < 1000) SayRatusan(nilai); else

{

if (nilai >= 1000 && nilai <= 1999) printf("Seribu ");

if (nilai >= 2000 && nilai <= 999999) { SayRatusan(nilai/1000); printf(" ribu "); } if (nilai % 1000 != 0) SayRatusan(nilai % 1000); } }

void SayJuta(unsigned long nilai) //1.000.000 -> 999.999.999 { if (nilai < 1000000) SayRibuan(nilai); else { SayRatusan(nilai / 1000000); printf(" juta "); if(nilai % 1000000 != 0) SayRibuan(nilai % 1000000); } }

void SayMilyar(unsigned long nilai) // 1.000.000.000 -> 999.999.999.999 { if (nilai < 1000000000) SayJuta(nilai); else { SayRatusan(nilai / 1000000000); printf(" Milyar "); if(nilai % 1000000000 != 0) SayJuta(nilai % 1000000000); } }

void SayBilangan(unsigned long nilai) // Fungsi pengarah {

if (nilai <= 9) SaySatuan(nilai);

if (nilai >= 10 && nilai <= 99) SayPuluhan(nilai);

if (nilai >= 100 && nilai <= 999) SayRatusan(nilai);

if(nilai >= 1000 && nilai <= 999999) SayRibuan(nilai);

if(nilai >= 1000000 && nilai <= 999999999) SayJuta(nilai);

if(nilai >= 1000000000) SayMilyar(nilai);

(14)

} void main(void) { SayBilangan(163); SayBilangan(25234); SayBilangan(-1); }

Analisa Numerik:

Mengecek Bilangan Prima

Bilangan Prima ialah Bilangan yang hanya memiliki 2 faktor yaitu , 1 dan bilangan itu sendiri.

Contoh :

7 merupakan bilangan Prima karena 7 hanya memiliki 2 faktor yaitu 1 dan 7 saja 8 bukan merupakan bilangan Prima karena 8 bisa memiliki lebih dari 2 faktor yaitu : 1 2 4 8

Dengan menggunakan pengertian diatas dapat dibuat algoritma : 1. Input N // N = Bilangan Prima yang akan di cek

2. counter = 0 // counter menyatakan jumlah faktor

3. FOR I = 1 to N step = 1 // step langkah setiap perulangan (i++)

Jika N % I == 0 maka // Jika N habis di bagi I counter++ //Tambahkan Counter 4. Jika counter == 2 maka “N Bilangan Prima”

Jika Tidak “N Bukan Bilangan Prima”

Jika kita telaah lebih lanjut , untuk mengecek bilangan ke N maka diperlukan N kali iterasi (langkah 3 ) . Oke kalau begitu mari kita sederhanakan lagi Kita tahu bahwa 1. Bilangan genap kecuali 2 bukan merupakan bilangan prima

2. Bilangan Genap ialah bilangan yang kelipatan 2

3. Setiap Bilangan pasti memiliki faktor 1 dan bilangan itu sendiri

Karena semua bilangan genap kecuali bukan prima dan Bilangan genap merupakan kelipatan 2 jadi kita dapat menskip pembagian dengan bilangan genap (step = 2) asalkan pertama kali dilakukan pengecekan bilangan genap.

Karena Setiap bilangan pasti memiliki faktor 1 dan bilangan itu sendiri jadi kita tidak perlu mencek 1 dan bilangan itu sendiri , tapi cukup mulai dari 2 sampai dengan n -1 .Jika ada faktor pada range tersebut sudah barang tentu bahwa bilangan tersebut bukan bilangan prima.

(15)

Baiklah mari kita sempurnakan algoritmanya 1. Input N

2. Jika N == 2 maka // 2 Merupakan Bilangan Prima “N Bilangan Prima”

3. Jika N % 2 == 0 maka // Bilangan Genap bukan bilangan Prima “N Bukan Bilangan Prima”

4. FOR I = 3 To N-1 STEP 2 // Tidak perlu mengadakan pengecekan

Jika N % I == 0 maka // terhadap bilangan genap “N Bukan Bilangan Prima” 5. “N Bilangan Prima

Dengan sedikit analisis , algoritma diatas telah mampu dioptimasi . Jika sebelumnya untuk mengecek bilangan ke N pasti memerlukan N iterasi . Maka pada keadaan sekarang jika bilangan itu bilangan genap maka tidak perlu itersi ( best case ) jika bukan bilangan genap maka diperlukan paling banyak N / 2 iterasi ( worst case ) .

Ternyata ada sebuah optimasi lagi yang dapat dilakukan . Apa itu ??? . Sebelumnya mari kita lihat sama – sama tabel di bawah ini:

Tabel Diatas ialah Tabel Faktor dari 8 .

Kalau diperhatikan ternyata pada nilai 4 ( kolom 1 baris 3 ) sudah ada pada kolom 2 . Contoh lain

Tabel diatas ialah Tabel Faktor dari 12 . Kalau diperhatikan ternyata nilai 4 (kolom 1 baris)sudah ada pada kolom 2 .

Apa yang bisa diambil dari contoh diatas ? , apa yang bisa dimanfaatkan untuk mengoptimasi algoritma pengecekan bilangan prima diatas ??

Dari tabel dapat disimpulkan : faktor 8 :

(16)

pada kasus nilai 8 tidak perlu diadakan pengecekan melebihi dari nilai 2 faktor 12 :

12 : 1 = 12 ; 12 : 2 = 6 ; 12 : 3 = 4 ; 12 : 4 = 3 dst

pada kasus nilai 12 tidak perlu diadakan pengecekan melebihi dari nilai 3 Artinya kita tidak perlu mengecek semua faktor dari bilangan. melainkan cukup setengahnya dari faktornya saja yaitu pada akar dari bilangan tersebut , karena faktor sisanya merupakan hasil pembagian dari bilangan tersebut dengan faktornya .

Nah dengan analisis tersebut algoritma diatas dapat disederhanakan menjadi : 1. Input N

2. Jika N == 2 maka “N Bilangan Prima” 3. Jika N % 2 == 0 maka “N Bukan Bilangan Prima”

4. FOR I = 3 To Sqrt(N) STEP 2 // Sqrt(N) -> Akar dari N Jika N % I == 0 maka “N Bukan Bilangan Prima” 5. “N Bilangan Prima

Algoritma diatas membutuhkan 0 itersi saat N bilangan genap . Sedangkan membutuhkan maksimum Akar(N) iterasi saat bilangan tersebut bukan bilangan genap .

Berikut Source code lengkap dari algoritma diatas . #include <stdio.h> #include <math.h> int isprima(int n) { int li; if (n == 2) return 1; if (n % 2 == 0 || n == 1) return 0;

for(li = 3;li <= sqrt(n);li+=2) { if (n%li == 0) return 0; } return 1; } void main(void) { int li;

printf("Bilangan prima dari 1 sampai 100 : \n"); for(li = 1;li<=100;li++)

if (isprima(li)) printf("%3d",li); }

Berikut Hasil dari source code diatas :

Bilangan Prima dari 1 sampai 100 :

(17)

Rekurs

i

if

Pengenalan

Rekursif ialah salah satu teknik pemrograman dengan cara memanggil sebuah fungsi dari dirinya sendiri, baik itu secara langsung maupun tidak langsung. Pemanggilan fungsi rekursif secara langsung berarti dalam fungsi tersebut terdapat statement untuk memanggil dirinya sendiri sedangkan secara tidak langsung berarti fungsi rekursif tersebut memanggil 1 atau lebih fungsi lain sebelum memanggil dirinya sendiri.

Fungsi Rekursif Tak Langsung

Rekursif tidak selalu lebih jelek daripada iteratif . Ada kalanya sebuah fungsi rekursif justru mempermudah penyelesaian masalah yang ditemui pada kasus iteratif

(pengulangan)

Kelemahan pada proses rekursif antar lain, memerlukan tempat penampungan stack yang cukup besar. Karena setiap kali pemanggilan fungsi , register – register seperti cs ( untuk memory far ) dan ip harus disimpan , belum lagi untuk penanganan local variable serta parameter fungsi yang tentunya membutuhkan ruang untuk stack lebih banyak lagi . Selain itu karena setiap pemanggilan fungsi , register dan memory harus di push ke stack maka setelah selesai pemanggilan perlu diadakannya pop stack . untuk mengembalikan memory dan register kembali ke keadaan awal , ini sering disebut sebagai overhead .

Proses Rekursif

Untuk dapat memahami proses yang terjadi dalam sebuah fungsi rekursif , marilah kita simak contoh fungsi rekursif berikut :

(18)

Misalkan Fungsi tersebut dipanggil dengan nilai a = 3 dan b = 3 maka pertama tama di cek apakah b = 0 (if (b == 0) return), jika sama maka keluar. Ternyata nilai b tidak

sama dengan 0 maka tambahkan a dengan 1 dan kurangi b dengan 1 . Maka keadaan sekarang menjadi a = 4 dan b = 2 . Baris berikutnya menampilkan nilai a dan b ke layar (printf("Masuk -> a = %d || b = %d \n",a,b)). Kemudian panggil fungsi rekursi

dengan nilai a = 4 dan b = 2 . Langkah – langkah tersebut diulang terus sampai

pemanggilan fungsi rekursi dengan nilai a = 6 dan b = 0. Pada saat ini kondisi if bernilai benar sehingga fungsi akan keluar (return) dan melanjutkan perintah setelah pemanggilan fungsi rekursi dengan a = 6 dan b = 0. Yaitu mencetak nilai a dan b (printf("Keluar -> a = %d || b = %d \n",a,b)). Setelah mencetak nilai a dan b maka fungsi rekursif

akan keluar lagi , dan melanjutkan perintah setelah pemanggilan fungsi rekursif sebelumnya dimana nilai a = 5 dan b = 1 . Demikian seterusnya sampai nilai a = 4 dan nilai b = 2. yang tidak lain pemanggilan fungsi rekurif yang pertama. Proses pemanggilan fungsi rekursif dapat diilustrasikan :

Langkah ke : 1. a = 4 ; b = 2 . Cetak : Masuk -> a = 4 || b = 2 2. a = 5 ; b = 1 . Cetak : Masuk -> a = 5 || b = 1 3. a = 6 ; b = 0 . Cetak : Masuk -> a = 6 || b = 0 4. a = 6 ; b = 0 , Cetak : Keluar -> a = 6 || b = 0 5. a = 5 ; b = 1 , Cetak : Keluar -> a = 5 || b = 1 6. a = 4 ; b = 2 , Cetak : Keluar -> a = 4 || b = 2

(19)

Untuk memperjelas lagi penggunaan fungsi rekursif dibawah ini akan di berikan contoh contoh program dengan menggunakan rekursif .

Menghitung Nilai Faktorial dan Fibonacci Dengan Rekursif

Untuk menghitung nilai faktorial bilangan bulat positif marilah kita daftarkan dulu nilai – nilai faktorial untuk mempermudah pengambilan algoritma .

0! = 1 1! = 1

2! = 2 x 1 N! = N x (N – 1) ! 3! = 3 x 2 x 1 = 3 x 2! 4! = 4 x 3 x 2 x 1 = 4 x 3!

Untuk Mencari Bilangan Fibonacci juga sama . Sebelumnya mari kita daftarkan dulu bilangan Fibonacci untuk mempermudah pencarian algoritma .

1 1 2 3 5 8 13 ... Dapat dilihat bahwa Fibo(0) = 1

Fibo(1) = 1

Fibo(2) = Fibo(1) + Fibo(0) = 1 + 1 = 2 Fibo(3) = Fibo(2) + Fibo(1) = 2 + 1 = 3

Untuk Listing Program dalam bahasa C saya serahkan ke pembaca sebagai latihan.

Menara Hanoi

Menara Hanoi ialah salah satu permainan yang dulunya dimainkan oleh seorang pendeta di Hanoi . Tujuan permainan ini ialah memindahkan n buah pringan dari tonggak asal (A) melalui tonggak bantu (B) menuju tonggak tujuan (C) .Dengan aturan – aturan bahwa piringan yang lebih kecil tidak boleh berada di bawah piringan yang lebih besar .

Seperti biasa untuk memecahkan masalah kita daftarkan dulu langkah – langka yang diambil mulai n = 1. Dengan dfinisi piringan yang paling atas ialah piringan 1. Untuk n = 1 :

- Pindahkan piringan 1 dari A ke C Untuk n = 2 :

- Pindahkan piringan 1 dari A ke B - Pindahkan piringan 2 dari A ke C - Pindahkan piringan 3 dari B ke C

(20)

Dari contoh diatas dapat diambil kesimpulan , untuk memindahkan N piringan dari tonggak asal (A) ke tonggak tujuan (C) maka piringan ke N harus berada di tonggak tujuan (C) , sedangkan piringan ke 1 sampai (N - 1) harus berada di tonggak bantu (B). Setelah piringan ke 1 sampai (N-1) berada pada tonggak bantu (B) , kemudian pindahkan piringan ke 1 sampai (n-1) tersebut dari tonggak bantu (B) ke tonggak tujuan (C) Nah bagaimana caranya membawa piringan ke 1 sampai (N-1) dari tonggak asal ke tonggak bantu (B) , caranya sama saja yaitu dengan memindahkan piringan ke (n-1) dari tonggak asal (A) ke tonggak tujuan yang pada saat ini berada pada tonggak (B) sedangkan piringan dari 1 sampai ke (N- 2) dipindahkan ke tonggak bantu yang saat ini berada di tonggak (C) , Setelah piringan ke 1 sampai (N-2) berada pada tonggak bantu (C) , kemudian pindahkan piringan ke 1 sampai (N-2) ke tonggak tujuan (B) dan seterusnya. Metode penyelesaian permainan Hanoi diatas sering disebut sebagai metode back tracking , jadi solusi dicari dengan cara mundur ke belakang dahulu , baru kemudian solusi bisa di temukan .

Berikut Listing program Menara Hanoi dalam bahasa C #include <stdio.h>

void Hanoi(int n,char asal,char bantu,char tujuan) // pindahkan piringan ke n { // dari asal menuju tujuan

// melalui bantu if (n == 0) return;

Hanoi(n-1,asal,tujuan,bantu); //pindahkan piringan ke n-1 // dari asal ke bantu melalui

//tonggak tujuan

printf("Pindahkan piringan ke %d ke dari %c ke %c\n",n,asal,tujuan); Hanoi(n-1,bantu,asal,tujuan); //pindahkan piringan ke n – 1

// dari bantu menuju tujuan // melalu asal

}

int main(void) {

int n;

printf("Jumlah piringan ? "); scanf("%d",&n);

Hanoi(n,'a','b','c'); return 0;

}

Berikut Hasil dari program diatas . Jumlah piringan ? 3

Pindahkan piringan ke 1 ke dari a ke c Pindahkan piringan ke 2 ke dari a ke b Pindahkan piringan ke 1 ke dari c ke b Pindahkan piringan ke 3 ke dari a ke c Pindahkan piringan ke 1 ke dari b ke a Pindahkan piringan ke 2 ke dari b ke c

(21)

Pindahkan piringan ke 1 ke dari a ke c

Penggunaan Templlate

Dalam pemrograman , terutama yang sangat tergantung pada tipe variable , sering kali kita direpotkan dengan harus membuat fungsi yang berfungsi sama tapi dengan tipe variable berbeda.Untuk itu pada C++ dikeluarkan lah sebuah keyword baru , yaitu template. Dengan penggunaan template kita bisa membuat sebuah fungsi yang bias mendukung segala macam tipe variable , tidak terbatas pada variable yang di definisikan oleh keyword C/C++ tapi juga mendukung penggunaan untuk tipe variable masa depan. Penggunaan template tidak terbatas hanya pada fungsi tapi juga

mencakup class ( termasuk juga struct , union) . Secara garis besar penggunaan template dapat dibagi 2 yaitu template pada fungsi ( function template)dan template pada Class ( class template). Oke saya rasa kita langsung saja membahas penggunaan template.

Function Template

Pertama - tama mari kita membahas tentang function template.Untuk itu marilah kita perhatikan contoh berikut.

template <class tipe> void swap(tipe &a,tipe &b) { tipe c; c = a; a = b; b = c; }

Pada contoh diatas terdapat sebuah fungsi swap (menukar 2 buah variable) menggunakan template.. Untuk pemanggilan fungsi dilakukan seperti pemanggilan fungsi tanpa template. Untuk itu mari perhatikan penggalan perintah untuk menggunakan fungsi swap.

Contoh template dengan instance tipe int

void main(void) { int a,b; a = 10; b = 20; swap(a,b); cout << a << “ “ << b << endl; }

Contoh template dengan instance tipe float

void main(void) { float a,b; a = 10.0; b = 20.0; swap(a,b); cout << a << “ “ << b << endl; }

Contoh template dengan instance struct tTes

struct tTes { int a,b; }; void main(void) {

(22)

tTes a,b; a.a = 10; a.b = 20; b.a = 30; b.b = 40; swap(a,b);

cout << a.a << " " << a.b << " " << b.a << " " << b.b; }

Dapat dilihat , dengan menggunakan template kita telah menghemat waktu untuk menulis fungsi Pada fungsi swap diatas , juga tidak menutup kemungkinan untuk menukar 2 buah kelas.

Pada contoh diatas fungsi tidak akan bekerja jika variable yang ditukar berbeda tipe . Walaupun kekerabatannya cukup dekat . Anda tidak bisa menukar tipe int (16bit) dengan tipe short (16 bit). Ini terkait dengan pendeklarasian template pada fungsi swap.

template <class tipe> void swap(tipe &a,tipe &b)

Pada pendeklarasian fungsi swap dapat dilihat bahwa formal parameter a sama dengan formal parameter b . Oleh sebab itu sudah seharusnya tipe pada aktual parameter pun harus sama. Untuk contoh fungsi swap diatas sebaiknya anda tidak menggunakan type-casting untuk mengatasi masalah diatas. Mengingat fungsi swap diatas dikirim by reference . (Yang mana dalam pengiriman fungsi menggunakan reference berkaitan dengan pointer). Tentu saja ukuran dari variable menjadi sangat penting karena kita telah merubah ukuran dari variable (type casting) bisa saja terjadi hasil yang tak terduga . Walupun kadang – kadang memberikan hasil yang benar. Kecuali jika ukuran kedua tipe variable tersebut benar - benar sama , anda dapat menggunakan type–casting dalam hal ini.

Untuk mendefiniskan lebih dari satu type pada template anda dapat menggnakan koma sebagai pemisah

contoh :

Template dengan 2 buah tipe

template <class tipe1,class tipe2>

Overloading Template Function

Jikalau suatu saat ada sebuah variable yang harus diperlakukan khusus untuk

menukarkannya anda dapat mengoverload sebuah template function. Sebagai contoh : misalkan jika anda ingin menukar 2 buah variable float tanpa perlu memperhatikan negatif atau positif . Anda tinggal membuat sebuah fungsi tambahan dengan variable float. Jadi ketika dijalankan compiler akan memprioritaskan dulu pada fungsi yang memiliki formal parameter dan aktual parameter dengan tipe yang sama. Baru kemudian jika tidak ditemukan maka compiler akan membuat sebuah instance dari template function yang telah anda buat. Untuk lebih jelasnya mari kita lihat contoh source code berikut ini .

#include <iostream.h> template <class Tipe> void swap(Tipe &a,Tipe &b) { Tipe tmp; tmp = a; a = b; b = tmp; }

(23)

void swap(float &a,float &b) { float c; a = (a < 0.00)?-a:a; b = (b < 0.00)?-b:b; c = a; a = b; b = c; } void main(void) { float a,b; a = -10.0; b = 20.0; swap(a,b); cout << a << " " << b; }

Class Template

Jenis template yang berikutnya ialah Class template. Class Template , tidak hanya berlaku untuk pendefinisian template pada class tapi juga berlaku pada pendefinisian struct dan union.Cara pendefinisan sama seperti Funtion template yang beda hanya pada caramembuat instance dari class template tersebut. Untuk lebih jelasnya mari kita perhatikan contoh pendefinisian Class Template.

Pendefinisian Class Template pada sebuah class CMyTemplate

template <class MyTipe> class CMyTemplate { protected : MyTipe m_a,m_b; public : void Done(void) {

memset(&m_a,0,sizeof(MyTipe)); // pendeklarasian method } // didalam kelas

};

//pendeklarasian methos diluar kelas template <class MyTipe>

void CMyTemplate<MyTipe>::Init(MyTipe a,MyTipe b) {

m_a = a; m_b = b; }

Pendefinisian Class Template pada sebuah struct tMyStruct

template <class MyTipe> struct tMyStruct

{

MyTipe a,b; };

Pendefinisian Class Template pada sebuah union _MyUnion

template <class MyTipe> union _MyUnion

{

MyTipe a; int b;

(24)

};

Yang perlu diperhatikan dari contoh diatas , antara lain perbedaan antara pendefinisian method didalam atau diluar kelas .

Untuk menggunakan sebuah class template sebelumnya kita harus mendefiniskan instance dari template yang akan dibuat. Untuk mendefinisikan instance dari class template dapt dilakukan dengan cara menuliskan tipe data dari instance yang diapit oleh tanda “<” ,”>” .

Contoh :

void main(void) {

CMyTemplate<short> a; // membuat instance CMyTemplate dengan tipe short

tMystruct<short> b; // membuat instance tMyStruct dengan tipe short _MyUnion<float> c; // membuat instance _MyUnion dengan tipe float }

Pada instance CMyTemplate yang dideklarasikan dengan tipe data short maka MyTipe (pada pendefinisian class ) akan menjadi short .Ini berarti variable m_a dan m_b akan bertipe short begitu pula pada struct dan union. Untuk mendefinisikan lebih dari 1 tipe pada class template dapat anda lakukan sama seperti Function Template yaitu dengan menggunakan tanda koma sebagai pemisah .

Contoh :

template <class MyTipe1,class MyTipe2> class CMyTemplate { protected : MyTipe1 m_a MyTipe2 m_b; public :

void Init(MyTipe1 a,MyTipe2 b) {

m_a = a; m_b = b; }

};

Untuk membuat instancenya tinggal ditambahkan tanda koma . Contoh :

void main(void) {

CMyTemplate<short,float> a; }

Jadi sekarang pada Object a , Variabel m_a akan bertipe short sedangkan pada variable m_b akan bertipe float.

Analisa Numerik:

Menghitung FPB Metode Euclidian

FPB ialah isitilah yang digunakan untuk menyatakan sebuah bilangan yang mampu

(25)

membagi pasangan bilangan lain sehingga didapatkan hasil bilangan bulat yang paling kecil. Dengan kata lain FPB ialah sebuah bilangan terbesar yang mampu membagi habis (sisa = 0) pasangan bilangan lain

Contoh :

FPB dari 60 dan 80 : 60 = 20 * 3

80 = 20 * 4

Pada contoh diatas FPB dari 60 dan 80 ialah 20.

Ada beberapa macam contoh untuk menghitung FPB salah satunya yang terkenal ialah algoritma Euclidian .

Berikut adalah Algoritma Euclidian untuk menemukan FPB dari 2 buah bilangan 1. Input Bilangan1

2. Input Bilangan2

3. Sisa = Bilangan1 modulus Bilangan2 4. Jika Sisa != 0 maka

Bilangan1 = Bilangan2 Bilangan2 = Sisa 5. Jika Sisa = 0 maka FPB = Bilangan2

Berikut adalah implementasinya dalam Bahasa C #include <stdio.h>

int FPB(int Bil1,int Bil2) { int sisa; while((sisa = Bil1%Bil2) != 0) { Bil1 = Bil2; Bil2 = sisa; } return Bil2; } void main(void) { int bil1,bil2; int sisa;

printf("FPB dari 60 dan 80 = %d\n",FPB(60,80)); printf("FPB dari 40 dan 120 = %d\n",FPB(40,120)); printf("FPB dari 2 dan 3 = %d\n",FPB(2,3));

} Hasil : FPB dari 60 dan 80 = 20 FPB dari 40 dan 120 = 40 FPB dari 2 dan 3 = 1

Analisa Numerik:

(26)

Menukar 2 Buah Nilai

Metode klasik dalam dalam menukar 2 buah nilai , biasanya dengan menggunakan bantuan sebuah variable penampung. Untuk itu diperlukan minimal 3 buah variable dalam implementasinya.

Contoh :

Untuk menukar var A dan B temp = A ;

A = B; B = temp;

Didalam bahasa C pendeklarasian variable harus diletakkan sebelum statemen. Jadi jika program anda cukup panjang ( dalam artinya banyak baris ) tentu saja anda harus ke atas dahulu untuk mendeklarasikan varibale temp.

Ada cara lain yang dapat digunakan untuk menukar 2 buah nilai tanpa harus memberikan variable tambahan ( cukup dengan 2 buah variable saja ). Yaitu dengan bantuan logika xor .

Untuk itu sebelumnya mari kita melihat sejenak tabel kebenaran xor.

Contoh : A = 1010 B = 0101 C = A xor B C = 1111 X = C xor A -> X = 0101 // penting !!!! Y = C xor B -> Y = 1010 // penting !!!! Dari contoh diatas dapat ditarik kesimpulan : C = A xor B

C xor A akan menghasikan B C xor B akan menghasilkan A

Sifat diatas biasanya digunakan untuk membuat sebuah enkripsi data yang sederhana. Tapi yang akan kita bicarakan ialah menggunakan xor untuk menukar 2 buah nilai Mari perhatikan contoh berikut .

(27)

B = C xor B // pertama A = C xor B // kedua

Pada C xor B yang pertama akan dihasilkan nilai A oleh sebab itu nilai tersebut ditaruh di B (karena kita akan menukar) . C xor B yang kedua dimana B merupakan nilai A awal maka akan menghasilkan B oleh sebab itu kita taruh di A. Dengan mensubtitusi nilai C dengan salah satu variable maka akan didapatkan :

A = A xor B B = A xor B A = A xor B

Karena (A xor B) = (B xor A) , pada statement 2 dapat diganti B = B xor A Sehingga dalam bahasa C dapat ditulis :

A ^= B ^= A ^= B;

Meakjubkan bukan ?? , Menukar 2 buah nilai hanya dengan 1 perintah ( titik koma ) .

C++ : Scope Class

C++ memperluas pengertian scope (visibility) dalam bahasa C dengan masuknya

class dan namespace. Artikel ini membahas scope sebuah class. Pembahasan scope tidak terlepas dari konsep yang saling berkaitan dalam C/C++ yaitu lifetime (storage

duration) dan linkage. Lifetime menentukan kapan destructor sebuah class dipanggil.

Scope sebuah kaji ulang

Komputer, sebagai sebuah mesin, dirancang untuk bekerja mengolah angka.

Komputer menyimpan data dan perintah di memori dalam bentuk angka. Manusia tidak menggunakan angka melainkan nama untuk membedakan suatu bentuk dengan bentuk lainnya. Manusia lebih mudah mengenali bentuk/benda melalui nama daripada angka. Sebagai contoh, dalam sebuah jaringan LAN lebih mudah mengenali server melalui nama server daripada alamat IP (sebuah angka) server tersebut. Nama juga sangat berarti bagi sebuah program, seseorang penulis program menggunakan nama untuk

membedakan data (variabel), fungsi, atau entity lain yang dikenal dalam sebuah bahasa pemrograman.

Istilah formal sebuah nama, dalam bahasa C/C++ disebut identifier. Nama (identifier) digunakan untuk menyatakan,

• Data

• fungsi (function)

• typedef

(28)

• enumeration, dan anggotanya

• union

• label

dalam sebuah program C/C++. Sebuah program mengenali nama obyek melalui

deklarasi nama tersebut. Scope membatasi nama (identifier), artinya sebuah nama hanya dapat digunakan dalam scope nama tersebut. Scope sebuah nama sudah ditentukan pada saat nama tersebut dideklarasikan. Nama dalam sebuah scope dapat dikenali di scope yang berbeda apabila sesorang penulis program menghendaki demikian. Sebuah scope dapat mempunyai hubungan (linkage) dengan scope lain, karena menggunakan sebuah nama (identifier) yang sama, dengan kata lain nama (identifier) tersebut visible di scope yang berbeda.

Translation Unit

Ada perbedaan antara organisasi penulisan program C++, melalui file .h (berisi deklarasi) dan .cpp (berisi definisi), dengan proses pemilahan token (parsing) yang dilakukan compiler. Perbedaan tersebut tidak begitu menentukan dalam memahami konsep scope, lifetime dan linkage dalam C. C++ memiliki batasan scope yang lebih abstrak, oleh karena itu standard C++ memperkenalkan istilah translation unit. Sebuah translation unit mungkin dibentuk dari beberapa file, karena umumnya sebuah program C++ menyertakan satu atau lebih file .h. Pada proses kompilasi, file berisi pernyataan program (source file) dan file lain yang dibutuhkan digabungkan menjadi satu kesatuan sebagai masukan proses pemilahan token.

(29)

Seperti ditunjukkan pada ilustrasi di atas [3], file main.cpp, h1.h, dan h2.h

digabungkan menjadi sebuah translation unit. Compiler tidak mengikutsertakan baris program diantara #ifndef (#if !defined) atau #else jika syarat tidak terpenuhi.

Sebagai contoh, jika INCL bernilai 1 maka dihasilkan translation unit TU#1, baris program diantara syarat kondisi pada file h1.h diikutsertakan. Apabila INCL bernilai 0, maka dihasilkan translation unit TU#2, baris program diantara syarat kondisional pada file h1.h tidak diikutsertakan dan baris program diantara syarat kondisi pada file h2.h yang diikutsertakan. Perlu diperhatikan juga bahwa compiler mengikutsertakan file yang dibutuhkan secara rekursif, jika file h1.h mencantumkan file *.h lainnya maka file

tersebut termasuk dalam translation unit yang sama.

Proses pemilahan token menggunakan pernyataan program yang terdapat dalam translation unit dan bukan yang tertulis pada masing-masing file. Demikian halnya dengan scope, lifetime dan linkage masing-masing identifer ditentukan berdasarkan translation unit.

Deklarasi dan Definisi

Sebuah deklarasi memperkenalkan sebuah nama dalam sebuah program. Deklarasi sebuah nama sekaligus menentukan scope nama tersebut. Definisi, selain memasukkan nama obyek1 dalam sebuah program juga membentuk (create) obyek tersebut dan

melakukan inisialisasi. Deklarasi dan definisi sering dipertukarkan, tetapi sebenarnya terdapat perbedaan deklarasi dan definisi.

Secara sederhana, sebuah program hanya mempunyai satu definisi terhadap satu obyek atau fungsi (function) dan sebuah program dapat mempunyai lebih dari satu deklarasi. Persyaratan tersebut dalam C++ dikenal dengan istilah aturan satu definisi (One Definition Rule(ODR)).

int i; //definisi int i=0; //definisi extern int i; //deklarasi extern int i=0; //definisi static int j; //definisi static int j=0; //definisi

void g(int k) //deklarasi fungsi void f(int k) //definisi fungsi {

int l; }

Dalam C++, seperti pada beberapa contoh di atas, sebuah deklarasi adalah sebuah definisi kecuali,

• sebuah deklarasi fungsi tanpa isi (body) fungsi tersebut, contoh fungsi g.

• sebuah deklarasi obyek dengan katakunci extern dan tanpa inisialisasi.

• sebuah deklarasi obyek (data member) static dalam scope class.

(30)

C yang mengenal definisi tentatif (tentative definition). C++ menyarankan untuk tidak menggunakan “implicit int” dalam deklarasi. Dalam C, jika tidak ditulis type obyek

maka dianggap obyek tersebut bertipe int, static a; //a bertipe int

const b; //b bertipe int void f(const c); //c bertipe int

main(void) { return 0; } //return type int

C++ menyarankan untuk menuliskan tipe obyek secara eksplisit, sebagai berikut, static int a;

const int b=1; void f(int const c);

int main(void) { return 0; }

Scope

Scope dan lifetime adalah dua konsep yang terkait erat. Visibility sebuah nama

(identifier) dalam sebuah program C++ berbeda-beda, sebuah nama dengan scope global mempunyai visibility paling luas sedangkan sebuah nama dengan scope lokal

mempunyai visibility lebih sempit misalkan sebatas eksekusi suatu fungsi. Sebuah scope menentukan batas visibility sebuah nama dalam program C++. Scope dapat dibentuk dengan sepasang tanda kurung {}, yang membentuk block scope, misalnya pada forloop, while-loop, dll. Batasan scope dapat juga lebih abstrak seperti pada pembahasan

translation unit.

Bahasa C mengenal beberapa bentuk scope, antara lain:

- block, scope nama adalah bagian program yang dibatasi oleh sepasang tanda kurung { }. Sebuah nama visible sejak deklarasi nama tersebut sampai dengan tanda kurung penutup } yang menandakan akhir masa pakai nama tersebut. - prototipe fungsi (function prototype), scope nama hanya sebatas tanda kurung ( dan ) yang membentuk prototipe fungsi.

- fungsi, scope sebuah nama adalah seluruh badan fungsi tersebut. - file, scope sebuah nama adalah keseluruhan file sejak sebuah nama dideklarasikan.

Scope block dan prototipe fungsi dikenal dengan scope lokal (local scope). Bahasa C++ menambahkan dua scope lagi, yaitu class dan namespace. Deklarasi class (dan namespace) dibatasi oleh sepasang tanda kurung { }, walaupun definisi member function dapat ditulis di luar deklarasi class. Pada penulisan definisi seperti itu, member function tetap berada dalam scope class.

Scope minimal

Standar C++ mengubah sedikit aturan mengenai scope sebuah nama variabel dalam pernyataan for-loop, while-loop, atau if-condition. C++ mengijinkan deklarasi variabel sebagai bagian dari sebuah for-loop. Sebagai contoh deklarasi variabel i (loop counter) pada cuplikan baris program berikut ini,

(31)

//dalam sebuah for-statement {

cout << i << endl; }

int n=i; //error: menggunakan i diluar scope

Pada contoh, scope i adalah badan for-loop tersebut yang dibatasi oleh pasangan tanda kurung { }. Penggunaan variabel i diluar scope adalah suatu pelanggaran terhadap aturan scope C++ yang terdeteksi pada saat kompilasi program. Perubahan aturan scope tersebut sejalan dengan teknik scope minimal (minimal scoping)[1]. Teknik scope minimal mempersempit jarak antara deklarasi sebuah nama dengan pemakaian nama tersebut. Teknik ini bertujuan untuk menambah readability2 sebuah program. Scope

minimal menunda alokasi obyek sampai obyek tersebut memang benar-benar dibutuhkan, seperti ditunjukkan pada contoh berikut

if (<kondisi>) {

int i,j; }

Jika <kondisi> tidak bernilai benar (.T.) maka tidak ada alokasi memori untuk obyek i dan j.

Tidak semua compiler C++ mengikuti aturan scope yang disempurnakan, salah satu yang paling menonjol adalah Microsoft Visual C++. Sampai dengan dengan versi 6, Visual C++ tidak mengikuti aturan scope yang baru dan hal ini adalah salah satu contoh ketidak sesuaian (incompatibility) VC++ dengan standar C++[6,7]. VC++ menggunakan konvensi pembentukan nama yang dikenal dengan notasi Hungarian (Hungarian

notation) dengan mengikutsertakan tipe data dalam nama variabel. Dengan demikian pendekatan VC++ tidak memandang perlu memperpendek jarak antara deklarasi dengan pemakaian nama tersebut pertama kali.

Lifetime

Lifetime atau storage duration sebuah obyek adalah rentang waktu sejak obyek

tersebut dibentuk sampai waktu saat obyek tersebut dihancurkan. Selama rentang waktu tersebut, nama tersebut mengacu ke lokasi memori yang ditempati oleh obyek tersebut, selepas rentang waktu tersebut, sebuah nama tidak lagi mengacu ke lokasi memori tersebut karena mungkin sudah ditempati oleh obyek lain.

C++ mengenal tiga jenis storage duration sebuah nama, yaitu: static, automatic

(local), dan dynamic. Argument sebuah fungsi mempunyai automatic storage duration, artinya argumen tersebut dibentuk begitu eksekusi program memasuki fungsi tersebut (scope argumen tersebut) dan dihancurkan begitu eksekusi fungsi tersebut selesai (keluar dari scope fungsi). Sebuah obyek automatic menempati memori stack (stack memory). Sebuah deklarasi obyek dengan scope block tanpa kata kunci extern atau static juga mempunyai automatic storage duration (seperti contoh scope minimal di atas). Sebuah obyek dengan static storage duration menempati memori sejak saat pertama eksekusi program, dengan demikian obyek static mempunyai alamat yang sama sepanjang eksekusi program. Obyek static menempati memori static (static storage). Sebuah obyek dengan dynamic storage duration menempati memori melalui fungsi

(32)

alokasi (operator new) dan dilepas dengan fungsi dealokasi (operator delete). Obyek dinamik menempati memori heap atau memori dinamik (free store).

Storage specifier

C++ mengenal lima buah kata kunci yang menyatakan attribut storage duration sebuah nama (storage class specifiers), yaitu: auto, register, extern, static dan

mutable. Sedikit perbedaan dengan C, typedef tidak termasuk storage class specifier. Secara umum, dalam sebuah deklarasi tidak boleh menggunakan dua buah storage specifier secara bersamaan. Kata kunci extern dan static dapat menjadi bagian dari deklarasi obyek atau fungsi dalam scope namespace3 dan scope block, akan tetapi

static tidak dapat menjadi bagian deklarasi fungsi dalam scope block. static juga dapat menjadi bagian deklarasi dalam sebuah scope class.

auto dan register dapat menjadi bagian sebuah deklarasi dalam scope block

maupun atau dalam deklarasi argumen fungsi (formal parameter), tetapi tidak dalam scope namespace, sebagai contoh:

register char *p; //error – register dalam scope namespace void f(register char *p); //ok – register dalam formal parameter void f(auto int i); //ok di C++, error di C

C++ mengijinkan penggunaan auto dalam argumen fungsi walaupun tidak ada pengaruh apapun, sedangkan C tidak memperbolehkannya.

mutable tidak berpengaruh terhadap linkage maupun lifetime sebuah nama, mutable hanya dapat digunakan dalam deklarasi obyek (data member) dalam scope class. mutable menyatakan bahwa sebuah obyek tidak pernah konstant.

Linkage

Sebuah nama yang sama tetapi dalam translation unit yang berbeda dapat mengacu ke sebuah obyek yang sama. Hal ini, dalam C maupun C++, disebut linkage. Ada 3 macam linkage, masing-masing adalah:

1. external linkage, yaitu sebuah nama yang dapat terjangkau dari scope lain meskipun berbeda translation unit.

2. internal linkage, yaitu sebuah nama dalam sebuah translation unit yang dapat terjangkau di scope lain dalam translation unit yang sama.

3. tanpa (no) linkage, yaitu nama sebuah obyek dalam sebuah scope dan tidak terjangkau melalui nama tersebut dari scope lainnya.

Linkage sebuah obyek maupun fungsi ditentukan oleh kombinasi beberapa faktor, yaitu: scope, storage class specifier, dan linkage yang ditetapkan melalui deklarasi sebelumnya. Selain itu const juga mempunyai pengaruh terhadap hasil akhir linkage obyek atau fungsi.

Secara umum, extern pada deklarasi sebuah obyek atau fungsi dalam scope

namespace menyatakan external linkage. Demikian halnya dengan deklarasi tanpa storage class specifier juga menyatakan external linkage. Sebaliknya static pada deklarasi obyek maupun fungsi menyatakan internal linkage. Sebagai contoh, definisi nama dalam file1.cpp dan file2.cpp berikut ini,

(33)

Pada contoh, definisi nama data tersebut mempunyai scope file, i mempunyai linkage external,sedangkan k mempunyai linkage internal. Hasil kompilasi (dan link) kedua file tersebut menghasilkan sebuah program dengan sebuah obyek i,j dan dua buah obyek k. Deklarasi j pada file1 mengacu ke obyek j di file2, deklarasi i pada file2 mengacu ke obyek i di file1. static pada deklarasi k mengacu ke obyek yang berbeda, walaupun kedua file menggunakan nama yang sama. Dalam C++, berbeda dengan C, const pada sebuah deklarasi menyatakan linkage internal, seperti deklarasi N pada contoh di atas. Namun demikian, extern pada deklarasi sebuah obyek const mengubah linkage obyek tersebut menjadi linkage eksternal.

Aturan linkage pada scope block berbeda dengan aturan linkage pada scope

namespace (termasuk scope file). Dalam scope blok, nama obyek tidak mempunyai linkage (no linkage), kecuali terdapat extern pada deklarasi obyek tersebut. Nama parameter (formal parameter) juga tidak mempunyai linkage. Sebagai contoh, void f(int i) //f: eksternal

{ //i:no linkage int j; //no linkage static int k; //no linkage //file1.cpp

int i=0; //internal extern j; //external static int k; //internal int const N=100 //internal //file2.cpp

extern int i; //external int j; //external static int k; //internal …

}

Pada contoh tersebut, nama fungsi f mempunyai linkage eksternal, nama parameter i tidak mempunyai linkage, nama variabel lokal j dan k tidak mempunyai linkage.

Bagaimana dengan deklarasi yang menggunakan extern pada blok scope, seperti contoh berikut ini,

static int i=0; //internal extern int j; //eksternal void f()

{

extern int i; //internal extern float j; //error extern int k; //external …

}

(34)

bergantung kepada linkage obyek pada scope yang memuat scope blok tersebut. Obyek i dalam blok scope mempunyai linkage internal, mengikuti linkage obyek i dalam scope file. Obyek k mempunyai linkage eksternal, mengikuti linkage obyek k dalam scope file. Deklarasi obyek merupakan pelanggaran terhadap aturan linkage, karena tipe data j (float) dalam scope blok berbeda dengan tipe data j (int) dalam scope file.

Scope Class

Setiap definisi class membentuk sebuah scope baru. Scope class mencakup deklarasi class, masing-masing badan fungsi anggota class (member function), dan constructor initializers.

Akses terhadap anggota class dapat dilakukan menggunakan salah satu diantara beberapa cara dibawah ini,

a) operator . b) operator ->

c) operator :: (scope resolution operator)

d) melalui fungsi anggota class tersebut (member function) atau derived class Ketiga cara tersebut harus mengikuti batasan akses (public, protected, private) class tersebut. Keempat cara tersebut dapat digunakan untuk mengakses anggota class dengan batasan akses public. Cara keempat dapat digunakan untuk mengakses anggota class dengan batasan akses protected dan public.

Class dalam class (nested class) mempunyai scope terpisah, seperti contoh berikut ini, struct s { struct t { int i; } j; }

Jika t tidak tersedia untuk akses public (protected atau private), maka operator :: tidak dapat digunakan untuk mengakses struct t karena batasan akses masih tetap berlaku. Standar C++ sebelum dibakukan, memperkenalkan cara untuk mendefinisikan suatu besaran konstan (compile-time constant) yang mempunyai scope class. Sebagai contoh sebuah class C berikut ini,

class C { int buf[10]; public: C(); };

(35)

mempunyai angota berupa array integer buf dengan jumlah elemen 10. Inisialisasi array buf dalam constructor perlu menggunakan operator sizeof() untuk mendapatkan

jumlah elemen array, sebagai berikut: C::C()

{

for(int i=0;i<(sizeof(buf)/sizeof(&buf[0]));i++) buf[i]=i;

}

Cara yang lebih mudah untuk inisialisasi array buf adalah dengan mendefinisikan jumlah elemen array buf. Dua cara untuk mendefinisikan besaran konstan dengan scope class adalah,

Dengan demikian inisialisasi array buf dalam constructor tidak lagi menggunakan operator sizeof(), melainkan dengan nilai konstan BUFSIZE.

C::C() {

for(int i=0;i<BUFSIZE;i++) buf[i]=i;

}

Cara ‘enum hack’ sering digunakan sebelum standar C++ memasukkan cara untuk mendefinisikan konstan dengan scope class. Cara ‘enum hack’ disebut demikian karena menggunakan enum tidak sesuai dengan penggunaan seharusnya. Namun demikian ‘enum hack’ masih lebih baik dari pada menggunakan manifest constant (#define) yang tidak mengenal batasan scope.

Overloading

Scope dan linkage adalah dua buah konsep dasar yang menjadi dasar compiler C++ dalam menguraikan penggunaan nama dalam sebuah program. Sebuah program dapat menggunakan nama yang sama asalkan berbeda scope. C++ melonggarkan hal ini dengan memasukkan konsep overloading untuk nama fungsi. C++ mengijinkan sebuah program menggunakan nama yang sama untuk dua buah fungsi yang berbeda.

Overloading dapat digunakan dalam scope file maupun scope class. Salah satu contoh adalah overloading anggota class berupa fungsi (member function), seperti pada contoh berikut ini,

(36)

Masing-masing class Base maupun class Derived membentuk scope tersendiri. Pada contoh, class Derived mempunyai fungsi write dengan signature yang berbeda. Hal ini tidak diperbolehkan dalam C++, karena function overloading tidak dapat menembus batas scope masing-masing class (cross scope). Cara pertama untuk mendapatkan hasil yang diinginkan adalah memanggil fungsi write class Base sebagai berikut,

Cara kedua adalah menggunakan using directive, namun hanya dapat dilakukan dengan compiler C++ yang sudah mengenal namespace.

Dalam menguraikan nama fungsi, linker C++ tidak hanya melihat nama fungsi

melainkan signature fungsi tersebut. Signature merupakan rangkaian kata (token) yang dapat membedakan kedua fungsi, yaitu tipe masing-masing argumen (formal parameter) fungsi tersebut. Sebagai contoh, char *strcpy(char *,const char *), mempunyai

signature { char*,const char *}. Signature hanya mengambil tipe masing-masing argumen, bukan nama argumen fungsi tersebut. Hal ini yang memungkinkan sebuah program C++ mempunyai deklarasi dua fungsi berbeda dengan nama yang sama dalam scope yang sama.

Class Linkage

Dalam hal nama obyek data maupun fungsi, external linkage dalam C++ dan C

mempunyai pengertian yang sama, yaitu sebuah nama yang mengacu ke satu obyek dan nama tersebut dapat digunakan di translation unit yang berbeda. Sebagai contoh,

file1.cpp

void f() {} int n;

(37)

file2.cpp

void f(); //mengacu ke fungsi f di file1.cpp

extern int n; //mengacu ke obyek data n di file1.cpp

Linkage sebuah nama class berbeda dengan pengertian linkage pada nama obyek data maupun fungsi. Sebagai contoh,

Dalam C++, nama sebuah class, “C” pada contoh di atas, mempunyai linkage external. Pada contoh di atas kedua translation unit mempunyai definisi class C yang sama persis. Pengertian linkage eksternal pada nama obyek dan fungsi tidak dapat digunakan untuk menjelaskan pengertian linkage eksternal pada nama class “C” tersebut.

Hal inilah perbedaan yang muncul dengan masuknya konsep class dalam C++.

Pengertian linkage eksternal secara umum, berlaku untuk nama data obyek, fungsi dan class, adalah setiap obyek dengan linkage eksternal harus mengikuti aturan “satu definisi” (ODR). Pada contoh, jika TU2 mempunyai definisi class C maka definisi tersebut harus sama dengan definisi class C pada TU1. ODR mensyaratkan, jika satu atau lebih translation unit mempunyai definisi sebuah obyek yang sama, maka definisi tersebut harus sama di semua translation unit (yang memuat definisi obyek tersebut). Salah satu cara praktis, sadar atau tidak sadar, setiap pemrogram memastikan hal ini dengan memasukkan definisi class dalam sebuah file header (.h) dan mengikutsertakan (melalui #include) obyek tersebut bilamana diperlukan, seperti kolom “source file” pada contoh di atas.

Static

Sebuah class dapat mempunyai anggota berupa data atau fungsi static. Tidak seperti obyek static pada scope file maupun blok, static dalam scope class mempunyai arti linkage eksternal. Selain operator . dan operator ->, anggota class berupa data dan fungsi static dapat diakses dengan operator ::.

Anggota class berupa data static harus dinisialisasi sekali saja, diluar scope class, yaitu dalam scope file tetapi tidak dalam file .h (header). Data static dalam scope class bukan merupakan bagian dari obyek class tersebut. Data static berlaku seperti halnya sebuah data global sebuah class, artinya hanya ada satu data static untuk semua obyek

(38)

class tersebut.

Anggota class berupa fungsi static tidak mempunyai pointer this, karena hanya ada satu fungsi static untuk semua obyek class tersebut. Tanpa pointer this, fungsi static tidak dapat mengakses anggota class lainnya yang non-static. Dengan demikian fungsi static umumnya digunakan untuk manipulasi anggota class berupa data statik. Salah satu contoh pemakaian fungsi static adalah pola desain (design pattern) Singleton.

Sebuah class dapat menempatkan data static dalam member function maupun sebagai anggota class seperti data member lainnya. Sebagai contoh,

class Base {

public:

int countCalls() {

static int count=0; //definisi static dalam member function return ++count;

} };

Semua class yang mewarisi (inherit) class Base tersebut juga mewarisi data static tersebut, sehingga count akan bertambah jika countCalls() dipanggil melalui obyek Base maupun Derived.

class Derived1 : public Base { }; class Derived2 : public Base { }; int main()

{

Derived1 d1; Derived2 d2;

int d1_count=d1.countCalls(); //d1_count=1 int d2_count=d2.countCalls(); //d2_count=2 }

Penjelasan mengenai nilai obyek static pada contoh di atas merupakan latihan bagi para pembaca. Definisi data static sebagai anggota class lebih umum digunakan, seperti ditunjukkan pada contoh berikut,

class Base {

private: static int i; public:

virtual int countCalls() { return ++i; } };

int Base::i;

class Derived1 : public Base {

private:

static int i; //menyembunyikan Base::i public:

(39)

};

int Derived1::i;

class Derived2 : public Base {

private:

static int i; //menyembunyikan Base::i public:

int countCalls() { return ++i; } }; int Derived2::i; int main() { Derived1 d1; Derived2 d2;

int d1_count = d1.countCalls(); //d1_count = 1 int d2_count = d2.countCalls(); //d2_count = 1 return 0;

}

Scope class Derived terpisah dengan scope Base maka class Derived tidak lagi mewarisi data static i class Base, sehingga countCalls memberikan nilai yang berbeda bila

dipanggil dari obyek class Derived.

C++ mengenal class local, sebuah definisi class dalam scope blok, sebagai contoh: #include <iostream> int i=10; int main() { void f(); f(); return 0; } void f() { static int j=20; class Local { int k; public: Local(int i) : k(i) {}

void a() { std::cout << k+i << std::endl; } void b() { std::cout << k+j << std::endl; } };

local l(30); l.a(); l.b(); };

class lokal dapat digunakan (visible) hanya sebatas scope fungsi f. Definisi class lokal harus mencakup definisi semua anggota class berupa fungsi (member function), karena C maupun C++ tidak mengenal definisi fungsi dalam fungsi. Class local juga tidak mungkin mempunyai anggota berupa data static, karena data static memerlukan

(40)

fungsi f, artinya jika f mempunyai argumen maka argumen tersebut tidak dikenal dalam scope class Local.

Analisa Numerik:

Menghitung Nilai Cosinus

Tahukah anda , bagaimana caranya komputer menghitung nilai dari cos(30) ? . Mungkin kalau hanya sekedar menghitung nilai dari cos(30°) kita tidak membutuhkan bantuan komputer. Nah bagaimana halnya dengan cos(30.5°).Komputer tentu saja tidak menyimpan nilai – nilai tersebut dalam sebuah tabel.Selain memakan tempat , juga terbatas hanya pada sudut yang tertentu yang disimpan saja. Dalam beberapa kasus pemrograman, penyimpanan nilai dalam tabel dapat dipertimbangkan terutama dalam program – program yang berjalan secara real time dimana dengan bantuan tabel dapat mengurangi beban dari proses komputasi . Pada kesempatan kali ini saya akan membahas salah satu algoritma yang dapat digunakan sebagai alat membantu mendapatkan nilai dari beberapa fungsi dasar matematika . Untuk itu ada baiknya kita menengok sejenak

pembahasan mengenai deret khususnya Deret Taylor dan Deret Maclaurin yang terdapat pada mata kuliah Kalkulus.

Deret Taylor dan Deret Maclaurin

Bentuk Umum Deret Taylor :

Nilai a adalah sebuah constanta , Deret MacLaurin merupakan Deret Taylor khusus yang didapat dengan cara mensubtitusi nilai a dengan 0.

Dengan bantuan rumus diatas maka menghitung nilai cos bukan merupakan hal yang misteri lagi . Persamaan diatas berlaku tidak hanya untuk menghitung nilai cos saja tapi juga dapat menghitung beberapa fungsi matematika lainnya , seperti fungsi fungsi yang berhubungan dengan trigonometri , exponensial , logaritma , Hyperbolic dan lainnya . Oke saya rasa kita langsung menuju contoh saja . Kali saya akan membuat fungsi untuk menghitung nilai cos dengan menggunakan deret MacLaurin.

(41)

Pertama – tama kita mencari dulu turunan masing masing tingkat dari cos(x) serta hasilnya bila x = 0 (Maclaurin)

dan seterusnya

jika diterjemahkan dalam bahasa C maka aka menjadi : int turunan(int n) { int hasil; n = n % 4; switch(n) {

case 0 : hasil = 1;break; case 1 : hasil = 0;break; case 2 : hasil = -1;break; case 3 : hasil = 0;break;

}

Fungsi turunan diatas ialah untuk menghitung nilai turunan tingkat ke - n. Melihat dari tabel bahwa pada turunan ke 4 sama dengan turunan ke 0 maka bisa disimpulkan: n = n % 4;

Setelah kita tahu turunannya maka dapat disusun algoritma global untuk penyelesaian semua masalah yang menggunakan deret Maclaurin dengan input X.

1. n = 0 // menyatakan turunan ke – n 2. pembilang = 1 // X0 = 1

3. penyebut = 1 // 0! = 1 4. hasil = 0 // hasil keseluruhan

5. suku = turunan(n) * pembilang / penyebut // hitung nilai dari suku ke n 6. hasil = hasil + suku

7. Tambahkan nilai n dengan 1

8. pembilang = pembilang * X // untuk mendapatkan Xk+1 = Xk * X

9. penyebut = penyebut * n // untuk mendapatkan faktorial ke n 10. Ulangi terus langkah ke 4 – 8 sampai keadaan tertentu

Dalam perhitungan menggunakan deret MacLauriun dimana fungsi diturunkan terus sampai tak hingga , maka diperlukan adanya sebuah pemotongan pada keadaan tertentu yang menyatakan kapan perhitungan tersebut harus berhenti . Keadaan tertentu yang dipakai biasanya ditentukan oleh nilai dari suku . Pada contoh yang saya berikan , jika

(42)

nilai suku sudah lebih kecil dari galat maka tidak perlu dilakukan perhitungan lagi alias keluar dari looping.

Berikut listing program lengkap dari contoh diatas : #include <stdio.h> #define abs(x) ((x >= 0)?x:-x) int turunan(int n) { int hasil; n = n % 4; switch(n) {

case 0 : hasil = 1;break; case 1 : hasil = 0;break; case 2 : hasil = -1;break; case 3 : hasil = 0;break; } return hasil; } double cos(double x) { double pembilang,penyebut,hasil,suku; double galat; double n; pembilang = penyebut = 1; galat = 0.00001; hasil = 0.0; n = 0; do {

if (turunan(n) != 0) // untuk mengurangi perkalian dengan 0 {

suku = turunan(n) * pembilang / penyebut; hasil = hasil + suku;

} n++;

pembilang = pembilang * x; // pangkat penyebut = penyebut * n; // faktorial }while(abs(suku) >= galat); return hasil; } void main(void) { const double PI = 3.14159265; printf("%8.4f\n",cos(0)); printf("%8.4f\n",cos(PI/6)); printf("%8.4f\n",cos(PI/4)); printf("%8.4f\n",cos(PI/2)); printf("%8.4f\n",cos(PI)); } Hasil : 1.0000 0.8660 0.7071 0.0000 -1.0000

Nah coba dibandingkan hasil yang anda dapat dari program ini dengan kalkulator . Hasilnya pasti sama.

(43)

Class C++ Dasar

Pemrograman C++ memerlukan pemahaman yang memadai untuk menterjemahkan desain ke dalam bentuk implementasi, terutama untuk desain yang menggunakan abstraksi class. Fokus pembahasan pada aspek pembentukan obyek (construction) sebuah class, dan proses sebaliknya pada saat obyek tersebut sudah tidak digunakan lagi (destruction).

Deklarasi dan Definisi

Deklarasi dan definisi adalah langkah awal dalam setiap penulisan program tidak terkecuali dalam bahasa C++. Deklarasi dan definisi diperlukan untuk semua tipe data termasuk tipe data bentukan user (user-defined type).

Bentuk sederhana deklarasi class adalah sebagai berikut,

class C { }; atau struct C { };

dalam bahasa C++ struct dan class mempunyai pengertian yang sama. Deklarasi

class dengan struct mempunyai anggota dengan akses public kecuali jika dinyatakan lain. struct C { int i; void f(); } class C { public: int i; void f(); }

Kedua deklarasi tersebut mempunyai arti yang sama.

Hal ini adalah pilihan desain yang diambil oleh desainer C++ (Bjarne Stroustrup) untuk menggunakan C sebagai basis C++ ketimbang membuat bahasa yang sama sekali baru. Tentunya ada konsekuensi atas pilihan desain ini, salah satu contoh adalah

kompatibilitas terhadap bahasa C. Dalam bahasa C deklarasi,

struct C { … };

menyatakan C sebagai nama tag. Nama tag berbeda dengan nama tipe, sehingga C (nama tag) tidak dapat dipergunakan dalam deklarasi yang membutuhkan C sebagai suatu tipe obyek. Kedua contoh deklarasi berikut ini tidak valid dalam bahasa C,

C c; /* error, C adalah nama tag */ C *pc; /* error, C adalah nama tag */

Dalam bahasa C, kedua deklarasi tersebut harus ditulis sebagai berikut,

Gambar

Gambar di atas merupakan ilustrasi dari objek objekBilangan dengan 2 member data, yakni

Referensi

Dokumen terkait

Return On Asset (ROA) yang positif menyatakan bahwa dari seluruh total aktiva yang digunakan untuk beroperasi, bank mampu memberikan laba bagi bank sedangkan jika Return

rahmat dan karunia-Nya penulis dapat menyelesaikan penelitian dan penyusunan skripsi dengan judul “Penetapan Kadar Formaldehida pada Ikan Kembung Banjar yang Dijual

Karena Level Gauge merupakan kelengkapan (accessories) tangki storage chemical injection , maka untuk merancang level gauge harus mengikuti design dari tangki storage

Media utama berupa buku ilustrasi ensiklopedia jenis-jenis burung Rangkong yang ada di Indonesia memiliki tujuan untuk mengedukasi target audience yaitu anak-anak usia sekolah

Penelitian ini bertujuan untuk mengetahui apakah ada hubungan Proses Asuhan Gizi Terstandar (PAGT) terhadap tingkat kepuasan dan lama hari rawat inap pasien anak dengan

Uji keragaman bobot dilakukan dengan syarat bahwa tidak boleh terdapat lebih dari dua suppositoria yang bobotnya menyimpang yang bobotnya menyimpang dari bobot rata-rata lebih

Gerakan tekuk lebih mudah (lebih kecil energinya) daripada gerakan ulur sehingga pita vibrasi ulur muncul pada frekuensi lebih tinggi daripada vibrasi tekuk... •

Penelitian ini bertujuan untuk mengetahui dan menjelaskan: (1) pengaruh orientasi pasar terhadap keunggulan bersaing: (2) pengaruh Inovasi terhadap Keunggulan