Pemrograman Dasar C Minggu 11
Topik Bahasan • Teknik Sort (Pengurutan) – Bubble Sort (menggunakan pass-by-reference)
• Kehandalan program input – nilai return gets() & sscanf
• Library Standard – Banyak fungsi library yang berguna dll – Penggunaan header file yang sesuai
Topik Bahasan • Isu ukuran bilangan – ERROR divide by zero – Bilangan sangat kecil dan sangat besar • Integer dan Riil
• Operator Bit – And ‘&’ Or ‘|’ Exor ‘^’ Comp ‘~’ – Operator shift (geser) Left << & Right >>
Penjelasan Bubble Sort • Bubble sort mengubah array, membawa nilai terbesar ke bagian akhir [0] and kemudian terbesar kedua ke [1] selanjutnya, dst. (seperti gelembung yang bermunculan diatas gelas) • Asumsikan CLSS_SIZ 4 & array dimulai sbb: mark array adalah [0] = 2 [1] = 5 [3] = 9 [3] = 3 Maka sort (pengurutannya) terjadi sbb:
Penjelasan Bubble Sort • Iterasi loop luar pertama k = 0, j = 3 [0] = 2 [1] = 5 [2] = 9 [3] tanpa swap =3 k = 0, j = 2 =3
[0] = 2 [1] = 9swap[2] = 5 [3] swap
k = 0, j = 1 =3
[0] = 9 [1] = 2 [2] = 5 [3]
Penjelasan Bubble Sort • Iterasi loop luar kedua k = 1, j = 3 [0] = 9 [1] = 2 [2] = 5 [3] tanpa swap =3 k = 1, j = 2 =3
[0] = 9
[1] = 5swap[2] = 2 [3]
• Iterasi loop luar terakhir
swap
Contoh Program – Bubble Sort
#include <stdio.h> parameter pointer #define CLSS_SIZ 4 void bsort( int *ary, int siz) { int j, k, temp; for(k = 0; k < siz – 1; ++k) for(j = CLS_SIZ – 1; j > k; --j) if(ary[j-1] < ary[j]) { temp = ary[j-1]; /* rutin swap */ ary[j-1] = ary[j]; ary[j] = temp; }} /* akhir dari fungsi */ int main (void) { int mark [CLSS_SIZ], i;
pointer diperlakukan sbg array
array lokal di main()
for(i = 0; i < CLSS_SIZ; i++) { printf(“\nMasukkan nilai %d “, i); scanf(“%d”, &mark[i]); /* load array */ } array dikirim by reference bsort(mark, CLSS_SIZ); for(i = 0; i < CLSS_SIZ; i++) printf(“\nmark[%d] = %d”, i, mark[i]); return (0); } /* akhir main */
Toleransi dari Input yang Tdk Sesuai • Kita sudah melihat “cek kisaran” dari input dengan mengetes nilai input di dalam kisaran. • scanf memberikan beberapa feedback dari input yang diubah melalui nilai return dari fungsi: scanf mengembalikan sebuah bilangan integer mengindikasikan berapa item data yang telah dikonversikan dengan benar.
Toleransi dari Input yang Tdk Sesuai #include <stdio.h> int main (void) { int x, chk; printf(“\n Masukkan satu desimal”); chk = scanf(“%d”, &x); if (chk = = 1) printf(“satu dikonversikan sebagai %d”, x); else printf(“\nInput tidak diterima”); return (0); } •
•
Input “27” dan tekan Enter dan scanf akan mengembalikan nilai 1 sebagai tanda diterimanya data, input “a” dan tekan Enter dan scanf akan mengembalikan 0 dan pesannya akan mengindikasikan nilai tidak diterima. Nilai return menyediakan cara yang mudah mengecek keberhasilan
Pemrograman Handal berlanjut • scanf sendiri tidak terlalu handal, kadangkadang macet, terkadang lebih baik menggunakan gets() untuk mengambil input sebagai string (array) dan menggunakan sscanf() untuk mengekstrak data yang diperlukan dari string tsb.
Pemrograman Handal berlanjut
• •
int main (void) char buf [80]; unsigned int d, m, y; int chk do { printf(“\nMasukkan tanggal format dd/mm/yy: “); gets(buf); chk = sscanf(buf, “%u %u %u, &d, &m, &y); if (chk != 3) printf(“Error coba lagi : “); } while (chk != 3); printf(“\nPada tanggal %u bulan %u di tahun %u”, d, m, y); return (0); } scanf mengharapkan sebuah urutan dari 3 bilangan desimal dipisahkan dengan ‘/’, hanya ketika benar program akan maju lebih dari loop do...while Pengembangan lebih lanjut dengan memonitor nilai return gets() (mengembalikan NULL jika mengambil stringnya gagal).
Library Standard • Standard C Library telah banyak dibuat, untuk menggunakannya tinggal di #include-kan nama file header nya (nama yang berakhiran .h) seperlunya. • Beberapa library yang berguna: – stdio.h – fungsi standar input dan output (seperti printf, scanf, dll) – math.h – berbagai fungsi matematika, sin, cos, log, powers, square-roots dll (catatan: selalu pakai double)
Library Standard • Beberapa library yang berguna: – string.h – fungsi untuk memanipulasi string, mencari string dll. – ctype.h – fungsi yang berguna untuk mengetes karakter (sebagai integer) “apakah alfabetik?” dll.
• File-file header berisi definisi dan prototype fungsi. Melihat dari prototype, parameter formal dan tipe return yang didefinisikan menunjukkan bagaimana menggunakan fungsi-fungsi ini. (Lihat folder include di kompiler). • Dapat mengikut sertakan fungsi sendiri ke dalam library sendir (untuk digunakan di program lain), hanya membutuhkan header file sendiri di definisi dan prototype fungsi dari fungsi sendiri.
Isu Bilangan Besar - Kecil • Matematika Integer – Header file limits.h mengandung konstan yang didefinisikan limit dari kompiler tertentu pada ukuran tipe integer, contoh: • INT_MAX untuk TurboC: +32767 • INT_MIN untuk TurboC: -32768 • ULONG_MAX untuk TurboC: +4,294,967,295
• Perhatikan situasi berikut: int a = 800, b = 700, c; c = a * b;
Isu Bilangan Besar - Kecil • Secara jelas hasil arithmatika adalah 560,000 tapi int tidak cukup besar untuk menampungnya (dikenal sebagai overflow). C tidak mempunyai aturan yang jelas tentang ini. • Ingat: tidak hanya penting untuk meningkatkan ukuran dari lokasi penerima (‘c’) misalnya tipe long int tapi juga operan ‘a’ atau ‘b’ untuk memastikan perhitungan dilakukan dengan ruangan yang cukup! (dapat dilakukan dengan casting, misalnya ‘a’ ke long int).
Tambahan Isu Bilangan Besar Kecil • Perhatikan pembagian dengan nol: int a = 1, b = 0, c; c = a/b;
• Dalam terminologi matematika, c seharusnya tak terhingga. Seperti yang kita lihat pada limits.h bilangan integer terbesar tetap terhingga maka hasil perhitungan ini tidak dapat ditangani dengan benar. Perhitungan seperti ni akan menghasilkan error “run time”: Divide Error dan program berhenti.
Tambahan Isu Bilangan Besar Kecil • Maka, masuk akal untuk mencari usaha pembagian dengan nol (catatan: ini termasuk usaha mencari modulus dari sesuatu dibagai nol contohnya c = b%0) dan menyetopnya, mengirim pesan yang sesuai ke screen: int a = 0, b = 800, c; if( a = = 0) { printf(“divide by zero err!”); exit (1); } c = b/a;
• CATATAN: exit() adalah dari <stdlib.h>
Isu Besar – Kecil di Float • Matematika Floating Point: – Lagi, bilangan yang bisa disimpan menggunakan tipe floating point, seperti double atau float, merupakan kisaran bilangan yang terbatas (finit), konstan yang mendefinisikan nilai ini, misalnya pada kompiler Borland, disimpan di values.h: • • • •
MAXDOUBLE = 1.797693E+308 MAXFLOAT = 3.37E+38 MINDOUBLE = 2.225074E-308 MINFLOAT = 8.43E-37 dst.
Isu Besar – Kecil di Float • Seperti pada tipe integer, tipe floating point dapat merepresentasikan tak terhingga: double a = 1.0, b = 0.0, c; c = a/b;
• Mencoba untuk menjalankan kode diatas akan menghasilkan: Floating point error: Divide by Zero Abnormal Program Termination
• Lagi C tidak mempunyai aturan yang jelas tentang ini, semuanya tergantung pada kompiler dan mesinnya masing-masing.
Tambahan Isu Besar-Kecil di Float • Arithmatika floating point dapat menyebabkan kondisi ‘overflow’ & ‘underflow’. Biasanya menyebabkan berhentinya program dan pesan runtime error. • Sebuah Domain error terjadi jika ada usaha untuk melaksanakan operasi dimana salah satu dari operan ada diluar ‘domain’ yang seharusnya operasi didefinisikan untuk bekerja, contohnya: double a = 0.0, b = 0.0, c; c = a/b;
Tambahan Isu Besar-Kecil di Float • Akan menyebabkan sebuah program termination dan melaporkan domain error. Fungsi math lib diberi parameter aktual diluar domain akan mengembalikan nilai NAN yang berarti ‘not-anumber’ tapi tidak berhenti. • Sebuah Range error akan terjadi jika hasil dari operasi diluar kisaran (range) yang dapat direpresentasikan oleh tipe returnnya. Sebuah fungsi matematika yang akan mengembalikan sebuah bilangan diluar kisaran (out-of-range) akan mengembalikan HUGE_VAL
Operator BIT • Semua standard tipe dalam C disimpan oleh komputer sebagai pola binari bit. Kita telah tahu sebuah variabel dari tipe char biasanya disimpan ke dalam sebuah byte tunggal pada PC. Satu byte terdiri dari 8 bit, contohnya 10010110 dimana posisi setiap bit dapat diinterpretasikan sbb: x 27 x 26 x 25 x24 x 23 x 22 x 21 x20 jadi 100101102 = 15010
• Sejauh ini operator yang kita gunakan (‘+’, ‘-’, ‘*’, dll) berlaku kepada variabel secara keseluruhan, tidak terpisah terhadap bit dari variabel tsb.
Operator BIT • Operator secara bit (bit-wise) berguna untuk programming ‘low level’ ketika kita ingin bermain dengan bit secara individu. • Pertama, pengingat dari representasi heksadesimal, yaitu bilangan dengan basis 16, dimana setiap posisi dapat diinterpretasikan sebb: x 163 x 162 x161 x 160 jadi 15010 = 9616 = 100101102 Dalam C kita menulis bilangan heks dengan 0x didepan jadi 15010 = 9616 = 0x96 Dengan printf dan scanf kita gunakan %x untuk Hex I/O
Operator Binari Bit Operator Fungsi a = 00101101 = 0x2d b = 11101001 = 0xe9 AND & c=a&b 00101101 & 11101001 OR | c=a|b 00101101 | 11101001 EXOR ^ c=a^b 00101101 ^ 11101001
Hasil c = 0x29 00101001 c = 0xed 11101101 c = 0xc4 11000100
Operator Binari Bit • Pada setiap kasus operator bekerja pada satu bit dari salah satu operan dan korespondensi bit dari operan yang lain pada satu waktu. char inc_limit (char a) { const char b = 0x0F; a = ++a & b; return (a); } Pada fungsi diatas, parameter aktual a dinaikkan dulu (increment) kemudian di bit-wise AND denga pola 00001111 (digunakan sebagai mask) jadi effeknya adalah menjamin bahwa a tidak pernah lebih dari 0001111. ‘++’ mempunyai prioritas lebih tinggi daripada ‘&’.
Tambahan Operator Bit-Wise Operator shift (geser): • Geser kiri << dan Geser kanan >> a = b << 3; akan mempunyai efek menggeser pola bit b 3 tempat ke kiri dengan nol mengisi pada sebelah kanan jadi jika b = 11101001 maka a akan menjadi 01001000. Setiap geser kiri seperti mengalikan dengan 2! a = b >> 2; akan mempunyai efek menggeser pola bit b 2 tempat ke kanan dengan apapun yan menjadi bit terbesar (MOST SIGNIFICANT BIT) dari pola bit menjadi pengisi dari sebelah kiri (memperpanjang tanda) jadi bila b = 11101001 maka a akan menjadi 11111010. Setiap geser kiri seperti membagi dengan 2!
Tambahan Operator Bit-Wise • Operator Compliment ~ Adalah operator tunggal (unary) jadi a = ~b; akan membalikkan semua pola bit yang ada di b dan menyimpan di a. Jika b = 00101101 maka a = 11010010
Rangkuman Akhir • Perencanaan dalam kertas – tahu apa yang harus dikerjakan sebelum koding: – Identifikasi titik keputusan (pilihan): • if untuk ‘jika ...atau ...’ atau case untuk pilihan banyak.
– Identifikasi repetisi (loop): • do .. while() untuk ‘selalu lakukan sekali, kemudian tentukan’. • while() untuk ‘tentukan sebelum loop pertama’ • for bentuk while yang padat (compact)
Rangkuman Akhir • Identifikasi kandidat fungsi – ‘Bagi dan Kuasai’ – Tugas yang mandiri – membuat segala sesuatu sederhana, membantu daya baca. – Tugas berulang, fungsi dibutuhkan ditempat lain, menghindari pengulangan kode.
• Pilihlah variabel dengan bijaksana – Hindari variabel tingkat file dan static yang tidak diperlukan (jangan membuang-buang memory). – Gunakan variabel lokal kepada fungsi dimana dapat diketahui tentang waktu hidupnya (menghindari kebingungan). – Pilihlah tipe yang sesuai dengan kisaran dan presisi yang dibutuhkan dalam perhitungan.
Rangkuman Akhir – Gunakan array (set dari tipe sama) dan structure (set dari tipe berbeda) untuk mengumpulkan data bersama. – Gunakan pointer untuk memberikan fungsi dll akses langsung kepada variabel diluar lingkup (out-of-scope), untuk memberikan akses kepada seluruh array dll.
• Testing, testing, testing: – Gunakan printf untuk menunjukkan apa yang terjadi. – Tes secara bertahap • Gunakan stub (fungsi dummy) untuk fungsi yang belum ditulis • Gunakan driver (main dummy) untuk mengetes fungsi secara terisolasi.
Rangkuman Akhir • Verifikasi – Perlu menjamin program benar-benar berjalan dalam kisaran yang dispesifikasi.
• Gunakan desain kertas secara top-down dan implementasi koding secara bottomup.