Академический Документы
Профессиональный Документы
Культура Документы
C e p at M ah i r
Bahasa C
IlmuKomputer.Com
Lisensi Dokumen:
Copyright 2003 IlmuKomputer.Com Seluruh dokumen di IlmuKomputer.Com dapat digunakan, dimodifikasi dan disebarkan secara bebas untuk tujuan bukan komersial (nonprofit), dengan syarat tidak menghapus atau merubah atribut penulis dan pernyataan copyright yang disertakan dalam setiap dokumen. Tidak diperbolehkan melakukan penulisan ulang, kecuali mendapatkan ijin terlebih dahulu dari IlmuKomputer.Com.
Biografi Penulis
Romi Satria Wahono. Lahir di Madiun, 2 Oktober 1974. Menamatkan SMU di SMU Taruna Nusantara, Magelang pada tahun 1993. Menyelesaikan program S1 dan S2 pada jurusan Informatika dan Ilmu Komputer di Saitama University, Jepang pada tahun 1999 dan 2001. Saat ini sedang menyelesaikan program S3 (PhD) pada jurusan dan universitas yang sama. Di Indonesia berstatus sebagai peneliti pada instansi Lembaga Ilmu Pengetahuan Indonesia (LIPI), tepatnya di Pusat Dokumentasi Informasi Ilmiah (PDII). Kompetensi inti adalah pada bidang Software Engineering, Object-Orientation, Software Pattern, Software Agent, Jaringan Komputer dan Web Engineering. Aktif sebagai penulis, dimana puluhan tulisan berupa scientific paper, artikel, dan tutorial telah diterbitkan dalam berbagai proceedings conference, jurnal ilmiah, majalah, koran dan portal, bertaraf nasional maupun internasional. Publikasi penulis selengkapnya bisa didapat dari URL http://romisatriawahono.net/publications Berpengalaman sebagai engineer, konsultan dan lecturer di berbagai perusahaan Jepang dan Indonesia, dalam bidang yang berhubungan dengan Ilmu Komputer dan Teknologi Informasi, khususnya tentang bahasa pemrograman, sistem operasi, jaringan komputer, administrasi server, aplikasi database, dan pemrograman berbasis web. Anggota dari society ilmiah ACM, IEEE Computer Society, IEICE, IPSJ, JSAI, dan IECI. Aktif dalam berbagai organisasi pelajar dan kemahasiswaan (Ketua Umum PPI Jepang 2001-2003), dan organisasi society ilmiah (Ketua IECI Japan 2001-2002). Romi Satria Wahono adalah pendiri dan pengelola beberapa situs dan perusahaan yang bergerak di bidang teknologi informasi, diantaranya adalah: IlmuKomputer.Com, Gegar Technologies, Green Digital Press. Informasi lebih lanjut tentang penulis ini bisa didapat melalui: URL: http://romisatriawahono.net Email: romi@romisatriawahono.net
Bab 1 Pendahuluan
Gambar 1: Sejarah Bahasa C Boleh dikatakan bahwa akar dari bahasa C adalah bahasa BCPL yang dikembangkan oleh Martin Richards pada tahun 1967. Kemudian berdasar pada bahasa BCPL ini Ken Thompson yang bekerja di Bell Telephone Laboratories (Bell Labs) mengembangkan bahasa B pada tahun 1970. Saat itu bahasa B telah berhasil diimplementasikan di komputer DEC PDP-7 dengan operating system (OS) UNIX. Pada tahun 1972, peneliti lain di Bell Labs bernama Dennis Ritchie menyempurnakannya menjadi bahasa C.
Gambar 2: Tokoh Yang Berjasa Dalam Pengembangan Bahasa C Pada tahun 1978, Dennis Ritchie bersama dengan Brian Kernighan mempublikasikan buku yang kemudian menjadi legenda dalam sejarah perkembangan bahasa C, yang berjudul The C Programming Language. Buku ini diterbitkan oleh Prentice Hall, dan pada saat ini telah diterjemahkan dalam berbagai bahasa di dunia. Boleh dikatakan bahwa buku ini adalah buku yang paling banyak direfer orang dan dijadikan buku panduan tentang pemrograman bahasa C sampai saat ini. Teknik dan gaya penulisan bahasa C yang merefer kepada buku ini kemudian terkenal dengan sebutan K&R C atau Classic C atau Common C. Seiring dengan berkembang pesatnya bahasa C, banyak vendor mengembangkan kompiler C menurut versi masing-masing. Hal ini menggerakkan ANSI (American National Standards Institute) pada tahun 1983 untuk membuat suatu komite yang kemudian diberi nama X3J11, yang betujuan untuk membuat definisi standar bahasa C yang lebih modern dan komprehensif, dengan memperbaiki syntax dan grammar bahasa C. Usaha ini berhasil diselesaikan 5 tahun kemudian, yaitu ditandai dengan lahirnya standard ANSI untuk bahasa C yang kemudian terkenal dengan sebutan ANSI C pada tahun 1988.
semakin sulit dipahami manusia dan hanya berisi perintah untuk mengakses bahasa mesin. Dalam perspektif mudahnya dipahami manusia, C bisa digolongkan dalam bahasa tingkat tinggi, namun C juga menyediakan kemampuan yang ada pada bahasa tingkat rendah, misalnya operasi bit, operasi byte, pengaksesan memori, dsb. Beberapa alasan mengapa memakai bahasa C adalah terangkum dibawah. C adalah bahasa pemrograman yang paling populer saat ini Dengan banyaknya programmer bahasa C, membawa pengaruh semakin mudahnya kita menemukan pemecahan masalah yang kita dapatkan ketika menulis program dalam bahasa C. Pengaruh positif lain adalah semakin banyaknya kompiler yang dikembangkan untuk berbagai platform (berpengaruh ke portabilitas). C adalah bahasa pemrograman yang memiliki portabilitas tinggi Program C yang kita tulis untuk satu jenis platform, bisa kita kompile dan jalankan di platform lain dengan tanpa ataupun hanya sedikit perubahan. Ini bisa diwujudkan dengan adanya standarisasi ANSI untuk C. C adalah bahasa pemrograman dengan kata kunci (keyword) sedikit Kata kunci disini adalah merupakan fungsi ataupun kata dasar yang disediakan oleh kompiler suatu bahasa pemrograman. Hal ini membawa pengaruh semakin mudahnya kita menulis program dengan C. Pengaruh lain dari sedikitnya kata kunci ini adalah proses eksekusi program C yang sangat cepat. C hanya menyediakan 32 kata kunci seperti terangkum dibawah:
auto do goto signed unsigned break double if sizeof void case else int static volatile char enum long struct while const extern register switch continue float return typedef default for short union
C adalah bahasa pemrograman yang fleksibel Dengan menguasai bahasa C, kita bisa menulis dan mengembangkan berbagai jenis program mulai dari operating system, word processor, graphic processor, spreadsheets, ataupun kompiler untuk suatu bahasa pemrograman. C adalah bahasa pemrograman yang bersifat moduler Program C ditulis dalam routine yang biasa dipanggil dengan fungsi. Fungsi-fungsi yang telah kita buat, bisa kita gunakan kembali (reuse) dalam program ataupun aplikasi lain.
Gambar 4: Proses Pembuatan Program C 1. Tulis source code program bahasa C dengan menggunakan text editor, kemudian simpan dalam sebuah file. Text editor disini bisa merupakan aplikasi notepad atau editplus pada windows, untuk operating system unix/linux kita bisa menggunakan aplikasi emacs yang cukup terkenal. Kompile file yang berisi source code program bahasa C. Kompilasi atau kompile (compile) adalah suatu proses merubah source code ke bahasa mesin sehingga bisa dieksekusi (executable) atau dijalankan. Banyak sekali kompiler bahasa C yang ada saat ini, baik yang gratis maupun yang kita harus membeli untuk menggunakannya. Untuk memudahkan proses belajar bahasa C, penulis memberikan rekomendasi untuk menginstall Cygwin (www.cygwin.com) bagi yang menggunakan operating system Windows. Cygwin adalah satu set free software yang dikembangkan oleh Redhat, yang berisi koleksi aplikasi dan tools UNIX yang didesain khusus untuk bisa dijalankan di Windows. Kebutuhan akan kompiler (GCC, GNU C Compiler) dan shell (Bash Shell) untuk membuat program C bisa kita dapatkan dengan menginstall Cygwin ini. Jalankan program yang telah dikompile. Setelah kita kompile file yang berisi source code, maka sebagai hasil kompilasi tersebut kita akan mendapatkan suatu file yang bisa dijalankan (executable file). Menjalankan program yang kita buat berarti menjalankan file hasil proses kompilasi tersebut.
2.
3.
Lisensi Dokumen:
Copyright 2003 IlmuKomputer.Com Seluruh dokumen di IlmuKomputer.Com dapat digunakan, dimodifikasi dan disebarkan secara bebas untuk tujuan bukan komersial (nonprofit), dengan syarat tidak menghapus atau merubah atribut penulis dan pernyataan copyright yang disertakan dalam setiap dokumen. Tidak diperbolehkan melakukan penulisan ulang, kecuali mendapatkan ijin terlebih dahulu dari IlmuKomputer.Com.
f (i ) (a) k f ( x) = x i =0 i!
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. Pertama tama kita mencari dulu turunan masing masing tingkat dari cos(x) serta hasilnya bila x = 0 (Maclaurin) Turunan 0 1 2 3 4 dan seterusnya jika diterjemahkan dalam bahasa C maka aka menjadi :
int turunan(int n) { int hasil; n = n % 4; switch(n) { case 0 : hasil = case 1 : hasil = case 2 : hasil = case 3 : hasil =
x=0 1 0 -1 0 1
} 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 2. pembilang = 1 3. penyebut = 1 4. hasil = 0 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 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 = case 1 : hasil = case 2 : hasil = case 3 : hasil = } 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.
Lisensi Dokumen:
Copyright 2003 IlmuKomputer.Com Seluruh dokumen di IlmuKomputer.Com dapat digunakan, dimodifikasi dan disebarkan secara bebas untuk tujuan bukan komersial (nonprofit), dengan syarat tidak menghapus atau merubah atribut penulis dan pernyataan copyright yang disertakan dalam setiap dokumen. Tidak diperbolehkan melakukan penulisan ulang, kecuali mendapatkan ijin terlebih dahulu dari IlmuKomputer.Com.
Berikut adalah Algoritma Euclidian untuk menemukan FPB dari 2 buah bilangan 1. 2. 3. 4. Input Bilangan1 Input Bilangan2 Sisa = Bilangan1 modulus Bilangan2 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
Lisensi Dokumen:
Copyright 2003 IlmuKomputer.Com Seluruh dokumen di IlmuKomputer.Com dapat digunakan, dimodifikasi dan disebarkan secara bebas untuk tujuan bukan komersial (nonprofit), dengan syarat tidak menghapus atau merubah atribut penulis dan pernyataan copyright yang disertakan dalam setiap dokumen. Tidak diperbolehkan melakukan penulisan ulang, kecuali mendapatkan ijin terlebih dahulu dari IlmuKomputer.Com.
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. A 0 0 1 1 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 . C = A xor B B = C xor B A = C xor B B A xor B 0 0 1 1 0 1 1 0
// pertama // 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 ) .
Lisensi Dokumen:
Copyright 2003 IlmuKomputer.Com Seluruh dokumen di IlmuKomputer.Com dapat digunakan, dimodifikasi dan disebarkan secara bebas untuk tujuan bukan komersial (nonprofit), dengan syarat tidak menghapus atau merubah atribut penulis dan pernyataan copyright yang disertakan dalam setiap dokumen. Tidak diperbolehkan melakukan penulisan ulang, kecuali mendapatkan ijin terlebih dahulu dari IlmuKomputer.Com.
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. A 0 0 1 1 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 . C = A xor B B = C xor B A = C xor B B A xor B 0 0 1 1 0 1 1 0
// pertama // 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 ) .
Lisensi Dokumen:
Copyright 2003 IlmuKomputer.Com Seluruh dokumen di IlmuKomputer.Com dapat digunakan, dimodifikasi dan disebarkan secara bebas untuk tujuan bukan komersial (nonprofit), dengan syarat tidak menghapus atau merubah atribut penulis dan pernyataan copyright yang disertakan dalam setiap dokumen. Tidak diperbolehkan melakukan penulisan ulang, kecuali mendapatkan ijin terlebih dahulu dari IlmuKomputer.Com.
Rekursif
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.
[ret-val] coba([parameter]) { // statement coba([parameter]) // statement }
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 :
void rekursi(int a,int b) { if (b == 0) return; a++; b--; printf("Masuk -> a = %d || b = %d \n",a,b); rekursi(a,b); printf("Keluar -> a = %d || b = %d \n",a,b); }
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 ->
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 :
Rekursi(3,3) 1 Rekursi(4,2) 2 Rekursi(5,1) 3 Rekursi(6,0) 4 5 6
Langkah ke : 1. a = 4 ; b = 2 . Cetak : Masuk 2. a = 5 ; b = 1 . Cetak : Masuk 3. a = 6 ; b = 0 . Cetak : Masuk 4. a = 6 ; b = 0 , Cetak : Keluar 5. a = 5 ; b = 1 , Cetak : Keluar 6. a = 4 ; b = 2 , Cetak : Keluar
Untuk memperjelas lagi penggunaan fungsi rekursif dibawah ini akan di berikan contoh contoh program dengan menggunakan rekursif .
N! = N x (N 1) !
Nah dari daftar diatas dapat dibuat fungsi rekursi untuk menghitung nilai faktorial ke n yaitu n > 1 n * Fakt (n 1) Fakt (n) = n == 0 || n == 1 1 Jika di terjemahkan ke dalam bahasa C menjadi : int Fakt(int n) { if (n == 1 || n == 0) return 1; return n * Fakt(n-1); }
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 Maka akan didapat rumusan untuk bilangan Fibonacci berupa : n > 1 Fibo(n 1) + Fibo(n 2) Fibo(n) = n == 1 || n == 0 1 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
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 (N2) 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) { if (n == 0) return; Hanoi(n-1,asal,tujuan,bantu); // pindahkan piringan ke n // dari asal menuju tujuan // melalui 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
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 Pindahkan piringan ke 1 ke dari a ke c
Lisensi Dokumen:
Copyright 2003 IlmuKomputer.Com Seluruh dokumen di IlmuKomputer.Com dapat digunakan, dimodifikasi dan disebarkan secara bebas untuk tujuan bukan komersial (nonprofit), dengan syarat tidak menghapus atau merubah atribut penulis dan pernyataan copyright yang disertakan dalam setiap dokumen. Tidak diperbolehkan melakukan penulisan ulang, kecuali mendapatkan ijin terlebih dahulu dari IlmuKomputer.Com.
Dibawah ini ialah salah satu metode konvensional untuk merubah bilangan dengan basis dasar 10 ke basis lainnya , yang mana penulis dapat ketika masih duduk di bangku sekolah dasar . Misalkan kita ingin mencari berapakah nilai bilangan 10 dalam basis 10 jika di konversi ke basis 2 (biner) . Untuk itu perhatikan gambar berikut
10 0 5 1 2 0 1 1 0
Gambar1
Pada gambar 1 didapat bahwa 10(10) = 1010(2) Algoritma pada gambar 1 dapat dijelaskan sebagai berikut . Nilai 10 kita bagi dengan basis tujuan yang kita mau (dalam hal ini 2 ) maka akan dihasilkan 5 , dengan sisa 0 . Kemudian 5 kita kembali bagi dengan basis yang kita tuju , sehingga 5 dibagi dengan 2 . Maka akan didapat 2 dengan sisa 1 begitu seterusnya. Langkah ini diulangan terus sampai hasil dari pembagian ialah 0 . Hasil konversinya didapat dari merunut sisa hasil pembagian dari yang paling bawah ke atas ( lihat gambar ) Dari gambar diperoleh 1010 sebagai hasil. Listing Program Setelah kita tahu cara metode pengkonversiannya , maka tentunya tidak sulit lagi untuk membuatnya kedalam bahasa pemrograman C . Untuk memudahkan dan sekalian memahami penggunaan rekursif , maka fungsi akan dibuat dengan menggunakan rekursif Berikut ialah listing programnya :
#include <stdio.h> char ch[17] = "0123456789ABCDEF"; void CetakBaseN(int base,int nilai) { if (nilai == 0) return; CetakBaseN(base,nilai / base); printf("%c",ch[nilai % base]); } void main(void) { CetakBaseN(2,255); printf("\n"); CetakBaseN(8,255); printf("\n"); CetakBaseN(10,255); printf("\n"); CetakBaseN(16,255); printf("\n"); } Cara kerja Fungsi CetakBaseN
CetakBase(2,10) 1 CetakBase(2,5) 2 CetakBase(2,2) 3 CetakBase(2,1) 4 CetakBase(2,0) 5 6 7 8
Misalkan kita memanggil fungsi CetakBaseN dengan nilai base = 2 dan nilai = 10 . Maka pertama tama dicek apakah nilai = 0 , jika sama maka langsung keluar . Ternyata nilai tidak sama dengan 0 maka lanjutkan pada baris berikutnya . Yaitu memanggil dirinya sendiri dengan parameter nilai yang kini bernilai nilai / base ( 10 / 2 = 5) (Langkah 1) Kemudian di cek kembali apakah nilai == 0 , dilanjutkan dengan memanggil dirinya sendiri yang kini parameter nilai bernilai nilai / base (5 / 2 = 2) (Langkah 2) begitu seterusnya . Ketika nilai == 0 (pada pemanggilan fungsi yang ke 5) maka fungsi akan keluar (Langkah 5) dan akan melanjutkan fungsi pemanggilnya yaitu mencetak sisa dari nilai / base . Kemudian fungsi akan keluar lagi (Langkah 6 ) dan kembali mencetak sisa dari nilai / base fungsi pemanggilnya dan begitu seterusnya.
Lisensi Dokumen:
Copyright 2003 IlmuKomputer.Com Seluruh dokumen di IlmuKomputer.Com dapat digunakan, dimodifikasi dan disebarkan secara bebas untuk tujuan bukan komersial (nonprofit), dengan syarat tidak menghapus atau merubah atribut penulis dan pernyataan copyright yang disertakan dalam setiap dokumen. Tidak diperbolehkan melakukan penulisan ulang, kecuali mendapatkan ijin terlebih dahulu dari IlmuKomputer.Com.
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 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"); 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) { SaySatuan(nilai / 10); printf(" puluh "); SaySatuan(nilai % 10); //Cetak puluhan diikuti kata puluh // kemudian cetak satuan // Nilai Puluhan bisa dicari dengan // membaginya dengan 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 if (nilai >= 200 && nilai <= 999) // jika diatasnya , bilang nilai { // ratusannya diikuti dengan kata SaySatuan(nilai / 100); printf(" ratus "); // ratus } if(nilai % 100 != 0) SayPuluhan(nilai % 100); //Hindari jika kelipatan 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) SayRatusan(nilai % 1000); // seleksi kelipatan 1000 // diikuti dengan mencetak digit sisanya
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 . Oke saya rasa sekian saja Kita jumpa lain waktu lain kesempatan 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)
{ }
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);