Pemrograman Dasar Dengan C-CPP
Pemrograman Dasar Dengan C-CPP
Pemrograman Dasar Dengan C-CPP
Disusun oleh:
Rihartanto
Arief Bramanto Wicaksono Putra
Samarinda, 2015
i
PRAKATA
ii
DAFTAR ISI
PRAKATA......................................................................................................................... ii
BAB I.................................................................................................................................. 1
BAB II .............................................................................................................................. 13
BAB IV ............................................................................................................................. 35
STATEMEN KONDISI.................................................................................................. 35
BAB V .............................................................................................................................. 51
PERULANGAN .............................................................................................................. 51
iii
5.1 Perulangan .............................................................................................................. 51
BAB VI ............................................................................................................................. 81
ARRAY ............................................................................................................................ 81
iv
8.6 Aritmatika Pointer ................................................................................................ 138
v
12.1.1 Bubble Sort ................................................................................................... 184
12.1.2 Selection Sort ............................................................................................... 190
12.1.3 Insertion Sort ................................................................................................ 194
12.2 Searching ............................................................................................................ 199
vi
BAB I
Selain bahasa pemrograman yang lebih penting adalah alur logika dalam
membangun suatu program komputer. Alur logika ini sering juga disebut sebagai
algoritma. Secara sederhana, algoritma dapat dikatakan sebagai langkah-langkah berpikir
yang logis, terurut dan terstruktur untuk menyelesaikan suatu kasus atau permasalahan.
Algoritma dapat dianalogikan seperti halnya resep masakan, dimana pada resep
tersebut sudah dijelaskan jenis bahan apa saja yang diperlukan beserta ukurannya.
Kemudian dijelaskan juga cara-cara pengolahannya langkah per langkah. Jika bahan atau
urutan langkahnya diubah, dapat dipastikan bahwa hasilnya tidak akan sesuai dengan
yang seharusnya.
Hal yang sama juga terjadi pada suatu program komputer. Sebelum membuat
program, harus dipahami terlebih dahulu kasus atau permasalahan yang akan
disolusikan. Kemudian bahan-bahan yang diperlukan dilengkapi dan selanjutnya tahapan
langkah-langkahnya harus terurut, logis dan benar. Jika semua hal tersebut sudah
dilakukan, dapat diharapkan bahwa program komputer yang dihasilkan memang dapat
digunakan sebagai solusi untuk kasus atau permasalahan yang sedang dihadapi.
1
Sebagai contoh, misalkan kita akan membuat program untuk menentukan apakah
sebuah bilangan yang diinput dari keyboard merupakan bilangan genap atau bilangan
ganjil. Ketentuan dasar untuk menyatakan apakah sebuah bilangan genap atau ganjil
adalah dengan membagi bilangan tersebut dengan bilangan dua. Bilangan tersebut adalah
bilangan genap jika habis dibagi dengan dua, tetapi jika tidak habis dibagi dua maka
bilangan tersebut adalah bilangan ganjil. Algoritma untuk penyelesaian kasus tersebut
dapat dinyatakan sebagai berikut:
Beberapa simbol flowchart yang sering digunakan diantaranya dapat dilihat pada
tabel 1. Namun simbol yang dapat digunakan dalam flowchart tidak hanya terbatas itu
saja, karena masih banyak sibol-simbol lainnya yang mempunyai tujuan yang lebih
spesifik.
2
Decision Digunakan untuk memberikan kondisi untuk
memilih salah satu dari dua pilihan
Merujuk pada contoh kasus sebelumya tentang penentuan bilangan genap/ganjil. Maka
flowchart untuk penyelesaian kasus tersebut dapat dilihat pada gambar 1.
Start
Input
angka
Angka
angka % 2 ==
adalah
0
Genap
Angka
adalah
Ganjil
End
3
Flowchart selalu dimulai dengan terminator Start dan harus diakhiri dengan
terminator End. Arah aliran sebaiknya mengalir secara konsisten dari atas ke bawah dan
dari kiri ke kanan. Meskipun tidak dapat dikatakan sebagai kesalahan, namun diusahakan
agar tidak ada aliran yang berlawan arah atas/bawah dan kiri/kanan tersebut.
Beberapa aturan dasar yang biasanya digunakan untuk penamaan variabel dan
konstanta adalah sebagai berikut:
Dalam bahasa C/C++ nama variabel bersifat case-sensitive, artinya huruf besar
dan huruf kecil dibedakan, sehingga UMUR, umur, Umur, umuR dan uMur dianggap
sebagai nama-nama variabel yang berbeda. Aturan tentang penamaan variabel dan
konsonan ini juga berlaku untuk penamaan nama fungsi. Reserved word yang tidak boleh
digunakan sebagai nama variabel dapat dilihat pada tabel 2.
4
Tabel 2: Reserverd word bahasa C/C++
Berikut adalah contoh penamaan variabel yang benar dan yang salah
5
Tabel 3: Tipe data dalam bahasa C/C++
long double 8 bytes +/- 1.7e +/- 308 (~15 digits) C/C++
Setiap tipe data memiliki karakteristik yang berbeda-beda untuk untuk tujuan
yang berbeda pula dalam pemrograman.
1.4 Operator
Operator merupakan perintah yang digunakan untuk melakukan manipulasi atau
komputasi terhadap objek tertentu. Sedangkan objek yang dimanipulasi akan disebut
sebagai operand. Sebagai contoh adalah 2 + 3. Pada contoh tersebut + adalah operator,
2 dan 3 adalah operand.
6
hirarkinya. Artinya operasi perkalian akan dikerjakan terlebih dahulu sebelum operasi
penjumlahan dan pengurangan.
1 + 2 * 3
Hasil dari operasi aritmatika di atas adalah 7 bukan 9, karena sesuai dengan hirarkinya,
perkalian 2 * 3 dikerjakan terlebih dahulu baru hasilnya ditambahkan dengan 1. Jika
menginginkan agar hasilnya adalah 9, maka harus ditambahkan tanda kurung agar
operasi penjumlahan dikerjakan terlebih dahulu sebelum perkalian, sehingga operasinya
aritmatikanya ditulis menjadi (1+2) * 3.
Operator gabungan atau pemberi nilai aritmatika juga digunakan untuk operasi
matematika. Yang termasuk dalam operator gabungan ini dapat dilihat pada tabel 5.
7
Operator gabungan ini umumnya digunakan pada bahasa pemrograman C/C++
serta bahasa lain yang menerapkan konsep bahasa C seperti Java. Namun operator ini
tidak digunakan dalam bahasa pemrograman seperti Basic dan Pascal.
Jika a adalah sebuah variabel numerik yang akan ditambahkan nilainya dengan
1, operasi aritmatikanya dapat ditulis dengan a = a + 1. Namun jika menggunakan
operator gabungan akan ditulis dengan a += 1 dan jika menggunakan operator
penambah ditulis dengan a++. Operator penambah dan operator pengurang dapat
diletakkan sebelum atau setelah variabel. Jadi operasi a++ dapat juga ditulis menjadi
++a. Meskipun memiliki hasil akhir yang sama, namun terdapat perbedaan dalam hal
waktu pelaksanaan operasinya.
8
Sebagai operand dapat berupa variabel, nilai tertentu ataupun ekspesi matematis. Dalam
pemrograman, operator relasi biasanya digunakan dalam statement kondisi (decision).
Operator && memberikan nilai true hanya jika kedua operand yang dihubungkan
bernilai benar. Operator || bernilai benar jika salah satu operand yang dihubungkan
bernilai benar.
Yang terakhir adalah operator bitwise. Operator bitwise merupakan operator yang
digunakan untuk memanipulasi data dalam bentuk bit. Artinya, data baik angka maupun
karakter diubah ke dalam bentuk biner ketika dilakukan operasi bitwise. Operator bitwise
yang ada dapat dilihat pada tabel 9.
9
Jika x adalah 10011001 dan y adalah 11001100 maka operasi bitwise atas x dan y
adalah sebagai berikut:
~x ~(10011001) 01100110
10
11
12
BAB II
Saat ini banyak sekali tersedia compiler/linker yang dapat di download langsung
melalui internet. Sebagian gratis dan sebagian lagi berbayar. Juga tersedia compiler
untuk platform sistem operasi yang berbeda-beda, seperti untuk sistem operasi windows,
linux, OSX atau lainnya baik untuk arsitektur 32 bit atau 64 bit. Sebagian compiler
seperti gcc masih harus digunakan langsung pada baris perintah (command prompt) dan
sebagian lainnya sudah terintegrasi pada IDE, misalnya DevC++.
Buku ini menggunakan Dev C++ sebagai IDE. DevC++ dapat digunakan sebagai
IDE baik untuk membuat program menggunakan bahasa C atau pun C++. Informasi
lengkap tentang DevC++ dapat dilihat di alamat http://www.bloodshed.net dan
http://orwelldevcpp.blogspot.com/, termasuk link untuk melakukan downloadnya.
13
Gambar 2. Pemilihan bahasa untuk editor DevC++
DevC++ menyediakan pilihan bahasa yang dapat digunakan selain bahasa Inggris.
Namun bahasa Indonesia belum termasuk bahasa yang disediakan sebagai pilihan.
14
Dalam pengaturan tema, yang dapat diatur adalah jenis huruf, kombinasi warna serta
kelompok icon yang digunakan dalam IDE DevC++. Jika nantinya ingin mengganti tema
sedang digunakan dengan tema lain, dapat dilakukan melalui menu Tools->Editor
Options->Fonts/Color.
Pilihan ini digunakan untuk menentukan header file mana saja yang akan dimasukkan ke
dalam cache memory. Secara default DevC++ sudah memilihkan file-file header yang
paling sering digunakan dalam pemrograman C/C++.
Secara default, DevC++ dapat langsung digunakan setelah selesai instalasi tanpa
perlu mengubah setting parameter yang terdapat di dalamnya. Dan seperti umumnya
program aplikasi windows, program ini memiliki baris menu, toolbar, baris status dan
bagian-bagian lainnya yang cara penggunaannya mirip dengan aplikasi windows lainnya.
15
Gambar 5. Implementasi konfigurasi yang dipilih
16
Selain toolbar dan menu, DevC++ juga memberikan beberapa shortcut untuk
perintah-perintah yang sering digunakan. Misalkan untuk melakukan kompilasi dapat
dilakukan dengan memilih menu Execute->Compile atau dengan menekan icon
(compile) atau dengan menekan shortcut F7.
Editor DevC++ sendiri dibagi menjadi 3 bagian utama, yaitu project manager
yang digunakan untuk mengelola file-file proyek, report window yang digunakan untuk
menampilkan hasil atau status dari program yang sedang dikerjakan dan programming
area yang digunakan sebagai tempat menulis baris-baris perintah program. Namun
demikian, project manager dan report window ini dapat ditampilkan atau disembunyikan
sesuai dengan kebutuhan penggunanya.
Header adalah sebuah program dengan ekstensi .h (baca: titik H atau dot H) yang
berisi kumpulan fungsi yang berguna untuk pengolahan data. Sintak pendefinisian untuk
penyertaan header:
#include <namaheader.h>
Sebagai contoh untuk menyertakan file header "stdio.h" yang berisi kumpulan fungsi
untuk penanganan input/output standar dalam bahasa C ditulis sebagai berikut:
#include <stdio.h>
17
Tergantung kebutuhannya, dalam satu program dapat menyertakan lebih dari satu file
header. Misalkan selain fungsi input/output juga dibutuhkan fungsi untuk penanganan
operasi matematis dan operasi string. Maka penyertaan header file dapat ditulis sebagai
berikut:
#include <stdio.h>
#include <math.h>
#include <string.h>
Sebagai catatan, penyertaan file header diletakkan pada bagian awal dari sebuah
program, sedangkan urutannya tidak diperhatikan. Artinya urutan peletakan untuk
stdio.h, math.h dan string.h tidak selalu harus seperti pada contoh di atas. File
header standar yang disediakan dalam C/C++ dapat dilihat pada tabel 10.
Fungsi utama atau kadang-kadang disebut juga dengan program utama adalah
fungsi dalam C/C++ yang diberi nama dengan main. Dinamakan sebagai fungsi utama
karena fungsi inilah yang pertama kali dijalankan ketika program dieksekusi. Sehingga
18
jika dalam sebuah source program terdiri dari lebih dari satu fungsi, maka fungsi main-
lah yang biasanya digunakan untuk mengelola operasi fungsi-fungsi lainnya.
Struktur fungsi utama ini terdiri dari nama fungsi diikuti dengan blok statemen.
Cara penulisannya adalah sebagai berikut:
main()
{
statement_1;
statement_2;
...
statement_n;
}
Tergantung jenis compiler yang digunakan, fungsi utama ini dapat ditulis dengan
main(), int main(), void main(), int main(void), void
main(void), int main(int argc, char *aargv[]) atau lainnya.
#include <stdio.h>
void main()
{
printf("Mari belajar pemrograman");
}
Struktur yang sama juga berlaku untuk C++, perbedaannya adalah pada cara penulisan
sintak serta file header yang digunakan. Untuk contoh program sederhana di atas, jika
ditulis dalam C++ program tersebut adalah sebagai berikut:
#include <iostream.h>
void main()
{
cout <<"Mari belajar pemrograman";
}
19
2.3 Deklarasi Variabel dan Konstanta
Variabel digunakan untuk menyimpan data yang bersifat sementara selama
program berjalan. Dikatakan sementara karena nilai yang disimpan dalam variabel
tersebut dapat berubah selama program dijalankan. Sedangkan konstanta digunakan
untuk menyimpan data yang bersifat tetap, dalam arti data tersebut tidak pernah dan tidak
dapat berubah selama program berjalan.
Sebelum variabel dan konstanta dapat digunakan maka variabel dan konstanta
tersebut harus dideklarasikan terlebih dahulu. Cara mendeklarasikan variabel adalah
dengan menyebutkan tipe data diikuti dengan nama variabel dan diakhiri dengan simbol
titik koma (;). Untuk mendeklarasikan konstanta adalah dengan menyebutkan keyword
const diikuti dengan tipe data kemudian nama konstanta beserta nilainya.
//deklarasi variabel
tipe_data var1, [var2, [var3...]];
//contoh deklarasi
int angka;
float luas, jarijari;
int usia=15;
//deklarasi konstanta
const tipe_data konst1=nilai1, [konst2=nilai2];
//contoh deklarasi
const float phi=3.14;
20
Dalam implementasinya, variabel hanya dikenali dalam blok dimana variabel
tersebut di deklarasikan. Artinya, nama variabel yang sama jika dideklarasikan dan
digunakan pada blok yang berbeda akan dianggap sebagai variabel yang berbeda.
#include <stdio.h>
main()
{
int jarijari=10;
const float phi=3.14285714;
#include <iostream>
using namespace std;
main()
{
int jarijari=10;
const float phi=3.14285714;
21
Sebagai tambahan, beberapa aturan dasar dalam pemrograman dengan C/C++ adalah:
1. C/C++ bersifat case sensitive, artinya penggunaan huruf besar dan huruf kecil
dibedakan, sehingga variabel angka berbeda dengan variabel Angka.
2. Semua keyword C/C++ ditulis dengan huruf kecil.
3. Satu baris perintah dianggap sebagai satu statemen. Setiap statemen diakhiri dengan
tanda titik koma (;).
4. Sepasang tanda kurung kurawal {} digunakan sebagai penanda blok statemen. Setiap
program bahasa C/C++ minimal memiliki satu blok statemen.
22
BAB III
INPUT OUTPUT
Input dan output berguna karena setiap program biasanya akan memerlukan input
agar prosesnya dapat dilaksanakan dan akan memberikan output sebagai hasil proses.
Setiap bahasa pemrograman memiliki perintah khusus untuk melakukan proses input dan
output. Perintah dan cara penulisannya dapat berbeda tergantung bahasa pemrograman
yang digunakan.
//sintaks
printf( "teks_yang_akan_di_cetak");
printf( "format_output", nama_variabel);
//contoh
printf("Hallo, apa kabar?);
printf("%d", angka);
//sintaks
cout << "teks_yang_akan_di_cetak" ;
cout << nama_variabel;
//contoh
cout << "Hallo, apa kabar?;
cout << angka;
23
Cara penulisan perintah scanf untuk input pada C adalah:
//sintaks
scanf( "format_input", &nama_variabel);
//contoh
scanf("%d", &angka);
pada perintah scanf, tanda & di depan nama variabel diperlukan untuk merujuk alamat
memori dari nama variabel yang diberikan.
//sintaks
cin >> nama_variabel;
//contoh
cin >> angka;
Berikut adalah contoh program sederhana untuk mencetak teks "Hello World" dengan
menggunakan C dan C++.
//dengan C
#include <stdio.h>
main()
{
printf( "Hello world");
}
//dengan C++
#include <iostream.h>
main()
{
cout << "Hello World";
}
Untuk penggunaan lebih lanjut, perintah input/output ini memiliki aturan yang
harus diikuti. Sebagai tambahan perintah input/output ini disediakan karakter escape
24
sequence untuk menghasilkan output yang diinginkan. Untuk data numerik juga
diperlukan format khusus sesuai dengan tipe datanya. Escape sequence dalam C dapat
dilihat pada table 11 dan format khusus pada tabel 12.
25
Karakter escape sequence dan format ini khususnya digunakan dalam bahasa C,
sedangkan C++ tidak lagi menggunakan format input/output karena perintah input dan
output dalam C++ sudah menerapkan konsep polimorpisme. Sedangkan escape sequence
masih bisa digunakan dalam C++ meskipun hal ini tidak dianjurkan.
Sebagai contoh untuk penggunaan format dan escape sequence tersebut, misalkan
kita diminta untuk membuat program untuk memasukkan sebuah nilai integer ke dalam
variabel angka, kemudian mencetak nilai yang dimasukkan tersebut. Untuk kasus
sederhana ini, flowchartnya dapat dilihat pada gambar 7.
Start
Input
angka
Cetak
angka
End
//dengan C++
#include <stdio.h>
main()
{
int angka;
printf("Masukkan sebuah angka: ");
scanf("%d", &angka);
26
%d pada perintah scanf menunjukkan bahwa data yang dimasukkan adalah integer,
simbol & di depan variabel angka adalah untuk mengarahkan lokasi memori tempat
nilai yang diinput akan disimpan. \n pada printf menunjukkan perintah ganti baris
sebelum mencetak teks selanjutnya, dan %d pada printf menunjukkan lokasi dimana
isi variabel angka akan dicetak.
//dengan C++
#include <iostream.h>
main()
{
int angka;
cout<<"Masukkan sebuah angka: ";
cin>>angka;
Jika ingin menampilkan output interger yang dimasukkan tersebut dalam format
hexadesimal dan oktal, cukup dengan cara mengganti format output yang tadinya
menggunakan format %d menjadi %x atau %o. Sehingga programnya menjadi:
27
//dengan C
#include <stdio.h>
main()
{
int angka;
printf("Masukkan sebuah angka: ");
scanf("%d", &angka);
Sedangkan untuk melakukan hal yang sama dalam C++ adalah dengan memasukkan
keyword dec untuk desimal, hex untuk hexa dan oct untuk octal. Sehingga programnya
menjadi:
//dengan C++
#include <iostream>
using namespace std;
main()
{
int angka;
cout << "Masukkan sebuah angka: ";
cin >> angka;
28
3.2 Input Output Karakter
Karakter dapat berupa huruf, angka, tanda hubung, simbol khusus atau simbol-
simbol lainnya. Seluruh simbol yang terdapat dalam tabel ASCII dapat dianggap sebagai
karakter, seperti ditunjukkan pada tabel 13 dan 14. ASCII itu sendiri merupakan
singkatan dari American Standard Code for Information Interchange.
Sebuah variabel dengan tipe data karakter dalam C/C++ dapat digunakan untuk
menyimpan satu buah karakter. Untuk menyimpan sebuah nilai karakter ke dalam sebuah
variabel bertipe data karakter adalah dengan menggunakan tanda kutip tunggal untuk
mengapit karakter yang akan disimpan tersebut.
29
char cHuruf;
cHuruf = 'a';
Sebelum sebuah variabel digunakan maka variabel tersebut harus dideklarasikan terlebih
dahulu. Dan jangan lupa, bahwa setiap statemen dalam C/C++ harus diakhiri dengan
simbol titik koma (;), sesuai dengan aturan dasar dalam penulisan program dalam bahasa
C/C++.
Untuk melakukan input dan output karakter dalam C dapat menggunakan fungsi input
standar scanf() dengan menggunakan format %c. Namun dapat juga menggunakan
perintah lain seperti getch() dan getche() yang didefinisikan dalam file header
conio.h. Sedangkan dalam C++ perintah input yang digunakan tetap cin.
30
Contoh program untuk input output karakter dalam C/C++ adalah:
#include <stdio.h>
main()
{
char cKarakter;
#include <iostream>
main()
{
char cKarakter;
31
Karakter dapat dicetak dalam format karakter atau format angka. Dalam bahasa
C, bentuk output ditentukan oleh format yang digunakan. Seperti pada contoh di atas,
jika yang karakter yang dimasukkan adalah huruf 'A' maka jika menggunakan format %c
outputnya adalah A, jika menggunakan format %d outputnya adalah 65, jika
menggunakan format %x outputnya adalah 41 dan jika menggunakan format %o
outputnya adalah 101.
Dalam C++, untuk mencetak karakter dalam format yang berbeda-beda seperti
dalam C masih diperlukan beberapa perintah atau keyword tambahan. Keyword dec,
hex dan oct digunakan untuk mengkonversi bilangan menjadi desimal, hexa dan octal.
Namun keyword ini hanya bisa mengkonversikan bilangan integer. Untuk mengkonversi
karakter menjadi integer dapat menggunakan perintah casting static_cast<int>().
Selain dengan perintah input standar, untuk melakukan input karakter dapat
menggunakan perintah getch() dan getche(). Perbedaan utama kedua perintah ini
dibandingkan dengan scanf() adalah jika pada scanf() data yang dimasukkan baru
akan diterima setelah tombol enter ditekan. Namun pada getch() dan getche() tidak
memerlukan penekanan tombol enter, sehingga jika tombol enter ditekan maka itu juga
dianggap sebagai input.
32
#include <stdio.h>
#include <conio.h>
main()
{
char cKarakter;
33
34
BAB IV
STATEMEN KONDISI
Bahasa C/C++ mengenal dua macam statemen kondisi yaitu if() dan
switch(). if() digunakan untuk memilih satu dari dua alternatif, sedangkan
switch() digunakan untuk memilih satu dari banyak alternatif.
Sedangkan ekspresi yang diperiksa dalam statemen if() tersebut dapat berupa
ekspresi matematis atau pun ekspresi logika. Baik ekspresi matematis atau ekspresi
logika, output yang dihasilkan akan berupa nilai logika true (benar) atau false
(salah).
if( ekspresi_yg_diperiksa )
{
blok_statemen_yang_dikerjakan ;
jika_ekspresi_bernilai_benar;
}
35
Ekspresi matematis atau logika yang diperiksa diletakkan dalam tanda kurung setelah
statemen if(). Jika ekspresi tersebut bernilai benar, maka blok statemen setelah if akan
dikerjakan, namun jika ekspresi tersebut bernilai salah maka blok statemen setelah if
tersebut tidak dikerjakan. Blok statemen yang ditandai dengan sepasang tanda kurung
kurawal hanya diperlukan jika jumlah statemen yang dikerjakan berjumlah lebih dari
satu. Jika jumlah statemennya hanya satu maka pasangan blok kurung kurawal tidak
diperlukan.
Statemen-statemen
sebelumnya
Dikerjakan jika
ekspresi
true ekspresi bernilai
logika
benar
false
Dikerjakan jika
ekspresi bernilai
salah
36
Flowchart untuk menyelesaikan contoh ini dapat dilihat pada gambar 9. Pada
gambar tersebut ditunjukkan adanya pemberian nilai awal sebelum variabel angka
diperiksa dalam statemen kondisi.
Start
angka = 10
End
Penggalan program untuk penggunaan statemen if() pada contoh kasus di atas adalah
sebagai berikut:
//dalam C
angka = 10;
if( angka > 10)
{
printf("Angka lebih besar dari sepuluh") ;
}
//dalam C++
angka = 10;
if( angka > 10)
{
cout << "Angka lebih besar dari sepuluh" ;
}
Karena statemen yang dikerjakan setelah if hanya satu buah, maka program tadi dapat
ditulis dengan menghilangkan pasangan kurung kurawal, sehingga penggalan program di
atas menjadi:
37
//dalam C
angka = 10;
if( angka > 10)
printf("Angka lebih besar dari sepuluh") ;
//dalam C++
angka = 10;
if( angka > 10)
cout << "Angka lebih besar dari sepuluh" ;
Pada contoh di atas, karena nilai yang disimpan dalam variabel angka adalah 10, maka
pernyataan angka > 10 akan bernilai false (salah), sehingga statemen
printf("Angka lebih besar dari sepuluh"); tidak dikerjakan.
Penting untuk diperhatikan, bahwa setelah statemen if() tidak diakhiri dengan tanda
titik koma (;).
Jika ekspresi kondisi yang diperiksa bernilai benar, maka blok statemen setelah if akan
dikerjakan, namun jika ekspresi tersebut bernilai salah maka yang dikerjakan adalah blok
statemen setelah else.
38
Modifikasi dari contoh kasus sebelumnya, if digunakan untuk memeriksa
apakah nilai variabel angka lebih besar dari 10, jika bernilai benar maka cetak teks
"angka lebih besar dari sepuluh", dan jika bernilai salah maka cetak teks
"angka lebih kecil atau sama dg sepuluh".
Start
angka = 10
cetak teks
angka > 10 true jika kondisi
benar
cetak teks
jika kondisi
salah
End
Penggalan program untuk penggunaan statemen if..else.. pada contoh kasus ini
adalah sebagai berikut:
//dalam C
angka = 10;
if( angka > 10)
printf("Angka lebih besar dari sepuluh") ;
else
printf("Angka lebih kecil atau sama dengan sepuluh") ;
//dalam C++
angka = 10;
if( angka > 10)
cout << "Angka lebih besar dari sepuluh" ;
else
cout << "Angka lebih kecil atau sama dengan sepuluh" ;
39
Jika jumlah statemen yang dikerjakan lebih dari satu, maka diperlukan pasangan kurung
kurawal untuk menandai blok statemen. Contoh di atas dapat dimodifikasi sehingga
menjadi:
//dalam C
angka = 10;
if( angka > 10) {
printf("Angka lebih besar dari sepuluh\n") ;
printf("angka = %d", angka);
}
else {
printf("Angka lebih kecil atau sama dengan sepuluh\n") ;
printf("angka = %d", angka);
}
//dalam C++
angka = 10;
if( angka > 10) {
cout << "Angka lebih besar dari sepuluh" << endl ;
cout << "angka = " << angka;
}
else {
cout << "Angka kecil atau sama dengan sepuluh" << endl ;
cout << "angka = " << angka;
}
Ingatlah, bahwa setelah if dan else tidak diakhiri dengan tanda titik koma (;).
40
Sebagai contoh, digunakanlah statemen if untuk memeriksa apakah variabel
angka bernilai 0 (nol), negatif atau positif. Di sini dapat dilihat bahwa terdapat
tiga alternatif yang dapat dipilih, sehingga akan diperlukan dua buah statemen if.
Angka dinyatakan bernilai positif jika nilainya lebih besar dari nol, dan
dinyatakan negatif jika nilainya lebih kecil dari nol dan dinyatakan nol jika nilainya
adalah nol. Dari keterangan ini dapat disusun beberapa alternatif algoritma untuk
penyelesaiannya.
Algoritma 1:
Masukkan sebuah angka
Periksa apakah angka = 0, jika benar cetak teks keterangan untuk nol, jika tidak
maka
Periksa apakah angka > 0, jika benar cetak teks keterangan untuk positif, jika
tidak cetak keterangan untuk negatif.
Algoritma 2:
Masukkan sebuah angka
Periksa apakah angka > 0, jika benar cetak teks keterangan untuk positif, jika
tidak maka
Periksa apakah angka = 0, jika benar cetak teks keterangan untuk nol, jika tidak
cetak keterangan untuk negatif.
Algoritma 3:
Masukkan sebuah angka
Periksa apakah angka > 0, jika benar cetak teks keterangan untuk positif, jika
tidak maka
Periksa apakah angka < 0, jika benar cetak teks keterangan untuk negatif, jika
tidak cetak keterangan untuk nol.
dan seterusnya, karena masih banyak alternatif lain yang dapat disusun untuk
menyelesaikan contoh ini dan memberikan hasil akhir yang sama.
41
Misalkan selanjutnya dibuat flowchart menurut algoritma ke-2 seperti ditunjukkan dalam
gambar 11. Berdasarkan flowchart tersebut kemudian dibuatkan program baik dengan C
maupun C++ sebagai berikut:
//dalam C
#include <stdio.h>
main()
{
int angka;
printf("Masukkan sebuah angka: ");
scanf("%d", &angka);
if(angka > 0)
printf("angka %d adalah positif", angka);
else if(angka==0)
printf("yang dimasukkan adalah NOL");
else
printf("angka %d adalah negatif", angka);
return 0;
}
Start
input
angka
cetak
angka > 0 true
“positif”
cetak
“negatif”
End
42
//dalam C++
#include <iostream>
using namespace std;
main()
{
int angka;
cout <<"Masukkan sebuah angka: ";
cin >> angka;
if(angka > 0)
cout <<"angka " << angka << " adalah positif" ;
else if(angka==0)
cout << "yang dimasukkan adalah NOL";
else
cout << "angka " << angka << " adalah negatif";
return 0;
}
4.4 Nested if
Nested if secara harfiah menyatakan bahwa terdapat statemen if di dalam
statemen if yang lain. Atau dapat juga dikatakan bahwa terdapat statemen if yang di
dalamnya mengandung statemen if lainnya. Nested if ini biasanya digunakan untuk
melakukan pemeriksaan kondisi yang bertingkat-tingkat. Jadi secara sederhana nested
dapat dinyatakan sebagai "statemen yang memiliki statemen yang sama di dalamnya".
Seberapa banyak jumlah nested if ini diizinkan dalam C/C++ sesungguhnya tidak
dibatasi. Hanya saja tidak dianjurkan untuk membuat nested yang terlalu banyak karena
dikhawatirkan akan menyulitkan dalam debuging program.
43
dari algoritma ini kemudian dapat dibuatkan flowchart seperti ditunjukkan pada gambar
12. Dari gambar tersebut terlihat bahwa jika angka yang dimasukkan tidak sama dengan
nol, maka akan diperiksa kondisi berikutnya. Kondisi kedua inilah yang dimaksudkan
dengan nested if. Jadi statemen if yang memeriksa ekspresi angka < 0 adalah
nested terhadap statemen if yang memeriksa ekspresi angka != 0.
Start
input
angka
cetak
angka != 0 true angka > 0 true
“positif”
End
44
//dalam C
#include <stdio.h>
main()
{
int angka;
printf("Masukkan sebuah angka: ");
scanf("%d", &angka);
if(angka != 0)
if(angka < 0)
printf("angka %d adalah negatif", angka);
else
printf("angka %d adalah positif", angka);
else
printf("yang dimasukkan adalah NOL");
return 0;
}
//dalam C++
#include <iostream>
using namespace std;
main()
{
int angka;
cout << "Masukkan sebuah angka: ";
cin >> angka;
if(angka != 0)
if(angka < 0)
cout << "angka " << angka << " adalah negatif";
else
cout << "angka " << angka << " adalah positif";
else
cout << "yang dimasukkan adalah NOL";
return 0;
}
45
memeriksa nilai variabel menurut tipe datanya. Kemudian nilai variabel inilah yang
secara langsung diletakkan pada keyword case untuk mengarahkan berjalannya aliran
program. Dalam bahasa yang lebih sederhana, isi variabel pada keyword switch()
akan dibandingkan dengan nilai yang berada pada case. Jika nilainya cocok, maka blok
perintah pada case yang bersesuaian itulah yang akan dijalankan.
Struktur perintah switch case terdiri dari keyword switch yang digunakan
untuk mengidentifikasi variabel yang akan dievaluasi, sebuah variabel yang berisi nilai
yang akan dievaluasi, sepasang kurung kurawal untuk membatasi blok milik perintah
switch case, sejumlah keyword case yang mengandung nilai pembanding terhadap
isi variabel, keyword break untuk menghentikan perintah yang dijalankan, keyword
default yang berisi perintah jika tidak satupun nilai pada case yang cocok dengan isi
variabel. Dan mengikuti aturan dalam bahasa C/C++, setiap baris perintah diakhiri
dengan tanda titik koma.
switch( namaVariabel )
{
case nilai_1 :
statement1;
...
statement_n;
break;
case nilai _2 :
statement1;
...
statement_n;
break;
...
case nilai _n :
statement1;
...
statement_n;
break;
default :
statement1;
...
statement_n;
break;
}
46
Misalkan kita akan membuat program yang mengimplementasikan perintah
switch case untuk memeriksa apakah angka yang dimasukkan berada antara 0 (nol)
sampai dengan 9 (sembilan). Jika angka yang dimasukkan berada antara 0 sampai 9,
kemudian cetaklah angka tersebut dengan menggunakan kata literalnya, misal yang
dimasukkan angka 3, maka yang dicetak adalah Tiga. Namun jika angka yang
dimasukkan tidak berada antara 0 sampai dengan 9 maka cetaklah kalimat yang
menyatakan bahwa angkat yang dimasukkan tersebut tidak berada di antara 0 sampai 9.
//dengan bahasa C
#include <stdio.h>
int main()
{
int angka;
printf("Masukkan angka antara 0-9: ");
scanf("%d", &angka);
switch(angka) {
case 0 : printf("\nAngka yang dimasukkan adalah Nol");
break;
47
//dengan bahasa C++
#include <iostream>
using namespace std;
int main()
{
int angka;
cout << "Masukkan angka antara 0-9: ";
cin >> angka;
switch(angka) {
case 0 : cout << endl <<"Angka yang dimasukkan adalah Nol";
break;
}
return 0;
}
48
Output program jika yang dimasukkan adalah angka 7:
Keyword break digunakan untuk membatasi perintah yang dijalankan dalam blok
switch case. Jika keyword break pada satu case dihilangkan maka perintah-
perintah pada case yang lain tetap akan dilaksanakan sampai ditemukan keyword
break berikutnya.
49
//dengan bahasa C++
#include <iostream>
using namespace std;
int main()
{
int angka;
cout << "Masukkan angka antara 0-9: ";
cin >> angka;
switch(angka) {
case 0 : cout << endl <<"Angka yang dimasukkan adalah Nol";
case 1 : cout << endl <<"Angka yang dimasukkan adalah Satu";
case 2 : cout << endl <<"Angka yang dimasukkan adalah Dua";
case 3 : cout << endl <<"Angka yang dimasukkan adalah Tiga";
case 4 : cout << endl <<"Angka yang dimasukkan adalah Empat";
case 5 : cout << endl <<"Angka yang dimasukkan adalah Lima";
break;
}
return 0;
}
Output dari program ini jika angka yang dimasukkan angka 3 adalah:
50
BAB V
PERULANGAN
5.1 Perulangan
Perulangan atau iterasi yang dalam pemrograman sering juga disebut dengan loop
atau looping merupakan suatu mekanisme dalam pemrograman untuk mengulangi
pengerjaan satu atau seklompok perintah program sebanyak jumlah tertentu atau selama
kondisi tertentu masih terpenuhi. Dalam bahasa C/C++ terdapat tiga perintah yang dapat
digunakan untuk melakukan perulangan yaitu while(), do while() dan for().
Masing-masing perintah memiliki karakteristik dan aturan-aturan tertentu dalam
penggunaannya.
Pada while loop, ekspresi kondisi akan diperiksa terlebih dahulu, jika kondisi
bernilai benar maka blok statemen akan dikerjakan namun jika kondisi bernilai salah
maka blok statemen tidak dikerjakan. Artinya, dengan while loop, blok statemen akan
dikerjakan berulang-ulang selama kondisi yang diberikan bernilai benar atau dapat juga
tidak dikerjakan sama sekali jika kondisi yang diberikan tidak pernah bernilai benar.
Pada do while loop, blok statemen akan dikerjakan terlebih dahulu kemudian baru
ekspresi kondisinya diperiksa. Jika bernilai benar maka blok statemen akan dikerjakan
kembali. Artinya, dengan menggunakan do while loop, blok statemen minimal akan
dikerjakan sebanyak satu kali.
51
5.2 While Loop
while loop bekerja dengan cara memeriksa apakah kondisi yang diberikan
bernilai benar, jika benar maka statemen yang ada pada tubuh loop akan dikerjakan.
Namun jika kondisinya bernilai salah maka aliran program akan dilanjutkan dengan
perintah berikutnya yang berada setelah statemen while. Sintak penulisan statemen
while dalam C/C++ adalah:
while( kondisi )
statement_yang_dikerjakan;
atau, jika yang statemen yang dikerjakan berjumlah lebih dari satu, maka sintaknya
adalah:
while( kondisi )
{
blok_statemen_yang_dikerjakan ;
secara_berulang;
}
Perhatikan ilustrasi pada gambar 13-a untuk looping dengan statemen tunggal
dan 13-b looping dengan multi statemen:
ekspresi kondisi
(a)
52
ekspresi kondisi
(b)
Dalam ilustrasi pada gambar 13, bagian ekspresi relasional atau logika diisi dengan ch
!= 'Y' yang akan menghasilkan nilai benar atau salah sesuai dengan nilai yang terdapat
dalam variabel ch. Jika kondisinya bernilai benar maka selanjutnya adalah mengerjakan
statemen dalam loop. Statemen ini akan terus dikerjakan berulang-ulang selama ekspresi
ch != 'Y' masih bernilai benar.
53
statemen-statemen
sebelumnya
statemen selanjutnya
ekspresi jika ekspresi bernilai
false
logika while salah
true
bagian statemen
yang diulang
(isi tubuh while)
(a)
statemen-statemen
sebelumnya
statemen selanjutnya
ekspresi jika ekspresi bernilai
false
logika while salah
true
bagian statemen
yang diulang
(isi tubuh while)
(b)
54
Isi tubuh while() dapat berupa statemen tunggal dan dapat pula terdiri dari
banyak statemen. Sebagai contoh, while() digunakan untuk memeriksa apakah
karakter yang diinput dari keyboard tidak sama dengan huruf 'Y'. Jika tidak sama, maka
masukkan karakter lainnya sampai dimasukkan huruf 'Y'. Flowchart untuk
menyelesaikan masalah ini ditunjukkan dalam gambar 15.
Start
ch = ‘\0’
ch != ‘Y’
true End
Input
karakter
Dari flowchart pada gambar 15 terlihat bahwa pertama kali variabel ch diberikan nilai
awal dengan null. Selanjutnya diperiksa apakah ch tidak sama dengan huruf 'Y', jika
tidak sama maka masukkan sebuah karakter dan simpan karakter tersebut ke dalam
variabel ch. Jika ch sama dengan huruf 'Y' maka aliran prorgam dihentikan. Contoh
program yang paling sederhana untuk flowchart pada gambar 15 adalah:
//dalam C
#include <stdio.h>
main()
{
char ch='\0';
while(ch != 'Y')
scanf("%c", &ch);
return 0;
}
55
//dalam C++
#include <iostream>
using namespace std;
main()
{
char ch='\0';
while(ch != 'Y')
cin >> ch;
return 0;
}
Kedua program ini jika dijalankan akan menampilkan halaman kosong tanpa informasi
apapun, dan akan berhenti setelah huruf 'Y' dimasukkan. Oleh karena itu sebaiknya
dilakukan sedikit modifikasi untuk memberikan informasi agar tujuan program ini
menjadi lebih jelas. Informasi ini dapat diberikan dengan menggunakan fungsi
printf() sehingga programnya menjadi:
//dalam C
#include <stdio.h>
main()
{
char ch='\0';
while(ch != 'Y')
cin >> ch;
return 0;
}
56
//dalam C++
#include <iostream>
using namespace std;
main()
{
char ch='\0';
while(ch != 'Y')
cin >> ch;
return 0;
}
Perhatikan, bahwa setiap kali menginput karakter diakhiri dengan menekan tombol
Enter
Simulasi perubahan nilai variabel ch serta nilai kondisi while ditunjukkan pada tabel 15.
57
5.3 do while Loop
do while loop bekerja dengan cara kebalikan dari while loop. Pada do
while loop, tubuh loop akan dikerjakan terlebih dahulu baru statemen kondisinya
diperiksa. Jika kondisi yang diberikan bernilai benar, maka statemen yang ada pada
tubuh loop akan dikerjakan kembali. Namun jika kondisinya bernilai salah maka aliran
program akan dilanjutkan dengan perintah berikutnya yang berada setelah statemen do
while. Sintak penulisan statemen while dalam C/C++ adalah:
do
statement_yang_dikerjakan;
while( kondisi );
atau, jika yang statemen yang dikerjakan berjumlah lebih dari satu, maka sintaknya
adalah:
do
{
blok_statemen_yang_dikerjakan ;
secara_berulang;
} while( kondisi );
Perhatikan ilustrasi pada gambar 16 untuk looping dengan statemen tunggal dan
looping dengan multi statemen:
do
loop dg statemen tunggal
statement;
while ( ch != 'Y' ) ;
ditutup dg tanda titik koma
ekspresi kondisi
58
tidak ada tanda titik koma
do
{
loop dg multi statemen
statement1;
statement2;
statement3;
ditutup dg tanda titik koma
} while ( ch != 'Y' ) ;
ekspresi kondisi
Dari ilustrasi pada gambar 16 terlihat bahwa statemen yang merupakan tubuh loop
dikerjakan terlebih dahulu baru kemudian memeriksa ekspresi logika atau ekspresi
relasional yang diberikan. Bagian ekspresi relasional atau logika diisi dengan ch !=
'Y' yang akan menghasilkan nilai benar atau salah sesuai dengan nilai yang terdapat
dalam variabel ch. Jika kondisinya bernilai benar maka statemen-statemen yang
terdapat pada tubuh loop akan diulangi pengerjaannya, tubuh loop ini akan terus
dikerjakan berulang-ulang selama ekspresi ch != 'Y' masih bernilai benar.
59
statemen-statemen
sebelumnya
ekspresi
logika do
while
false
statemen selanjutnya
jika ekspresi bernilai
salah
Isi tubuh do while() dapat berupa statemen tunggal dan dapat pula terdiri dari
banyak statemen. Sebagai contoh, do while() digunakan untuk memeriksa apakah
karakter yang diinput dari keyboard tidak sama dengan huruf 'Y'. Jika tidak sama, maka
masukkan karakter lainnya sampai dimasukkan huruf 'Y'. Flowchart untuk
menyelesaikan masalah ini ditunjukkan dalam gambar 18.
60
Start
ch = ‘\0’
Input
karakter
ch != ‘Y’
false
End
Dari flowchart pada gambar 18 terlihat bahwa pertama kali variabel ch diberikan nilai
awal dengan null. Selanjutnya memasukkan sebuah karakter dan simpan karakter
tersebut ke dalam variabel ch. Setelah itu periksa apakah ch tidak sama dengan huruf
'Y', jika tidak sama maka masukkan kembali sebuah karakter dan simpan karakter
tersebut ke dalam variabel ch. Jika ch sama dengan huruf 'Y' maka aliran prorgam
dihentikan.
//dalam C
#include <stdio.h>
main()
{
char ch='\0';
do
scanf("%c", &ch);
while(ch != 'Y');
return 0;
}
61
//dalam C++
#include <iostream>
using namespace std;
main()
{
char ch='\0';
do
cin >> ch;
while(ch != 'Y');
return 0;
}
Kedua program ini jika dijalankan akan menampilkan halaman kosong tanpa informasi
apapun, dan akan berhenti setelah huruf 'Y' dimasukkan. Oleh karena itu sebaiknya
dilakukan sedikit modifikasi untuk memberikan informasi agar tujuan program ini
menjadi lebih jelas. Informasi ini dapat diberikan dengan menggunakan fungsi
printf() sehingga programnya menjadi:
//dalam C
#include <stdio.h>
main()
{
char ch='\0';
do
scanf("%c", &ch);
while(ch != 'Y');
return 0;
}
62
//dalam C++
#include <iostream>
using namespace std;
main()
{
char ch='\0';
return 0;
}
Perhatikan, bahwa setiap kali menginput karakter diakhiri dengan menekan tombol
Enter
63
Pada do while()loop, statemen pada tubuh loop akan dikerjakan terlebih
dahulu baru ekspresi kondisinya diperiksa. Artinya minimal tubuh loop dikerjakan
sebanyak satu kali, dan akan diulangi jika ekspresi kondisinya menghasilkan nilai benar.
Hal ini berbeda dengan while()loop dimana ekspresi kondisi diperiksa terlebih
dahulu, yang berarti tubuh loop dapat tidak pernah dikerjakan sama sekali jika ekspresi
kondisi tidak pernah menghasilkan nilai benar.
atau, jika yang statemen yang dikerjakan berjumlah lebih dari satu, maka sintaknya
adalah:
Statemen for() memiliki tiga bagian di dalamnya yaitu inisialisasi, kondisi dan
incement/decrement. Inisialisasi merupakan pemberian nilai awal pada variabel yang
digunakan sebagai indeks. Kondisi merupakan ekspresi relasional yang digunakan untuk
menentukan kapan perulangan berhenti, kondisi ini biasanya memeriksa nilai dari
variable indeks. Counter digunakan untuk mengontrol perubahan nilai pada variabel
yang digunakan sebagai indeks. Setiap bagian ini dipisahkan dengan tanda titik koma.
64
Perulangan akan terus dilakukan sampai variabel indeks memiliki nilai tertentu.
Ketika indeks sudah mencapai nilai seperti yang dikondisikan maka perulangan akan
dihentikan, dan dilanjutkan dengan pengerjaan statemen berikutnya yang terletak setelah
statemen for().
Perhatikan ilustrasi pada gambar 19 untuk looping dengan statemen tunggal dan
looping dengan multi statemen:
inisialisasi
ekspresi kondisi
counter
inisialisasi
ekspresi kondisi
counter
Dalam ilustrasi gambar 19, bagian inisialisasi diisi dengan j=0 yang berarti variabel j
diberi nilai nol sebagai nilai awal. Bagian ekspresi kondisi atau ekspresi relasional diisi
dengan j<10 yang akan menghasilkan nilai benar atau salah sesuai dengan nilai yang
terdapat dalam variabel j dan bagian counter diisi dengan j++ yang berarti setelah
65
statemen dalam loop dikerjakan, nilai variabel j diubah dengan cara menaikkan nilainya
dengan satu. Statemen dalam loop akan terus dikerjakan berulang-ulang selama nilai j
masih lebih kecil dari 10.
Ada beberapa cara penggambaran flowchart untuk for loop. Selama pada
flowchart tersebut menunjukkan tiga bagian (inisialisasi, ekspresi kondisi dan counter)
dari for loop secara spesifik maka cara tersebut dapat digunakan. Sebagian orang
menggunakan simbol kondisi seperti yang digunakan pada while dan do while,
sementara sebagian lainnya menggunakan simbol preparsi. Cara penggambaran
flowchart untuk for loop dapat dilihat pada gambar 12.a dan 12.b.
statemen-statemen statemen-statemen
sebelumnya sebelumnya
inisialisasi j=0
ekspresi
j<10
kondisi for()
true true
false false
counter j++
(a)
66
statemen-statemen statemen-statemen
sebelumnya sebelumnya
idx j
Pada gambar 20.b flowchart untuk for loop digambarkan dengan menggunakan
simbol preparasi. Pada simbol preparasi ini diisi dengan inisialisasi, ekspresi kondisi dan
counter dimana setiap bagian dipisahkan dengan simbol titik koma dalam hal ini diisi
67
dengan j=0; j<10; j++. Di bawahnya diletakkan simbol-simbol yang menunjukkan
proses yang akan dikerjakan secara berulang dan diakhiri dengan simbol konektor
(lingkaran) sebagai penanda akhir tubuh loop yang di dalamnya diisi dengan variabel j
yang digunakan sebagai variabel indeks. Di dalam buku ini, flowchart untuk for()
loop akan menggunakan cara seperti pada gambar 20.b.
Sebagai contoh kasus, misalkan kita diminta untuk membuat program sederhana
untuk mencetak angka 1 sampai 10 dengan perulangan menggunakan for() loop.
Flowchartnya dapat digambarkan seperti pada gambar 21.
Start
cetak j+1
End
Pada simbol preparasi diisi dengan j=0; j<10; j++, yang berarti j diberi
nilai awal nol kemudian kondisi yang diperiksa adalah apakah nilai j masih lebih kecil
dari 10 dan counter dilakukan dengan menambahkan nilai j dengan satu. Pada simbol
68
output, yang dicetak adalah j+1 agar output yang dihasilkan adalah urutan angka 1,
2, 3, ..., 10. Jika yang dicetak hanya j saja maka output yang dihasilkan adalah
urutan angka 0, 1, 2, ..., 9.
//dalam C
#include <stdio.h>
main()
{
int j;
return 0;
}
//dalam C++
#include <iostream>
using namespace std;
main()
{
int j;
return 0;
}
69
Pada contoh di atas, tubuh for() loop tidak menggunakan pasangan kurung kurawal
karena tubuh loop hanya berisi satu statemen. Namun jika jumlah statemennya lebih dari
satu maka pasangan kurung kurawal harus disertakan.
Pasangan loop pada nested loop dapat terdiri dari loop for() dengan for(),
for() dengan while(), for() dengan do while(), while() dengan for()
dan seterusnya. Kombinasi dan jumlah loop yang digunakan dalam nested loop
disesuaikan dengan kebutuhan dalam pembuatan program.
Dalam bentuk flowchart, beberapa struktur nested loop seperti pasangan loop
for() dengan for()ditunjukkan pada gambar 22, for() dengan
while()ditunjukkan pada gambar 23 dan for() dengan do while() ditunjukkan
pada gambar 24.
70
Pada gambar 22 terlihat bahwa terdapat dua buah loop for() yaitu loop i dan
loop j. Loop j berada di dalam loop i, sehingga dapat dikatakan loop j adalah nested
loop dari loop i. Loop i melakukan perulangan sebanyak 10 kali dan loop j
melakukkan perulangan sebanyak 10 kali di dalam loop i. Dengan kondisi ini berarti isi
tubuh loop kedua dilakukan sebanyak 100 kali, yaitu 10 kali perulangan loop j dikalikan
10 kali perulangan loop i. Sedangkan isi tubuh loop pertama hanya diulang sebanyak 10
kali, yaitu sebanyak perulangan loop i.
statemen-statemen statemen-statemen
sebelumnya sebelumnya
idx2 j
idx1 i
Statemen-statemen Statemen-statemen
selanjutnya selanjutnya
71
Gambar 23 memperlihatkan nested loop dengan kombinasi loop for() dan loop
while(). Loop for diisi dengan j=0; j<10; j++ yang berarti loop j akan
melakukan perulangan sebanyak 10 kali. Dengan demikian isi tubuh loop pertama juga
akan dilakukan perulangan sebanyak 10 kali. Kemudian loop while() diberi kondisi
ch != 'Y', yang berarti isi tubuh loop kedua hanya dikerjakan selama variabel ch
tidak sama dengan huruf Y besar. Namun jumlah perulangan yang dilakukan atas isi
tubuh loop kedua tidak dapat ditentukan terlebih dahulu, bisa sekali, bisa lebih dari sekali
atau bisa tidak sama sekali. Secara keseluruhan jumlah perulangan untuk isi tubuh loop
kedua adalah banyaknya perulangan loop while() dalam 10 kali perulangan loop j
sebagai loop pertama.
statemen-statemen statemen-statemen
sebelumnya sebelumnya
ekspresi
ch != ‘Y’
logika while
false false
true true
idx1 j
Statemen-statemen Statemen-statemen
selanjutnya selanjutnya
72
Gambar 24 memperlihatkan nested loop dengan kombinasi loop for() dan loop
do while(). Loop for diisi dengan j=0; j<10; j++ yang berarti loop j akan
melakukan perulangan sebanyak 10 kali. Dengan demikian isi tubuh loop pertama juga
akan dilakukan perulangan sebanyak 10 kali. Kemudian loop do while() diberi
kondisi ch != 'Y', yang berarti isi tubuh loop kedua hanya dikerjakan selama variabel
ch tidak sama nilainya dengan huruf Y besar. Namun jumlah perulangan yang dilakukan
atas isi tubuh loop kedua tidak dapat ditentukan terlebih dahulu, minimal dilakukan
sekali namun dapat juga dilakukan lebih dari sekali. Secara keseluruhan jumlah
perulangan untuk isi tubuh loop kedua adalah banyaknya perulangan loop do while()
dalam 10 kali perulangan loop j sebagai loop pertama.
statemen-statemen statemen-statemen
sebelumnya sebelumnya
false false
idx1 j
Statemen-statemen Statemen-statemen
selanjutnya selanjutnya
73
Contoh kasus:
Buatlah program dengan menggunakan nested loop untuk menghasilkan tampilan berikut
ini:
0
0 1
0 1 2
0 1 2 3
0 1 2 3 4
...
...
...
0 1 2 3 4 5...n-1
Jumlah baris dan kolom yang dicetak adalah sebanyak n, dimana nilai n merupakan
bilangan integer positif yang dimasukkan dari keyboard.
1. Deklarasikan variabel i, j, n
2. Masukkan jumlah baris ke dalam variabel n
3. Buat perulangan i sebanyak n kali
4. di dalam loop i, buat perulangan j sebanyak i kali
5. Di dalam loop j, cetak nilai j
6. Cetak ganti baris setelah loop j selesai
7. Selesai
74
Algoritma alternatif 2, kombinasi while() dan for()
75
Start Start Start
Input n
i=0; i<n; i++ i=0; i<n; i++
j=0 false
true false
j
Cetak j Cetak j
Ganti
j++
baris j++
i true
Ganti
j <= i
baris
Start
i
Ganti
baris
(a)
Start
i++
(b)
Start
(c)
76
Berikut adalah contoh program dalam bahasa C/C++ yang dibuat berdasarkan flowchart
pada gambar 25.
#include <stdio.h>
main()
{
int i, j, n;
printf("\n");
}
}
//Dalam C++
#include <iostream>
using namespace std;
main()
{
int i, j, n;
77
//Nested loop for() dan while()
//Dalam C
#include <stdio.h>
main()
{
int i, j, n;
printf("\n");
}
}
//Dalam C++
#include <iostream>
using namespace std;
main()
{
int i, j, n;
78
//Nested loop while() dan do while()
//Dalam C
#include <stdio.h>
main()
{
int i=0, j, n;
while(i<n)
{
j=0;
do {
printf("%d ", j);
j++;
}while(j<=i);
printf("\n");
i++;
}
}
//Dalam C++
#include <iostream>
using namespace std;
main()
{
int i=0, j, n;
while(i<n)
{
j=0;
do {
cout << j << " ";
j++;
} while(j<=i);
79
Jika program-program tersebut dijalankan, kemudian dimasukkan angka 7 sebagai
jumlah baris, maka tampilan output dari program adalah:
80
BAB VI
ARRAY
Array atau sering juga disebut dengan larik merupakan sekumpulan variabel yang
memiliki tipe data yang sama dan diidentifikasi dengan menggunakan satu nama saja.
Atau, dalam kalimat yang lain, satu nama variabel atau pengenal yang digunakan untuk
sekumpulan data yang memiliki tipe data yang sama. Artinya jika salah satu anggota
array memiliki tipe data integer maka anggota array lainnya juga bertipe integer, jika
salah satu anggota array memiliki tipe data karakter maka anggota array lainnya juga
karakter.
Seperti halnya sebuah variabel, array akan menempati suatu lokasi memori
tertentu di dalam komputer. Areal memori ini biasanya saling berhubungan dan
berurutan. Anggota dari sebuah array disebut sebgai elemen array. Elemen tertentu
dalam array dapat diakses dengan melalui indeks milik array tersebut. Setiap elemen
dalam array akan memiliki nomor indeks yang berbeda. Nomor indeks berbentuk urutan
bilangan integer yang dimulai dari angka nol. Ilustrasi untuk array yang memiliki enam
elemen ditunjukkan dalam gambar 26.
nomor indeks
alamat memory
x[0] 7 2293936
x[1] -23 2293490
x[2] 123 2293404
x[3] 0 2293400
x[4] 2345 2293412
x[5] -542 2293416
81
Dari ilustrasi pada gambar 26 terlihat bahwa untuk array yang berisi 6 elemen,
indeksnya adalah 0, 1, 2, 3, 4 dan 5 seluruhnya berjumlah 6. Jika kemudian array diakses
dengan menggukanan angka 6 sebagai indeks maka akan memunculkan kesalahan
pemrograman. Namun kesalahan program ini tidak terjadi ketika kompilasi program
dilakukan tetapi terjadi ketika program dijalankan.
Bentuk array dapat dibedakan menurut ukuran atau dimensinya, mulai dari
dimesi satu sampai beberapa dimensi sesuai dengan kebutuhan dalam pemrograman.
Secara visual, array sering digambarkan dalam bentuk tabel. Array satu dimensi
digambarkan sebagai tabel satu kolom dengan banyak baris, array dua dimensi
digambarkan sebagai tabel dengan banyak kolom dan banyak baris, array 3 dimensi
digambarkan sebagai tabel dengan banyak kolom dan baris yang berlapis-lapis dan
seterusnya.
Tidak ada aturan khusus kapan array satu dimensi, dua dimensi dan seterusnya
mesti digunakan dalam sebuah program. Penggunaan ini biasanya disesuaikan dengan
kebutuhan program yang dibuat.
82
6.1 Array Satu Dimensi
Terkadang ada keadaan dimana kita perlu menggunakan array dalam suatu
program. Dengan memanfaatkan array, program yang dihasilkan akan menjadi lebih
sederhana dan lebih mudah untuk dipahami. Sebagai contoh misalkan kita diminta untuk
membuat program untuk membuat :
Berasumsi jika dalam satu kelas terdiri dari 20 orang siswa yang akan dicatat
tinggi badannya. Artinya dalam program akan diperlukan 20 variabel yang masing-
masing akan menyimpan data untuk satu orang siswa. Misalkan tinggi badan dicatat
dalam satuan cm dan selalu beruba bilangan bulat, maka variabel yang digunakan dapat
dideklarasikan sebagai berikut:
dapat dibayangkan kesulitan yang akan muncul jika jumlah data siswa yang akan dicatat
diubah misalnyanya menjadi 100 orang. Namun hal ini bisa dengan mudah diatasi
dengan menggunakan array. Array untuk mencatat data 20 orang siswa dapat
dideklarasikan sebagai:
int tgSiswa[20];
83
Seperti halnya sebuah variabel, sebelum dapat digunakan, array terlebih dahulu
harus dideklarasikan dengan cara yang sama dengan pendeklarasian variabel. Penamaan
sebuah array memiliki aturan yang sama dengan penamaan variabel. Aturan
pendeklarasian array satu dimensi adalah sebagai berikut:
tipe_data nama_array[jumlah_elemen];
jadi, array dideklarasikan dalam tipe data dimana tipe data ini adalah salah satu tipe data
yang dikenal dalam C/C++. Kemudian nama array yang cara penamaannya sama dengan
penamaan variabel dan jumlah elemen dari array yang ditulis diantara tanda kurung siku
( [...] ). Jumlah elemen array ini adalah bilangan bulat positif.
Dalam C/C++, isi memory tidak dibersihkan dari penggunaan sebelumnya ketika
variabel atau array baru dideklarasikan/diciptakan. Oleh karena itu, dalam prakteknya
sebaiknya melakukan inisialisasi untuk semua variabel yang digunakan termasuk array.
Ada dua cara untuk melakukan inisialisasi pada array. Pertama adalah ketika
melakukan deklarasi dan yang kedua setelah deklarasi array. Pada cara pertama yaitu
dengan memberikan suatu nilai tertentu yang dipisahkan dengan tanda koma untuk setiap
elemen array. Deretan nilai ini diletakkan dalam kurung kurawal.
setiap nilai dalam tanda kurung kurawal yang berada di sebelah kanan tanda sama
dengan akan menjadi nilai awal untuk elemen array yang bersesuaian. Artinya
tgSiswa[0] akan disi dengan 0, tgSiswa[1] akan disi dengan 1, tgSiswa[2] akan
disi dengan 2, tgSiswa[3] akan disi dengan 3 dan tgSiswa[4] akan disi dengan 4.
84
Cara deklarasi array lainnya untuk memberikan nilai awal adalah dengan
memberikan nilai default yang sama untuk semua elemen array. Misalkan untuk contoh
sebelumnya, seluruh elemen pada tgSiswa diberi nilai awal 0, maka deklarasinya dapat
ditulis sebagai:
cara deklarasi kedua ini dapat dengan lebih cepat dilakukan karena berapapun jumlah
elemen dari array, cukup diberikan satu nilai tunggal dalam kurung kurawal disebelah
tanda sama dengan. Maka seluruh elemen array akan memiliki nilai awal yang diberikan
tersebut.
Cara pemberian nilai awal yang lainnya adalah dengan menggunakan looping,
misalnya for() loop. Perhatikan program berikut:
#include <stdio.h>
main()
{
int i, tgSiswa[5];
Pada program ini terlihat variabel yang dideklarasikan adalah i yang digunakan sebagai
indeks dan array tgSiswa yang memiliki 5 elemen. Loop i yang berfungsi sebagai
indeks array memiliki nilai berturut-turut 0, 1, 2, 3 dan 4 yang seluruhnya berjumlah 5,
sesuai dengan jumlah elemen array. Kemudian setiap array diisi dengan nilai 0.
Selanjutnya, untuk mencetak seluruh isi dari array juga diperlukan sebuah
looping lainnya. Berikut adalah modifikasi dari program sebelumnya untuk melakukan
pemberian nilai dan pencetakan isi semua elemen array.
85
//dalam C
#include <stdio.h>
main()
{
int i, tgSiswa[5];
//dalam C++
#include <iostream>
using namespace std;
main()
{
int i, tgSiswa[5];
Berbeda dengan program sebelumnya dimana seluruh elemen array diisi dengan nilai 0,
pada program ini elemen array diisi dengan nilai indeks dikalikan dengan 2 yang
ditunjukkan dengan perintah tgSiswa[i] = i*2; sehingga output dari program ini
jika dijalankan adalah:
86
Bagaimana jika inisialisasi atau pemberian nilai awal tidak dilakukan terhadap
array? Seperti sudah disampaikan sebelumnya bahwa dalam C/C++, isi memory tidak
dibersihkan dari penggunaan sebelumnya, artinya mungkin sekali area memory yang
digunakan untuk variabel atau array sudah berisi nilai tertentu. Perhatikan program
berikut, dimana setelah dideklarasikan tanpa inisialisasi nilai awal, langsung dilakukan
pencetakan untuk semua elemen array.
//dalam C
#include <stdio.h>
main()
{
int i, tgSiswa[10];
//dalam C++
#include <iostream>
using namespace std;
main()
{
int i, tgSiswa[10];
87
output dari program ini adalah
disini tampak bahwa setiap elemen array sudah berisi nilai tertentu meskipun tidak
dilakukan pemberian nilai awal. Karena alasan inilah maka inisialisasi sebaiknya
dilakukan sebelum array digunakan yang bertujuan untuk menghindari terjadinya
kesalahan.
Perhatikan, Kesalahan yang umum terjadi dalam penggunaan arrau adalah karena tidak
memperhitungkan indeks ke-0. Kesalahan pemrograman ini sering disebut sebagai off-
by-one error, yang terjadi karena program mengakses data diluar batasan yang
disediakan. Misalkan kita memiliki array dengan 5 elemen, kemudian statemen
mengakses array tersebut dengan angka indeks 5, maka saat itulah kesalahan program
terjadi. Hal ini terjadi karena indeks terakhir untuk array dengan 5 elemen adalah 4.
Off-by-one error biasaynya terjadi ketika program dijalankan dan tidak ditemui pada saat
kompilasi program. Hal ini terjadi karena off-by-one error merupakan kesalahan pada
logika program, bukan kesalahan dalam penulisan sintak.
Contoh kasus:
Buatlah sebuah program untuk mencatat rata-rata suhu harian selama dua minggu,
kemudian hitunglah suhu terendah dan tertinggi serta rata-rata suhu dua mingguannya.
Data suhu dicatat dalam bilangan pecahan dan dimasuk dimasukkan melalui keybaord.
88
Bentuk output yang ditampilkan adalah:
1. Data suhu selama 2 minggu
2. Suhu minimum dan maksimum
3. Suhu rata-rata selama 2 minggu
Algoritma:
1. Definisikan variabel yang diperlukan untuk data suhu, suhu minimum, suhu
maksimum, serta variabel pendukung lainnya
2. Masukkan data suhu harian selama 2 minggu
3. Periksa suhu terendah dan tertinggi
4. Jumlahkan seluruh suhu harian
5. Hitung suhu rata-rata dua mingguan
6. Cetak suhu minimal, maksimal dan rata-rata
7. Selesai
Flowchart untuk penyelesaian contoh kasus ini ditunjukkan pada gambar 28. Data
suhu harian disimpan dalam array suhu[] dan diinput dengan menggunakan looping
for() yang menggunakan variabel j sebagai indeks. Setelah semua data dimasukkan,
beri nilai awal untuk variabel suhuMin dan suhuMax dengan data pertama yang
dimasukkan tadi yaitu suhu[1] serta variabel jumlah diberi nilai awal 0.
89
Start A
Input
suhuMin >
suhu[ j ] true suhuMin = suhu[ j ]
suhu[ j ]
suhuMax <
suhuMin = suhu[ 1 ] true suhuMax = suhu[ j ]
suhu[ j ]
suhuMax = suhu[ 1 ]
jumlah += suhu[ j ]
jumlah = 0
j
A B B C
Cetak
xRata = jumlah/14
suhuMin
Cetak
suhu[ j ]
Cetak
xRata
j
C End
Gambar 28. Flowchart perhitungan min, max dan rata-rata suhu dua mingguan
90
Program dalam bahasa C/C++ yang dibuat berdasarkan flowchart pada gambar 28
adalah:
//dalam C
#include <stdio.h>
main()
{
float suhu[14]={0};
float suhuMin, suhuMax, jumlah, xRata;
int j;
suhuMin = suhu[1];
suhuMax = suhu[1];
jumlah = 0.0;
//pencetakan
printf("\n\nData suhu yang dimasukkan adalah:\n");
for(j=0; j<14; j++)
printf("%4.2f\t", suhu[j]);
91
//dalam C++
#include <iostream>
using namespace std;
main()
{
float suhu[14]={0};
float suhuMin, suhuMax, jumlah, xRata;
int j;
suhuMin = suhu[1];
suhuMax = suhu[1];
jumlah = 0.0;
//pencetakan
cout<<"\n\nData suhu yang dimasukkan adalah:\n";
for(j=0; j<14; j++)
cout << suhu[j] << "\t";
92
Jika program ini dijalankan, kemudian data yang dimasukkan berturut-turut: 23, 24.5,
20.75, 29, 30, 31, 31.5, 24.75, 26, 22, 34, 21.25, 25 dan 27, maka output dari program
tersebut adalah:
tipe_data nama_array[jumlah_baris][jumlah_kolom];
sehingga
int aDua[3][3];
berarti mendeklarasikan array bertipe integer dengan nama aDua yang memiliki 9
elemen yang terdiri dari 3 baris dan 3 kolom. Gambar 29 menunjukkan ilustrasi untuk
array aDua yang memiliki 9 elemen tersebut.
93
kolom 0 kolom 1 kolom 2
Pada gambar 29 terlihat bahwa array memiliki 3 baris yaitu baris ke-0, ke-1 dan
ke-2 serta 3 kolom yaitu kolom ke-0, ke-1 dan ke-2. Untuk mengakses elemen array
adalah dengan menyebutkan nama array beserta indek kolom dan barisnya. Sehingga
aDua[0][0] berarti elemen pada baris ke-0 kolom ke-0, aDua[0][1] berarti elemen
pada baris ke-0 kolom ke-1, aDua[1][0] berarti elemen pada baris ke-1 kolom ke-0
dan seterurnya hingga aDua[2][2] yang berarti elemen pada baris ke-2 kolom ke-2
yang merupakan elemen terakhir dari array aDua.
Seperti halnya dengan array satu dimensi, pada array dua dimensi juga perlu
dilakukan inisialisasi atau pemberian nilai awal sebelum array tersebut digunakan. Untuk
melakukan inisialisasi dapat dilakukan secara langsung ketika array dideklarasikan atau
dengan menggunakan looping. Dalam hal penggunaan mekanisme looping, diperlukan
dua buah loop yang masing-masing bertindak sebagai indeks baris dan sebagai indeks
kolom pada array.
Setiap kelompok nilai dalam kurung kurawal merupakan nilai awal untuk setiap baris
dalam array. Dalam hal ini aDua[0][0] diberi nilai 0, aDua[0][1] diberi nilai 1 dan
aDua[0][2] diberi nilai 2. Secara lengkap nilai awal untuk setiap elemen array aDua
dapat dilihat pada tabel 18.
94
Tabel 18. Nilai setiap elemen array setelah inisialisasi
Elemen Nilai
aDua[0][0] 0
aDua[0][1] 1
aDua[0][2] 2
aDua[1][0] 0
aDua[1][1] 1
aDua[1][2] 2
aDua[2][0] 0
aDua[2][1] 1
aDua[2][2] 2
int aDua[3][3];
int i, j;
Pada contoh ini nested looping digunakan untuk melakukan pemberian nilai awal elemen
array aDua. Variabel i digunakan sebagai indeks baris dan variabel j digunakan sebagai
indeks kolom. Sedangkan nilai yang diberikan untuk setiap elemen array adalah sama
dengan j. Jika program ini dijalankan maka isi setiap elemen array aDua sesuai urutan
pengisian nilainya adalah seperti ditunjukkan pada tabel 19.
95
Tabel 19. Nilai elemen array, inisialisasi dengan looping
Elemen Nilai
aDua[0][0] 0
aDua[0][1] 1
aDua[0][2] 2
aDua[1][0] 0
aDua[1][1] 1
aDua[1][2] 2
aDua[2][0] 0
aDua[2][1] 1
aDua[2][2] 2
Jika struktur looping pada potongan program sebelumnya digunakan kembali tetapi
dengan mempertukarkan fungsi baris kolomnya sehingga variabel i yang tadinya
merupakan indeks baris digunakan sebagai indeks dan variabel j yang tadinya
merupakan indeks kolom digunakan sebagai indeks baris. Untuk mengaplikasikan hal ini
cukup dengan mengganti perintah
aDua[i][j] = (i+j);
menjadi
aDua[j][i] = (i+j);
Setelah modifikasi kecil ini dilakukan, maka isi setiap elemen array aDua sesuai urutan
pengisian nilainya adalah seperti ditunjukkan pada tabel 20.
Elemen Nilai
aDua[0][0] 0
aDua[1][0] 1
aDua[2][0] 2
aDua[0][1] 0
aDua[1][1] 1
96
aDua[2][1] 2
aDua[0][2] 0
aDua[1][2] 1
aDua[2][2] 2
Perhatikan gambar 30 yang mengilustrasikan perbedaan isi elemen array aDua sesuai
tabel 19 dan tabel 20.
0 1 2 0 1 2
0 0 1 2 0 0 0 0
1 0 1 2 1 1 1 1
2 0 1 2 2 2 2 2
Matriks biasanya ditulis dengan menggunakan kurung siku atau kurung kurawal.
Misalkan A adalah matriks ordo 3x3, maka matriks dapt ditulis sebagai:
97
a11 adalah elemen matrik A pada baris pertama kolom pertama, a12 adalah elemen
matriks A pada baris pertama kolom kedua, a 21 adalah elemen matriks A pada baris
kedua kolom pertama dan seterusnya hingga a 33 yang merupakan elemen baris ketiga
kolom ketiga.
Misalkan kita memiliki dua buah matriks A dan B. Operasi penjumlahan matrik
A dan B baru bisa dilakukan jika memenuhi syarat matrik A dan B memiliki ordo yang
sama. Artinya jika A adalah matrik 3x3 maka B juga harus 3x3. Jika ordo matrik A
berbeda dengan matrik B maka operasi penjumlahan atau pengurangan tidak dapat
dilakukan.
98
Dari gambar 31 terlihat bahwa elemen c 11 adalah hasil penjumlahan/penguranan
elemen a11 dan b11, elemen c12 adalah hasil penjumlahan/penguranan elemen a 12 dan b12,
dan seterusnya. Jika kita menggunakan i sebagai indeks baris dan j sebagai indeks
kolom, maka notasi untuk operasi penjumlahan atau pengurangan dapat disederhanakan
menjadi:
99
Flowchart program untuk operasi penjumlahan matriks 3x3 ditunjukkan pada gambar 33.
Start
A
Input
C[ i ][ j ] = A[ i ][ j ] + B[ i ][ j ]
A[ i ][ j ]
j j
i i
Input Cetak
B[ i ][ j ] C[ i ][ j ]
j j
i i
A
End
100
Pada flowchart gambar 33 terlihat bahwa terdapat empat buah nested loop, masing-
masing untuk input data matriks A, input data matriks B, operasi penjumlahan matriks A
dan matriks B serta yang terakhir untuk mencetak matriks C sebagai matriks hasil
penjumlahan. Contoh program yang dibuat berdasarkan flowchart tersebut adalah:
//Dalam C
#include <stdio.h>
main()
{
int i, j, A[3][3], B[3][3], C[3][3];
//Cetak matriks C
printf("\nHasil penjumlahan matriks A dan B:\n");
for(i=0; i<3; i++)
{
for(j=0;j<3; j++)
printf("%5d", C[i][j]);
printf("\n");
}
}
101
//Dalam C++
#include <iostream>
using namespace std;
main()
{
int i, j, A[3][3], B[3][3], C[3][3];
//Cetak matriks C
cout<< "\nHasil penjumlahan matriks A dan B:" <<endl;
for(i=0; i<3; i++)
{
for(j=0;j<3; j++)
cout << C[i][j] << "\t";
102
Bentuk output dari program ini jika dijalankan dan data yang dimasukkan berturut-turut
3, 5, 6, 7, 8, 9, 3, 4, 6, 6, 8, 6, 4, 9, 9, 10, 12, 17 adalah:
Namun demikian array lebih dari tiga dimensi relatif jarang digunakan. Selain alasan
kompleksitas dalam penanganan indeksnya, jumlah memory komputer yang digunakan
juga menjadi pertimbangan. Sebagai contoh, array empat dimensi dengan tipe data
integer dengan ukuran [10][6][9][4] akan membutuhkan ruang memori sebesar
10*6*9*4*2 atau 4320 byte jika diasumsikan tipe data integer menggunakan memory
sebesar 2 byte. Jika array dengan ukuran yang sama tetapi dengan tipe data double maka
jumlah memory yang dibutuhkan adalah 17280 byte, dengan asumsi bahwa tipe data
double menggunakan 8 byte memory. Ruang memory yang digunakan untuk array akan
meningkat secara eksponensial menurut jumlah dimensinya.
103
Dalam hal penggunaan looping, jumlah dimensi array akan berbanding lurus
dengan jumlah loop yang digunakan sebagai indeks. Artinya, array satu dimensi
memerlukan satu buah loop, array dua dimensi memerlukan 2 buah loop, array lima
dimensi memerlukan lima buah loop, dan seterusnya.
104
BAB VII
FUNGSI
Langkah-langkah berikut ini adalah salah satu contoh dekomposisi masalah untuk
sistem ATM tersebut:
1. Urai masalah yang kompleks menjadi sejumlah tugas yang lebih kecil dan
komponen-komponen yang dapat dikelola. Dalam C/C++, yang menjadi komponen
utama adalah fungsi main() yang merupakan tempat dimana pemanggilan fungsi
lainnya diakukan.
2. Identifikasi semua komponen utama. Untuk contoh kasus ATM, asumsikan bahwa
komponen utamanya adalah:
Menampilkan saldo
Transfer dana
Penarikan uang
Pendaftaran fasilitas perbankan
3. Setelah komponen utama maka tugas-tugas yang terlibat pada komponen-komponen
tersebut dapat divisualisasikan dan dipecah kembali menjadi tugas-tugas yang lebih
sederhana.
4. Komponen "Penarikan uang" dapat disederhanakan menjadi fungsi-fungsi:
105
Ambil saldo rekening
Bandingkan saldo yang tersedia dengan jumlah yang diinginkan
Update data rekening
Tolak permintaan penarikan dana
Cetak slip
5. Jika diperlukan, hasil dekomposisi ini dapat dipecah lagi menjadi fungsi-fungsi yang
lebih kecil dan lebih spesifik.
Fungsi
utama
Bandingkan Tolak
Update data Keluarkan
saldo dg permintaan Cetak slip
rekening uang
permintaan penarikan
106
7.1 Prototipe fungsi
Prototipe bertujuan untuk memberitahu C/C++ bagaimana sebuah fungsi
dibangun dan digunakan dalam program. Dalam praktek pemrograman, adalah hal yang
umum untuk menunjukkan bentuk dari sebuah fungsi sebelum fungsi tersebut benar-
benar dibuat. Programer harus dengan cermat memikirkan apa kegunaan sebuah fungsi,
bagaimana fungsi tersebut menerima input dan output seperti apa yang akan
dihasilkannya. Untuk lebih jelasnya, perhatikan prototipe fungsi berikut:
Prototipe dan implementasi fungsi dapat sangat beragam. Input parameter untuk
sebuah fungsi tidak selalu diperlukan, seperti halnya bahwa sebuah fungsi tidak harus
selalu mengembalikan sebuah nilai. Dalam kasus ini programer dapat menyatakan
parameter fungsi dan/atau nilai kembalian fungsi sebagai void. Perhatikan dua prototipe
fungsi berikut yang mengimplementasikan kata kunci void.
void cetakSlip(int);
Kata kunci void di depan nama fungsi menunjukkan bahwa fungsi cetakSlip tidak
akan mengembalikan suatu nilai tertentu setelah fungsi ini selesai dilaksanakan.
int ambilBilanganAcak(void);
107
Prototipe fungsi harus diletakkan diluar fungsi main() dan sebelum fungsi main()
dimulai dan tidak ada batasan berapa banyak prototipe fungsi yang dapat dimasukkan
dalam sebuah program. Perhatikan contoh berikut:
#include <stdio.h>
int jumlahDuaBilangan(int, int); //prototipe fungsi
int ambilBilanganAcak(void); //prototipe fungsi
void cetakSlip(int); //prototipe fungsi
main()
{
//tubuh program
}
tipedata_fungsi adalah tipe data dari nilai yang akan dikembalikan setelah fungsi
tersebut dijalankan. Fungsi dapat mengembalikan nilai apa saja (int, float, char, dsb)
kecuali array. nama_fungsi biasanya menggambarkan operasi yang fungsi tersebut.
nama_fungsi dibuat mengikuti tata cara pembuatan variabel. daftar parameter
adalah satu atau sejumlah variabel beserta tipe datanya yang dipisahkan oleh tanda koma.
108
Daftar parameter diletakkan dalam tanda kurung setelah nama fungsi. Parameter adalah
variabel yang akan menerima nilai atau tertentu ketika fungsi tersebut dipanggil.
Ilustrasi aliran program yang menggunakan fungsi dapat dilihat pada gambar 35.
Fungsi main() sebagai fungsi utama diwakili oleh flowchart yang dimulai dengan Start,
flowchart disampingnya adalah flowchart untuk fungsi yang diberi nama hLuas().
hLuas() merupakan fungsi yang digunakan untuk menghitung luas persegi panjang.
Simbol flowchart yang digunakan untuk pemanggilan fungsi adalah persegi dengan garis
sejajar pada sisi kiri dan kanannya.
Pemanggilan sebuah fungsi dilakukan dengan cara menulis nama fungsi disertai
dengan seluruh parameter yang diperlukan. Pada ilustrasi gambar 35, pemanggilan
fungsi dilakukan dalam perintah luas = hLuas(panjang, lebar). Perintah ini
bermakna setelah fungsi hLuas() dikerjakan maka nilai yang dikembalikan oleh fungsi
tersebut disimpan dalam variabel luas. Sedangkan agar fungsi hLuas() dapat bekerja
diperlukan dua buah nilai, dalam hal ini nilai variabel panjang dikirim menuju fungsi
109
hLuas() dan ditampung dalam variabel x, dan nilai variabel lebar ditampung dalam
variabel y, untuk selanjutnya dilakukan operasi perkalian x dan y. Hasil operasi
perkalian yang disimpan dalam variabel luas inilah yang kemudian dikembalikan
kepada fungsi pemanggilnya, yakni baris perintah dalam fungsi main().
Start
Input pj
hLuas(int x, int y)
Input lb
luas = x * y
Cetak
luas
end
Contoh konkrit untuk penggunaan fungsi, misalkan kita diminta membuat program
untuk melakukan perhitungan (a) luas persegi panjang, (b) luas bujursangkar, (c) isi
balok dan (d) isi kubus. Sebelum perhitungan dilakukan, terlebih dahulu tampilkan menu
pilihan untuk memilih perhitungan mana yang akan dikerjakan. Setelah suatu pilihan
dibuat dan dikerjakan, tampilkan kembali menu ini untuk memilih jenis perhitungan
lainnya.
Perhitungan luas persegi panjang, luas bujur sangkar, isi balok dan isi kubus
menggunakan formula dasar matematika yang sama. Luas persegi panjang dan luas
bujursangkar dihitung dengan cara mengalikan panjang dengan lebar, bujur sangkar
110
memiliki nilai panjang dan lebar yang sama dan sering disebut sebagai sisi.
Sedangkan isi balok dan isi kubus dihitung cara mengalikan panjang dengan lebar
dengan tinggi, atau dapat disederhanakan menjadi luas_alas kali tinggi.
Dari uraian sebelumnya terlihat bahwa dalam perhitungan luas persegi panjang,
luas bujursangkar, isi balok dan isi kubus terdapat kesamaan dalam hal menghitung luas.
Dalam praktek pemrograman, kesamaan tugas atau proses perhitungan seperti iniliah
yang kemudian diimplementasikan sebagai fungsi. Algoritma untuk penyelesaian kasus
ini dapat disusun sebagai berikut:
1. Tampilkan menu pilihan perhitungan: (a) luas persegi, (b) luas bujursangkar, (c) isi
balok dan (d) isi kubus.
2. Masukkan pilihan perhitungan, jika pilihan adalah:
a. Masukkan nilai untuk panjang dan lebar, panggil fungsi hLuas(panjang, lebar)
untuk menghitung luas persegi.
b. Masukkan nilai untuk sisi, panggil fungsi hLuas(sisi, sisi) untuk menghitung luas
bujursangkar.
c. Masukkan nilai untuk panjang, lebar dan tinggi, panggil fungsi hLuas(panjang,
lebar) kali tinggi untuk menghitung isi balok.
d. Masukkan nilai untuk sisi, panggil fungsi hLuas(sisi, sisi) kali sisi untuk
menghitung isi kubus.
111
Start hLuas(int x, int y)
C
luas = x * y
Tampilkan
pilihan
return luas
Input
pilihan
A B
isi = hLuas(p, l) * t
cetak isi
luas = hLuas(p, l)
cetak isi
luas = hLuas(s, s)
diulang? true C
cetak
luas
A B end
112
//dalam C
#include <stdio.h>
#include <conio.h>
int hLuas(int, int);
main()
{
int p, l, s, t;
int isi, luas;
char ulang, pilih;
do{
system("cls");
printf("Pilih jenis perhitungan:");
printf("\na. Luas persegi panjang");
printf("\nb. Luas bujur sangkar");
printf("\nc. Isi balok");
printf("\nd. Isi Kubus");
printf("\n\nMasukkan huruf pilihan: ");
pilih=getche();
switch(pilih){
case 'a':
case 'A': printf("\n\nMenghitung luas persegi ");
printf("\nInput panjang : ");
scanf("%d", &p);
printf("Input lebar: ");
scanf("%d", &l);
luas = hLuas(p, l);
printf("Luas adalah: %d", luas);
break;
case 'b':
case 'B': printf("\n\nMenghitung luas bujursangkar");
printf("\nInput sisi : ");
scanf("%d", &s);
luas = hLuas(s, s);
printf("Luas adalah: %d", luas);
break;
case 'c':
case 'C': printf("\n\nMenghitung isi balok");
printf("\nInput panjang : ");
scanf("%d", &p);
printf("Input lebar: ");
scanf("%d", &l);
printf("Input tinggi: ");
scanf("%d", &t);
isi = hLuas(p, l) * t;
printf("Isi adalah: %d", isi);
break;
113
case 'd':
case 'D': printf("\n\nMenghitung isi kubus");
printf("\nInput sisi : ");
scanf("%d", &s);
isi = hLuas(s, s) * s;
printf("Isi adalah: %d", isi);
break;
default: printf("\n\ninput pilihan yang salah");
break;
}
return 0;
}
//dalam C++
#include <iostream>
#include <conio.h>
using namespace std;
main()
{
int p, l, s, t;
int isi, luas;
char ulang, pilih;
do{
system("cls");
cout << "Pilih jenis perhitungan:";
cout << "\na. Luas persegi panjang";
cout << "\nb. Luas bujur sangkar";
cout << "\nc. Isi balok";
cout << "\nd. Isi Kubus";
cout << "\n\nMasukkan huruf pilihan: ";
pilih=getche();
114
switch(pilih){
case 'a':
case 'A': cout<<"\n\nMenghitung luas persegi panjang";
cout << "\nInput panjang : ";
cin >> p;
cout << "Input lebar: ";
cin >> l;
luas = hLuas(p, l);
cout << "Luas adalah: " << luas;
break;
case 'b':
case 'B': cout << "\n\nMenghitung luas bujursangkar";
cout << "\nInput sisi : ";
cin >>s;
luas = hLuas(s, s);
cout << "Luas adalah: " << luas;
break;
case 'c':
case 'C': cout << "\n\nMenghitung isi balok";
cout << "\nInput panjang : ";
cin >> p;
cout << "Input lebar: ";
cin >> l;
cout << "Input tinggi: ";
cin >> t;
isi = hLuas(p, l) * t;
cout << "Isi adalah: " << isi;
break;
case 'd':
case 'D': cout << "\n\nMenghitung isi kubus";
cout << "\nInput sisi : ";
cin >> s;
isi = hLuas(s, s) * s;
cout << "Isi adalah: " << isi;
break;
default: cout << "\n\nSalah input pilihan ";
break;
}
return 0;
}
//fungsi
Pada untuk
program di menghitung
atas, perintah luas persegi
system("cls") digunakan untuk membersihkan atau
int hLuas(int panjang, int lebar)
menghapus
{ layar sebelum menampilkan menu pilihan. Perintah ini memanggil fungsi
int luas;
clear screen (cls) milik sistem operasi windows. Perintah cls hanya bekerja
luas = panjang * lebar;
return luas;
} 115
dilingkungan sistem operasi windows, sehingga jika sistem operasi yang digunakan
selain windows perintah cls ini harus diganti dengan perintah yang sesuai dengan
sistem operasi yang digunakan.
116
#include <stdio.h>
main()
{
int num1;
printf("\nMasukkan sebuah angka: ");
scanf("%d", &num1);
printf("\nAngka yang anda masukkan: %d\n", num1);
}
Karena variabel lokal hanya dikenal dalam fungsi tempat variabel tersebut
dideklarasikan, maka nama variabel yang sama dapat digunakan dalam fungsi lainnya
tanpa khawatir data yang tersimpan di dalamnya saling tertukar. Untuk lebih jelasnya
perhatikan program berikut ini:
#include <stdio.h>
void printAngka(void);
main()
{
int num1 = 10;
printf("nilai num1 dalam fungsi main: %d\n", num1);
printAngka();
printf("nilai num1 dalam fungsi main: %d\n", num1);
return 0;
}
void printAngka()
{
float num1 = 5.5;
117
Pada fungsi main(), num1 dideklarasikan sebagai integer sedangkan pada fungsi
printAngka() dideklarasikan sebagai float. Pada output terlihat bahwa nilai varibel
num1 yang berada dalam fungsi main() adalah 10 dan yang berada dalam fungsi
printAngka() adalah 5.5. Artinya, meskipun nama variabelnya sama namun karena
didefinisikan di dalam fungsi yang berbeda maka variabel num1 pada fungsi main()
dan num1 pada fungsi printAngka() adalah dua variabel yang berbeda.
Berbeda dengan variabel lokal, variabel global akan dikenali sebagai variabel
yang sama dimanapun variabel itu ditemui di dalam program. Variabel global biasanya
didefinisikan di luar semua fungsi. Akibatnya jika nilai variabel tersebut diubah dalam
suatu fungsi maka nilai perubahannya akan berdampak pada fungsi lain yang
menggunakan variabel yang sama. Perhatikan contoh program berikut ini.
#include <stdio.h>
void printAngka(void);
int num1;
main()
{
num1 = 10;
printf("nilai num1 dalam fungsi main: %d\n", num1);
printAngka();
printf("nilai num1 dalam fungsi main: %d\n", num1);
return 0;
}
void printAngka()
{
num1 *= 2;
Varibel num1 didefinisikan di luar semua fungsi. Pada fungsi main(), variabel num1
diisi dengan nilai 10 kemudian pada fungsi printAngka() nilai variabel ini dikalikan
dengan 2. Perubahan nilai yang terjadi dalam fungsi printAngka() ini akan
berdampak pada fungsi main(). Output dari program jika dijalankan adalah
118
Pada output terlihat bahwa pertama kali nilai num1 adalah 10 pada fungsi main(),
kemudian menjadi 20 pada fungsi printAngka(). Setelah aliran program kembali ke
fungsi main() tampak bahwa nilai num1 adalah 20, artinya perubahan nilai yang terjadi
dalam fungsi printAngka() juga berdampak pada fungsi main().
#include <stdio.h>
int pangkat2(int);
int main(void)
{
int t=10;
int pangkat2(int x)
{
x = x*x;
return(x);
}
Pada contoh ini, nilai argumen t yang dikirim ke fungsi pangkat2() adalah 10, nilai
ini dikopikan ke dalam variabel x pada fungsi pangkat2(). Ketika operasi x = x*x
dilaksanakan, hanya nilai variabel lokal x yang berubah. Variabel t yang digunakan
119
untuk memanggil fungsi pangkat2() tetap bernilai 10. Karenanya, output dari program
adalah x=100 t=10.
Ingatlah bahwa yang dikirim ke dalam fungsi adalah nilai dari argumen bukan
argumennya, sehingga apapun operasi yang terjadi di dalam fungsi tidak berpengaruh
pada variabel yang digunakan pada pemanggilan fungsi tersebut.
Cara yang kedua adalah pass by reference. Dengan cara ini yang dikirim ke
dalam fungsi adalah pointer atau alamat dari argumen, bukan nilai yang ada dalam
argumen tersebut. Karenanya operasi yang dilakukan terhadap alamat argumen tersebut
juga akan berpengaruh pada variabel yang ada pada fungsi pemanggilnya.
#include <stdio.h>
void tukar(int *x, int *y);
Fungsi tukar() digunakan untuk melakukan pertukaran nilai dari dua variabel yang
diwakili oleh x dan y karena x dan y menyimpan alamat variabel bukan nilainya.
Kemudian, di dalam fungsi, operasi pertukaran data dilakukan.
120
Output program setelah dijalankan adalah:
Mula-mula variabel i diberi nilai 10 dan j diberi nilai 20. Kemudian dilakukan
pemanggilan fungsi tukar() dengan mengirimkan alamat variabel i dan j (operator &
digunakan untuk menghasilkan alamat variabel). Dengan demikian yang dikirim adalah
alamat variabel i dan j, bukan nilai yang ada dalam kedua variabel tersebut.
Fungsi tambahDua() bertipe void, artinya tidak ada nilai yang akan dikembalikan oleh
fungsi ini. angka adalah array bertipe integer yang sebagai parameter fungsi. Berikut
adalah lengkap untuk pengiriman array ke dalam fungsi.
121
#include <stdio.h>
//deklarasi fungsi
void tambahDua(int []);
main()
{
int arAngka[5] = { 3, 40, 5, 16, 9};
int i;
tambahDua(arAngka);
return 0;
}
Dalam fungsi main() array arAngka bertipe integer dan diberi nilai berturut-
turut 3, 40, 5, 16 dan 9 untuk setiap elemennya. Pemanggilan fungsi
tambahDua() dilakukan dengan perintah tambahDua( arAngka ). Disini terlihat
bahwa cara pemanggilannya sama dengan cara pemanggilan fungsi dengan pass by
122
value. Namun karena arAngka merupakan array maka yang diterima oleh fungsi
tambahDua() adalah alamat dari array arAngka. Jadi, meskipun arAngka dan angka
merupakan nama array yang berbeda, namun kedua array ini sebenarnya merujuk pada
lokasi memori yang sama. Sehingga perubahan yang terjadi pada array angka juga
berakibat pada array arAngka. Perhatikan output dari program ini. Pada output terlihat
bahwa nilai pada array arAngka setelah pemanggilan fungsi tambahDua() adalah
sama dengan nilai pada array angka yang berada dalam fungsi tambahDua()
tipe_data[][ukuran]
tipe_data[][ukuran][ukuran]
tipe_data[][ukuran][ukuran]...[ukuran]
masing-masing deklarasi untuk array dua dimensi, tiga dimensi dan yang lebih dari tiga
dimensi. Perhatikan bahwa kurung siku pertama selalu dikosongkan, sedangkan kurung
siku selanjutnya diisi dengan ukuran array yang sesungguhnya sesuai urutan dimensinya.
Hal ini diperlukan untuk memberi tahu compiler agar dapat menentukan ukuran dari
setiap dimensi tambahan pada array. Berikut adalah contoh ilustrasi deklarasi dan fungsi
untuk pengiriman array multi dimensi ke dalam fungsi.
123
#include <stdio.h>
main()
{
int arSatu[3][3], arDua[4][4][3];
int x;
...
x = fungsi1(arSatu, 3);
...
fungsi2(arDua);
...
}
Dengan memanfaatkan array yang dikirim sebagai argumen fungsi kita dapat
memodifikasi flowchart dan program yang ditunjukkan pada gambar 33 sehingga
algoritmanya menjadi lebih sederhana. Algoritma operasi penjumlahan matriks, secara
singkat dapat ditulis menjadi
1. Panggil fungsi untuk input data matriks A
2. Panggil fungsi untuk input data matriks B
3. Jumlahkan matriks A dan B, simpan hasilnya dalam matriks C
4. Panggil fungsi untuk mencetak elemen matriks A
5. Panggil fungsi untuk mencetak elemen matriks B
6. Panggil fungsi untuk mencetak matriks C
7. Selesai
124
Berdasarkan algoritma ini, flowchart yang memanfaatkan fungsi untuk operasi
penjumlahan matrik dapat dilihat pada gambar 37.
Start jmlMatrik(X,Y,Z)
Z[ i ][ j ] = X[ i ][ j ] + Y[ i ][ j ]
jmlMatrik(A, B)
j
cetakMatrik(A)
cetakMatrik(B) cetakMatrik(X)
return
Input
j
X[ i ][ j ]
ganti
j baris
i i
return return
125
Contoh program yang dapat dibangun berdasarkan flowchart pada gambar 37 adalah:
//Dalam C
#include <stdio.h>
void inputMatrik(int[][3]);
void cetakMatrik(int[][3]);
void jmlMatrik(int[][3], int[][3], int[][3]);
main()
{
int A[3][3], B[3][3], C[3][3];
//Cetak matriks A
printf("Matriks A: \n");
cetakMatrik(A);
//Cetak matriks B
printf("\n\nMatriks B: \n");
cetakMatrik(B);
//Cetak matrik C
printf("\n\nHasil penjumlahan matriks A dan B:\n");
cetakMatrik(C);
return 0;
}
126
void cetakMatrik(int X[][3])
{
int i, j;
printf("\n");
}
}
//Dalam C++
#include <iostream>
#include <iomanip>
using namespace std;
void inputMatrik(int[][3]);
void cetakMatrik(int[][3]);
void jmlMatrik(int[][3], int[][3], int[][3]);
main()
{
int A[3][3], B[3][3], C[3][3];
127
//Cetak matriks A
cout <<"Matriks A: " << endl;
cetakMatrik(A);
//Cetak matriks B
cout <<"\n\nMatriks B: " << endl;
cetakMatrik(B);
//Cetak matrik C
cout <<"\n\nHasil penjumlahan matriks A dan B:" << endl;
cetakMatrik(C);
return 0;
}
128
Jika program ini dijalankan kemudian berturut-turut dimasukkan angka 3, 4, 5, 6,
3, 4, 5, 7 dan 4 untuk setiap elemen matriks A dan angka 5, 6, 7, 8, 4, 3,
4, 5 dan 6 untuk setiap elemen matriks B, maka ouputnya adalah:
129
130
BAB VIII
POINTER
1001 1004
1002
1003
1004
1005
1006
Memori
131
Gambar 38. Sebuah variabel yang menunjuk variabel lainnya
Sebagai contoh, jika sebuah variabel berisi alamat dari variabel lainnya, variabel pertama
dikatakan menunjuk (point to) variabel kedua. Hal ini diilustrasikan dalam gambar 38.
Sama seperti variabel lainnya, sebelum dapat digunakan variabel pointer harus
terlebih dahulu dideklarasikan. Variabel pointer (selanjutnya akan disebut sebagai
pointer saja) dideklarasikan dengan cara menuliskan tipe data diikuti tanda * (bintang)
dan nama variabel.
tipe_data *nama_variabel;
Tipe data dari pointer biasanya sesuai dengan tipe data dari variabel yang alamatnya
akan disimpan. Meski secara teknis semua tipe pointer dapat menunjuk alamat manapun
dalam memori, namun semua operasi pointer sangat bergantung pada tipe datanya.
Misalkan kita mendeklarasikan pointer dengan tipe data integer (int *), compiler akan
mengasumsikan bahwa data pada alamat yang tersimpan dalam pointer tersebut adalah
integer tidak peduli apakah data pada alamat yang ditunjuk tersebut benar-benar integer
atau bukan. Karena itu, ketika mendeklarasikan pointer, perlu dipastikan apakah tipe
datanya cocok dengan tipe data variabel atau objek yang ditunjuk.
m = &angka;
berarti, letakkan alamat memori dari variabel angka ke dalam m. Alamat ini adalah
lokasi variabel angka dalam memori internal komputer dan tidak ada hubungannya
dengan nilai yang tersimpan pada alamat tersebut. Kita dapat mengartikan & sebagai
"alamat dari". Sehingga, m = &angka dapat ditulis dalam kalimat verbal sebagai "m
menerima alamat dari angka".
132
Untuk memahami pemberian nilai di atas dengan lebih baik, asumsikan bahwa
variabel angka menempati lokasi 2000 untuk menyimpan datanya. Asumsikan juga
bahwa data yang tersimpan dalam angka adalah 100. Maka setelah pemberian nilai di
atas, m akan memiliki nilai 2000. Karena yang merupakan alamat memori adalah 2000,
sedangkan 100 adalah data yang berada pada alamat 2000 tersebut.
q = *m;
meletakkan nilai dari angka ke dalam q. Sehingga q akan memiliki nilai 100 karena 100
tersimpan pada lokasi memori 2000, yang merupakan alamat memori yang tersimpan
dalam m. Kita dapat mengartikan * sebagai "pada alamat". Dalam kasus ini, statemen
q = *m dapat ditulis dalam kalimat verbal sebagai "q menerima nilai yang
tersimpan pada alamat m".
133
#include <stdio.h>
int main()
{
int x = 99;
int *p1, *p2;
p1 = &x;
p2 = p1;
p1 dan p2 berisi data yang sama yaitu alamat dari x. Maka, keduanya mengacu pada
objek yang sama yaitu variabel x. Output dari program ini jika dijalankan adalah:
Secara default, dalam C/C++, argumen yang dikirim dalam fungsi adalah dalam
bentuk nilai dimana nilai ini dikopikan ke dalam variabel lokal dalam fungsi untuk dapat
digunakan. Tergantung pada besaran data dari argumen yang dikirim, hal ini bisa jadi
mengakibatkan pemborosan dalam hal penggunaan memori.
Tidak ada yang salah dengan penggunaan pass by value ke dalam fungsi.
Penduplikasian data mudah untuk dilakukan juga mudah dalam hal debugging program.
Namun dalam kenyataannya, programmer C dituntut untuk mampu membangun program
134
dengan memanfaatkan memori sekecil mungkin. Bayangkan pada kasus sistem minimal
(embedding system) dimana jumlah memory yang tersedia sangat terbatas. Dalam situasi
ini, membuat duplikasi data akan berarti pemborosan sumber daya memori. Bahkan,
meskipun pemrograman tidak dilakukan untuk sistem minimum, penurunan kinerja
program akan terjadi ketika data dalam ukuran besar dikirimkan ke dalam fungsi dengan
cara pass by value (misalnya array atau struktur data yang menyimpan data pelanggan).
#include <stdio.h>
void tukar(int *, int *);
Dan pada fungsi, * diletakkan didepan nama variabel pointer, sehingga pada contoh di
atas fungsi tukar() ditulis dengan
135
void tukar(int *x, int *y)
{
...
}
Perintah tukar(&i, &j) akan mengirimkan alamat variabel i dan j ke dalam fungsi
tukar(), alamat ini akan diterima oleh pointer x dan y. Pada gilirannya operasi
pertukaran data yang dilakukan oleh pointer x dan y sebenarnya adalah operasi
pertukaran data pada variabel i dan j.
136
#include <stdio.h>
int main(void)
{
double x = 100.1, y;
int *p;
Pada contoh output tersebut terlihat bahwa alamat yang tersimpan dalam p sama persis
dengan alamat asli &x. Jadi, meskipun operasi pointer p merupakan operasi yang valid,
namun nilai yang diletakkan melalui p adalah data yang tidak valid.
137
Agar program di atas menghasilkan nilai yang benar, maka pada proses peletakan
nilai ke dalam y harus dilakukan konvesi balik dari integer menjadi double. Caranya
dengan mengganti perintah y = *p dengan perintah y = *(double*)p.
p1++;
p1 akan berisi 2002, bukan 2001. Hal ini dikarenakan setiap kali dilakukan increment,
p1 akan mengacu pada integer berikutnya, dalam hal ini kenaikan terjadi untuk setiap 2
byte. Hal yang sama juga terjadi pada operasi decrement. Misalkan p1 bernilai 2000,
maka operasi
p1--;
Dari contoh di atas dapat disimpulkan bahwa dalam operasi aritmatika pointer, setiap
kali dilakukan increment atau decrement, pointer akan mengacu pada lokasi memori dari
elemen berikutnya sesuai dengan ukuran tipe datanya. Jika tipe data pointer adalah char,
maka operasi aritmatika akan terlihat "normal" karena char menggunakan 1 byte data.
Namun jika tipe datanya adalah float maka kenaikan atau penurunan terjadi untuk setiap
4 byte karena float menggunakan 4 byte memori, jika datanya adalah integer maka
kenaikan atau penurunan terjadi untuk setiap 2 byte. Perhatikan ilustrasi pada gambar 39
untuk memudahkan dalam memahami konsep ini.
138
char *ch=(char*) 3000;
int *I = (int*) 3000;
ch 3000
i
ch+1 3001
ch+2 3002
i+1
ch+3 3003
ch+4 3004
i+2
ch+5 3005
Gambar 39. Aritmatika pointer tergantung pada tipe datanya (int diasumsikan 2 byte)
Proses penjumlahan dan pengurangan pointer tidak hanya dilakukan dengan cara
melakukan increment dan decrement, tetapi juga dapat dilakukan dengan cara
penjumlahan atau pengurangan dengan nilai tertentu seperti
p1 = p1 + 10;
yang menyebabkan p1 mengacu pada elemen ke-10 setelah posisinya saat ini.
Selain penambahan atau pengurangan dengan angka integer, hanya ada satu
operari artimatika lain yang dapat dilakukan pada pointer, yaitu pengurangan pointer
dengan pointer lainnya untuk mengetahui berapa banyak elemen yang ada diantara kedua
pointer sesuai dengan tipe data pointer tersebut. Semua operasi artimatika lainnya tidak
tidak dapat dilakukan. Artinya, operasi perkalian atau pembagian tidak dapat dilakukan
pada pointer, demikian juga penjumlahan dua buah pointer juga tidak dibolehkan.
Operasi dengan operator bitwise tidak dapat digunakan, dan juga pada penambahan atau
pengurangan pointer tidak dapat dilakukan dengan bilangan yang memiliki tipe data float
atau double.
139
140
BAB IX
STRING
Ilustrasi isi memori untuk deklarasi tersebut ditunjukkan pada gambar 40.
namaku[5]
S u s i \0
Alamat memori
Deklarasi variabel namaku juga dapat dilakukan dengan cara memasukkan literal string.
Literal string adalah urutan karakter yang diapit dengan tanda petik dua.
Dengan cara ini, pada deklarasi array namaku tidak perlu mencantumkan jumlah
elemen, karena jumlah elemennya akan disesuaikan dengan data yang diberikan,
termasuk karakter null.
141
Meskipun secara logis string merupakan array karakter, penting untuk diketahui
bahwa string diimplementasikan sebagai sebuah pointer yang mengacu pada area memori
tertentu. lebih spesifik, nama variabel string sebenarnya merujuk pada pada alamat
memori dari karakter pertama pada string. Statement berikut merupakan deklarasi string
sebagai pointer
Statemen ini mendeklarasikan variabel pointer dan meletakkan literal string "Susi" pada
lokasi memori pertama dan selanjutnya dari alamat yang diacu oleh pointer namaku.
Dengan kata lain, pointer namaku mengacu pada karakter pertama dari string "Susi".
#include <stdio.h>
main()
{
char *namaku = "Susi";
int x=0;
Output program:
142
Pada output terlihat bahwa nilai pointer sama dengan alamat dari huruf pertama yaitu
0x53.
Gambaran pointer yang digunakan untuk merujuk pada sebuah string dan string sebagai
yang deklarasikan sebagai array karakter diilustrasikan pada gambar 41.
*namaku 0x4d
Pointer berisi alamat memori dari
elemen pertama pada array
namaku[5]
S u s i \0
Alamat memori
#include <stdio.h>
main()
{
char warna[12];
143
Pada contoh, string dideklarasikan sebagai array karakter dengan nama warna. Pada
fungsi scanf() variabel warna ditulis tanpa menggunakan tanda & di depan nama
variabel seperti halnya pada input data pada umumnya, demikian pula pada proses
output.
Namun cara ini bukan tanpa masalah. Jika data yang diinput mengandung
karakter spasi, misal "merah muda", yang dicetak hanya data sampai sebelum spasi
saja, dalam hal ini "merah". Kejadian berlaku baik pada C menggunakan scanf() dan
printf() maupun C++ menggunakan cin dan cout. Hal ini terjadi karena karakter
spasi oleh fungsi input standar dianggap sebagai karakter null.
Untuk mengatasi hal ini, kita dapat menggunakan fungsi gets() untuk
melakukan input string. Untuk melakukannya perintah scanf("%s", warna) pada
program sebelumnya diganti dengan perintah gets(warna). Dengan gets() jika data
yang dimasukkan adalah "merah muda", maka yang dicetak dengan perintah printf()
atau cout juga "merah muda".
Namun penggunaan perintah gets() juga bukan tanpa masalah. Karena gets()
akan mengabaikan jumlah elemen array yang dideklarasikan. sebagai contoh jika data
yang dimasukkan adalah "merah muda terang" yang terdiri dari 18 karakter termasuk
karakter null, tetap akan dicetak sebagai "merah muda terang" meskipun jumlah
elemen array yang dideklarasikan adalah 12.
Dalam prakteknya array satu dimensi atau dua dimensi, keduanya dapat
digunakan untuk array string. Array satu dimensi dapat digunakan dengan
mengimplementasikan pointer lalu meletakkan literal string ke dalamnya, sedangkan
array dua dimensi digunakan jika tidak mengimplementasikan pointer.
144
Untuk memberikan gambaran yang lebih jelas, perhatikan contoh program
berikut yang menggunakan array satu dimensi dengan pointer:
#include <stdio.h>
main()
{
char *strNama[5] = {0};
char answer[80] = {0};
int x;
strNama[0] = "David";
strNama[1] = "Sheila";
strNama[2] = "Marta";
strNama[3] = "Bima";
strNama[4] = "Rahma";
strNama merupakan array pointer bertipe char yang memiliki 5 elemen. Literal string
dimasukkan satu persatu ke dalam setiap elemen array. Kemudian dengan memanfaatkan
loop for(), isi setiap elemen array dicetak ke layar.
Sedangkan jika tidak menggunakan pointer, array yang digunakan adalah array
dua dimensi seperti dicontohkan pada program berikut:
#include <stdio.h>
main()
{
char warna[5][12];
int x;
145
Array warna merupakan array dua dimensi yang mampu menampung sebanyak
60 karakter. Namun dalam implementasinya sebagai string, kita hanya perlu
mereferensikan dimensi pertamanya saja, baik untuk proses input ( gets(warna[x]))
maupun output (puts(warna[x])). Jika program ini dijalankan, salah satu contoh
outputnya adalah:
Sebagai contoh kasus, misalkan kita diminta untuk membuat program sederhana
untuk menghitung jumlah setiap huruf vokal dalam kalimat yang dimasukkan melalui
keyboard. Setelah dihitung, cetaklah jumlah setiap huruf vokal yang ada.
Untuk menyelesaikan contoh kasus ini terlebih dahulu disusun algoritma untuk
penyelesaiannya sebagai berikut:
1. Masukkan kalimat
146
2. Beri nilai awal 0 untuk variabel jmlA, jmlE, jmlI, jmlO dan jmlU
3. Hitung jumlah karakter menggunakan fungsi strlen()
4. Dengan menggunakan looping, periksalah setiap huruf mulai dari karakter pertama
sampai karakter terakhir.
a. Jika huruf A atau a, tambahkan jmlA dengan 1
b. Jika huruf E atau e, tambahkan jmlE dengan 1
c. Jika huruf I atau i, tambahkan jmlI dengan 1
d. Jika huruf O atau o, tambahkan jmlO dengan 1
e. Jika huruf U atau u, tambahkan jmlU dengan 1
5. Cetak jumlah setiap huruf vokal
6. Selesai
Jumlah setiap huruf vokal disimpan dalam variabel global. Setelah seluruh
karakter diperiksa dan diperoleh jumlah dari setiap huruf vokal dari kalimat yang
dimasukkan, kemudian hasilnya dicetak ke layar.
147
Start cekVokal()
Input kalimat
‘a’ jmlA++
i=0; i<strlen(kalimat);
i++
‘e’ jmlE++
cekVokal(kalimat[i])
‘i’ jmlI++
i
return
Contoh program yang dibangun berdasarkan flowchart pada gambar 42 adalah sebagai
berikut:
//Dalam bahasa C
#include <stdio.h>
#include <string.h>
void cekVokal(char);
int jmlA, jmlE, jmlI, jmlO, jmlU;
main()
{
int i;
char kalimat[80];
148
printf("Masukkan sebuah kalimat:\n");
gets(kalimat);
Dari total 62 karakter dalam kalimat yang dimasukkan, termasuk spasi dan tanda baca,
terdapat 11 huruf a, 5 huruf e, 5 huruf i, 1 huruf o dan 3 huruf u.
149
150
BAB X
Sejauh ini kita sudah menggunakan berbagai tipe data yang disediakan oleh
C/C++ seperti byte, short, int, long, float, double, char dan boolean yang sering juga
disebut sebagai tipe data primitif atau tipe data sederhana. Namun kadang kala, karena
kebutuhan yang berbeda, kita memerlukan tipe data lain yang lebih kompleks yang
merupakan kombinasi dari berbagai tipe data primitif yang sudah tersedia dalam C/C++.
10.1 Struct
struct digunakan untuk mendeklarasikan tipe data yang merupakan kumpulan
dari sejumlah tipe data primitif atau tipe data kompleks lainnya serta memberinya nama
sebagai pengenal tipe data. Secara fisik, struct disimpan dalam lokasi memori yang
berurutan sehingga operator sizeof dapat digunakan untuk mengambil ukuran memori
yang digunakan oleh struct bersangkutan.
struct dideklarasikan dengan cara menulis kata kunci struct diikuti dengan
nama_struct, lalu elemen-elemen anggota struct yang ditulis dalam pasangan tanda
kurung kurawal dan diakhiri dengan tanda titik koma sebagai berikut;
//cara pertama
//deklarasi struct
struct nama_struct {
tipe_data elemen1;
tipe_data elemen2;
...;
tipe_data elemen_n;
};
151
//cara kedua
Seperti halnya tipe data dan variabel lainnya, struct dapat didefinisikan di dalam
sebuah fungsi atau di luar fungsi. Jika struct didefinisikan dalam sebuah fungsi maka
struct akan bersifat lokal pada fungsi tersebut saja, namun jika didefinisikan di luar
fungsi maka struct akan bersifat global untuk program dimana struct tersebut berada.
Sebagai contoh, dalam bidang dua dimensi, sebuah titik akan diwakili oleh
koordinat (x,y) dimana x adalah jarak horizontal dari titik sumbu dan y adalah jarak
veritkal dari titik sumbu. x dan y adalah bilangan desimal. Untuk keperluan ini kita dapat
membuat tipe data komplek untuk mewakili sebuah titik sebagai berikut:
struct titik {
float x;
float y;
};
Untuk penggunaannya, titik dianggap sebagai tipe data baru yang digunakan untuk
mendeklarasikan variabel. Contoh sederhana untuk penggunaan struct titik di atas
pada pemrograman menggunakan C++ adalah:
152
//dalam C++
#include <iostream>
using namespace std;
struct titik {
float x;
float y;
};
main()
{
titik A;
A.x = 1.5;
A.y = -10;
Untuk mengakses elemen dari tipe data kompleks adalah dengan cara menyebutkan
nama variabel, diikuti tanda titik (.) dan nama elemen dari data kompleks. Pada contoh di
atas, untuk mengakses elemen x dari variabel A adalah A.x dan untuk mengakses
elemen y adalah A.y.
//dalam C
#include <stdio.h>
struct titik {
float x;
float y;
};
main()
{
struct titik A;
...dst
}
153
Sebagai contoh kasus untuk pemanfaatan tipe data kompleks di atas adalah untuk
menghitung jarak antara dua titik dengan menggunakan dalil pitagoras. Jika diketahui
koordinat titik A adalah (x1, y1) dan B adalah (x2, y2) maka jarak antara A dan B adalah
akar dari (x1 -x2) 2 + (y1, y2)2 .
Dalam C/C++, fungsi yang digunakan untuk menghitung pangkat suatu bilangan
adalah pow() dan fungsi untuk menghitung nilai akar dari suatu bilangan adalah
sqrt() dimana fungsi ini didefinisikan dalam header file math.h.
Flowchart sederhana untuk menghitung jarak antara dua titik A dan titik B dapat
dilihat pada gambar 43.
Start
Input
koordinat A
Input
koordinat B
Hitung jarak AB
Cetak jarak
AB
end
Contoh program untuk menghitung jarak antara dua titik menggunakan dalil
pitagoras sesuai dengan alur flowchart pada gambar 43 adalah sebagai berikut:
154
//dengan C
#include <stdio.h>
#include <math.h>
struct titik {
float x;
float y;
};
main()
{
struct titik A, B;
float jarak;
//dengan C++
#include <iostream>
#include <math.h>
using namespace std;
struct titik {
float x;
float y;
};
main()
{
titik A, B;
float jarak;
155
cout << "Masukkan koordinat B:\n nilai x: ";
cin >> B.x;
cout << " nilai y: ";
cin >> B.y;
Misalkan dimasukkan koordinat (3.5, 5.0) untuk titik A dan koordinat (2.2, -3.5) untuk
titik B, maka bentuk output dari program ini adalah:
//dengan C
void cetakTitik(struct titik x) {
printf("(%.2f, %.2f)", x.x, x.y);
}
//dengan C++
void cetakTitik(titik x) {
printf("(%.2f, %.2f)", x.x, x.y);
}
156
Dan sedikit perubahan pada fungsi main sebagai berikut:
//diubah menjadi
printf("\n\nJarak antara titik A");
cetakTitik(A);
printf(" dan titik B");
cetakTitik(A);
printf(" adalah: %.2f", jarak);
//diubah menjadi
cout <<"\nJarak antara titik A" ;
cetakTitik(A);
cout <<" dan B ";
cetakTitik(B);
cout << "adalah: " << jarak;
sehingga jika program ini dijalankan, maka pada outputnya akan dimunculkan koordinat
untuk titik A dan B sebagai berikut:
//dengan C
struct titik *pA;
//dengan C++
titik *pA;
157
pA adalah nama variabel pointer. Operator yang digunakan utuk mengakses elemen dari
struct pada variabel pointer adalah operator panah ( ->), bukan operator titik (.).
Sehingga jika diperlukam mengakses elemen x dari variabel pA caranya adalah dengan
menulis pA->x.
main()
{
struct titik A;
struct titik *pA;
A.x = 1.5;
A.y = -10;
pA = &A;
pA->x = pA->x *2;
pA->y = pA->y /2;
printf("Koordinat A: (%.2f, %.2f)\n", A.x,A.y);
}
Cara lain untuk mengakses elemen struct pada variabel pointer selain menggunakan
operator panah adalah dengan menggunakan operator bintang. Tabel 21 menunjukkan
ekuivalensi penggunaan operator titik, operator panah dan operator bintang pada variabel
bertipe data kompleks.
158
10.4 Nested Struct
Tidak hanya terdiri elemen dengan tipe data sederhana, sebuah struct juga dapat
memiliki elemen bertipe data kompleks lainnya. Cara pendefinisian struct dengan elemen
bertipe struct lainnya sama dengan cara pendefinisian struct dengan elemen bertipe data
sederhana. Perbedaannya hanyalah pada tipe data yang digunakan dalam pendeklarasian
elemen struct.
Dari contoh program sebelumnya kita sudah memiliki struct titik yang
digunakan untuk menyimpan koordinat (x,y) pada bidang dua dimensi. Selanjutnya, tipe
data titik ini dapat digunakan untuk membuat struct baru yang digunakan untuk
menyimpan koordinat (x, y, z) pada bidang 3 dimensi. Perhatikan penggalan program
berikut, yang digunakan untuk pendefinisian struct titik3D yang akan digunakan untuk
menyimpan koordinat (x,y,z).
//dengan C
//pendefinisian struct untuk koordinat (x,y,z)
struct titik3D {
struct titik d2;
float z;
};
//dengan C++
//pendefinisian struct untuk koordinat (x,y,z)
struct titik3D {
titik d2;
float z;
};
titik3D memiliki dua buah elemen yaitu d2 dan z. d2 bertipe titik dan z bertipe
float. Kemudian dideklarasikan variabel A dan B yang bertipe titik3D yang bertujuan
untuk menyimpan koordinat (x, y, z). Dalam pemrograman, elemen x dari variabel A
dapat diakses dengan A.d2.x, elemen y dengan A.d2.y dan elemen z dengan A.z.
159
Demikian pula elemen variabel B, elemen x diakses dengan B.d2.x, elemen y dengan
B.d2.y dan elemen z dengan B.z.
Modifikasi pada program untuk menghitung jarak antara dua titik sebelumnya,
yang menghitung jarak dalam bidang dua dimensi (bidang datar), menjadi penghitung
jarak pada bidang tiga dimensi (ruang) dengan memanfaatkan titik3D ini, menjadi:
//dengan C
#include <stdio.h>
#include <math.h>
struct titik {
float x;
float y;
};
struct titik3D{
struct titik d2;
float z;
};
main()
{
struct titik3D A, B;
float jarak;
160
//dengan C++
#include <iostream>
#include <math.h>
using namespace std;
struct titik {
float x;
float y;
};
struct titik3D {
titik d2;
float z;
};
main()
{
titik3D A, B;
float jarak;
Jika kemudian program ini dijalankan dan dimasukkan koordinat titik A(3, 4.5, 6) dan
koordinat titik B (-3, 5, -2.5) maka output dari program ini adalah:
161
162
BAB XI
File atau berkas digunakan sebagai tempat atau media untuk menyimpan data
secara permanen. File kemudian dapat dibaca kembali untuk mendapatkan informasi
yang ada didalamnya atau dapat juga digunanak untuk menyimpan data lain ke
dalamnya. Sederhananya, file dapat digunakan sebagai media untuk input dan output
seperti halnya monitor dan printer.
Sistem operasi memungkinkan progam untuk membaca atau menulis file. Dari
banyak jenis file yang ada, tipe file sederhana yang paling sering digunakan untuk input
dan output adalah file bertipe teks. File teks mudah ditangani dan tidak memerlukan
aplikasi khusus baik untuk membaca atau menulisnya. File teks bahkan dapat diakses
oleh program pada sistem minimalis yang terdapat pada perangkat elektronik.
Apapun jenis operasi file yang akan dilakukan, operasi file selalu terdiri dari tiga
tahapan, yaitu:
163
untuk satu tujuan operasi saja pada setiap waktu, yaitu untuk proses pembacaan, proses
penulisan atau proses penambahan.
Karena file teks hanya memproses karakter, pada dasarnya proses pembacaan dan
penulisan data dilakukan dengan cara membaca atau menulis atau karakter pada setiap
waktu. Dalam C/C++ sudah tersedia fungsi yang dapat digunakan untuk membaca atau
menulis baris dalam file teks, namun secara esensial proses ini tetap dilakukan dengan
cara memproses satu karakter pada setiap waktu. Proses per baris lebih bertujuan untuk
memudahkan dan menyingkat proses pembacaan atau penulisan data.
Tergantung dari kebutuhan sistem operasinya, karakter penanda baris baru dapat
dikonversi menjadi kombinasi enter/ganti baris bergantung pada apakah data sedang
ditulis ke, atau dibaca dari file teks. Konversi karakter lainnya juga dapat terjadi
menyesuaikan dengan kebutuhan sistem operasi dalam melakukan peyimpanan data.
Translasi ini terjadi secara transparan dan terjadi karena programmer memberikan sinyal
untuk memproses file teks.
164
Dimulai dengan perintah #include <stdio.h> lalu mendeklarasikan sejumlah
variabel yang akan digunakan, termasuk di dalamnya variabel pointer dengan tipe data
FILE. Tipe data FILE didefinisikan dalam stdio.h dan digunakan untuk
mendeklarasikan pointer file yang digunakan dalam operasi file. Sebelum ditulis, sebuah
file harus dibuka terlebih dahulu. Untuk membuka sebuah file digunakan fungsi
fopen(). Fungsi ini memerlukan dua buah argumen, yaitu nama file beserta ekstensinya
dan jenis operasi yang akan dilakukan.
Nama file dapat ditulis dalam huruf besar atau huruf kecil atau kombinasi
keduanya selama penamaan file tersebut diizinkan oleh sistem operasi. Nama file dibuat
dalam tanda petik, pada contoh program sebelumnya adalah contoh.txt. Parameter
kedua adalah jenis operasi yang akan dilakukan, berisi salah satu dari huruh w, r, atau a
yang ditulis dalam tanda petik dan harus dengan huruf kecil.
165
11.3 Membuka File Untuk Dibaca
Atribut r digunakan untuk membuka file untuk tujuan pembacaan. Penggunaan
atribut ini mengasumsikan bahwa file yang dibuka adalah berjenis teks dan file tersebut
berada pada direktori aktif ketika program dijalankan. Jika ternyata file tersebut tidak
terdapat pada direktori yang aktif maka file pointer akan diisi dengan nilai NULL.
Perhatikan contoh program berikut yang melakukan pembacaan huruf per huruf
dari file contoh.txt. Jika file tidak ditemukan maka variabel fp akan berisi nilai NULL
sehingga akan mencetak pesan "File tidak ditemukan". Namun jika file dimaksud
berhasil dibuka, maka isi dari file akan dicetak huruf demi huruf sampai ditemukan tanda
EOF (end of file) yang mengindikasikan bahwa isi file sudah habis.
if(fp != NULL )
do {
c = getc(fp);
putchar(c);
} while (c!= EOF);
else
printf("file tidak ditemukan!");
fclose(fp);
}
166
Jika diinginkan untuk membaca sejumlah huruf atau karakter sekaligus dapat
dilakukan dengan menggunakan fungsi fgets(). Fungsi ini akan mengembalikan nilai
false jika proses pembacaan data tidak berhasil, yang mengindikasikan bahwa tidak
ada lagi data yang dapat diambil. Perhatikan contoh program berikut yang menggunakan
fgets() dengan buffer sebesar 100 karakter. fgets() akan mengambil sebanyak 100
karakter sekaligus, atau sampai ditemukan simbol enter.
Misalkan dari file teks yang berhasil dibuka terdapat simbol enter pada urutan
karakter ke 35, maka fgets() hanya akan mengambil 35 karakter pertama saja
meskipun buffer yang tersedia adalah untuk 100 karakter, Namun jika tidak terdapat
simbol enter, maka jumlah yang diambil adalah sebanyak 100 karakter sekaligus.
fp = fopen("contoh.txt","r");
if(fp != NULL )
while (fgets(c, 100, fp)) {
printf("%s", c);
}
else
printf("file tidak ditemukan!");
fclose(fp);
}
167
//Membuka file untuk penambahan data dengan C
void main()
{
FILE *fp;
//tutup file
fclose(fp);
return 0;
}
Jika program ini dijalankan, maka file contoh.txt yang tadinya sudah berisi sepuluh
baris kalimat "Ini adalah contoh kalimat. Baris ke-1" sampai dengan "
Baris ke-10" akan ditambahkan satu baris kalimat "Ini adalah data yang
ditambahkan :)" pada akhir file. Sehingga isi dari file contoh.txt sekarang adalah
168
Tabel 22. Atribut untuk operasi file Bahasa C
atribut Keterangan
File dibuka hanya untuk ditulis, jika file sudah ada isi file akan
w
terhapus
File dibuka hanya untuk dibaca, jika file belum ada maka akan
r
mengembalikan nilai NULL
File dibuka hanya untuk penambahan data, jika file tidak ada maka
a
akan diciptakan file baru
w+ Sama dengan w, selain ditulis juga dapat dibaca
r+ Sama dengan r, selain dibaca juga dapat ditulis
a+ Sama dengan w, selain dapat ditulis juga dapat dibaca
Kelas stream diatur dalam hirarki yang cukup kompleks. Meski tidak diperlukan
pemahaman yang mendalam tentang hirarki ini untuk dapat melakukan pemrograman
dasar untuk input/output file, namun penjelasan secara garis besar dapat sangat
membantu. Beberapa diantaranya yang sudah sering kita gunakan adalah operator
ekstraksi >> yang merupakan anggota dari kelas istream dan operator penyisipan <<
yang merupakan anggota dari kelas ostream. Kedua kelas ini diturunkan dari kelas
ios. Kelas yang digunakan untuk menampilkan output pada monitor dan input dari
keyboard dideklrasikan dalam file header iostream.h yang digunakan hampir pada
semua program kita.
Kelas ios merupakan kelas dasar untuk seluruh hirarki input/ouput. Terdiri dari
banyak konstanta dan fungsi anggota yang digunakan pada semua jenis operasi input dan
output. istream dan ostream adalah kelas yang diturunkan dari ios dan juga
ditujukan untuk operasi input dan output. Namun dari banyak kelas yang diturunkan dari
ios tersebut, kelas yang spesifik digunakan dalam operasi file adalah ifstream
digunakan untuk tujuan input file (membaca data dari dalam file) dan ofstream untuk
tujuan output file (menulis data ke dalam file) dan fstream untuk tujuan keduanya, input
169
dan output. Kelas ifstream dan ofstream dideklarasikan dalam file header
fstream.h.
Kelas istream terdiri dari beberapa fungsi input seperti getline(), get(),
read() dan operator ekstraksi (extractor). Sedangkan beberapa fungsi dari kelas
ostream adalah put(), write() dan operator penyisipan (insertor). Secara ringkas
kelas untuk operasi file pada C++ adalah seperti ditunjukkan pada tabel 23 dan mode
operasi file ditunjukan pada tabel 24.
Kelas Keterangan
ifstream Kelas stream untuk menulis data ke dalam file
ofstream Kelas stream untuk membaca data dari dalam file
fstream Kelas stream untuk membaca/menulis data dari/ke dalam file
Mode Keterangan
ios::in Buka file untuk operasi input
ios::out Buka file untuk operasi output
ios::binary Buka file dengan modus binary
Atur posisi awal ke bagian akhir dari file
ios::ate Jika flag ini tidak diatur dengan nilai tertentu, maka posisi adalah
pada awal file
Semua operasi output diletakan di bagian akhir dari file, jika file
yang dibuka sebelumnya sudah memiliki data, maka penambahan
ios::app data dilakukan dengan tidak menghilangkan data sebelumnya. Flag
ini hanya dapat digunakan pada stream yang membuka file dengan
mode hanya untuk output.
Jika file yang dibuka untuk output sebelumnya sudah memiliki isi,
ios::trunc
maka isinya akan dihapus dan diganti dengan data yang baru.
170
terlebih dahulu sebuah objek dari kelas ifstream. Setelah itu dengan fungsi anggota
open(), buka file dengan cara memberikan nama file dan mode operasi ios::in
sebagai argumen pada fungsi open().
//deklarasi objek
ifstream nama_objek;
//membuka file
nama_objek.open("nama_file_teks.txt", ios::in)
atau membuka file bersamaan dengan deklarasi objek, dapat dilakukan dengan cara
berikut:
Untuk memeriksa apakah file berhasil dibuka, dapat menggunakan fungsi anggota
is_open(). Jika file berhasil dibuka maka is_open() akan mengembalikan nilai 1
atau true. Perhatikan dua buah contoh program berikut yang melakukan operasi yang
sama, yaitu memeriksa apakah berhasil membuka file yang diberikan atau tidak.
Perbedaannya hanya pada cara penulisan perintah untuk mendeklarasikan objek dan
membuka file.
#include <iostream>
#include <fstream>
using namespace std;
main()
{
ifstream myFile;
myFile.open("contoh.txt", ios::in);
if(myFile.is_open())
cout << "File berhasil dibuka";
else
cout << "File tidak berhasil dibuka";
myFile.close();
}
171
#include <iostream>
#include <fstream>
using namespace std;
main()
{
ifstream myFile ("contoh.txt", ios::in);
if(myFile.is_open())
cout << "File berhasil dibuka";
else
cout << "File tidak berhasil dibuka";
myFile.close();
}
Jika program ini dijalankan dan jika file contoh.txt terdapat pada direktori aktif, di layar
monitor akan ditampilkan pesan "File berhasil dibuka", namun jika file dimaksud
tidak ditemukan maka akan ditampilkan pesan "File tidak berhasil dibuka".
Setelah berhasil membuka file teks, barulah kemudian proses pengambilan data
atau membaca isi file dilakukan. Untuk membaca isi file dilakukan menggunakan fungsi
get() untuk mengambil satu buah karakter, atau getline() untuk mengambil satu
baris. Cara penggunaan fungsi get() dan getline() dengan asumsi bahwa stream
objek adalah myFile, ch adalah variabel bertipe char dan baris adalah variable
bertipe string, adalah sebagai berikut:
Pada penggunaan fungsi get(), terlebih dahulu ditulis nama objek, kemudian operator
titik dan fungsi get() dengan nama variabel char yang akan menampung hasil
pembacaan. Pada penggunaan fungsi getline(), nama objek dan variabel string
yang digunakan untuk menampung hasil pembacaan file digunakan sebagai parameter
fungsi. Sedangkan yang dimaksud dengan satu baris di sini adalah sampai ditemukan
172
simbol enter ("\n"). Baik fungsi get() maupun fungsi getline() akan
mengembalikan nilai NULL jika sudah tidak ada lagi data yang dapat diambil.
Dari contoh program pada bagian sebelumnya yang menggunakan bahasa C kita
memiliki satu buah file teks yang bernama contoh.txt yang berisi sepuluh baris
kalimat. Di sini file tersebut akan digunakan sebagai contoh untuk file input yang akan
dibaca menggunakan fungsi get() dan getline().
main()
{
char ch;
ifstream myFile ("contoh.txt", ios::in);
if(myFile.is_open()) {
cout << "File berhasil dibuka, isi file adalah:\n\n";
while(myFile.get(ch))
cout <<ch;
}
else
cout << "File tidak berhasil dibuka";
myFile.close();
}
173
Contoh program, menggunakan fungsi getline() untuk membaca file teks.
main()
{
string baris;
ifstream myFile ("contoh.txt", ios::in);
if(myFile.is_open()) {
cout << "File berhasil dibuka, isi file adalah:\n\n";
while(getline(myFile, baris))
cout <<baris; }
else
cout << "File tidak berhasil dibuka";
myFile.close();
}
Disini terlihat perbedaan output pada pembacaan data menggunakan fungsi get() dan
getline(). Output program yang menggunakan fungsi get() memperlihatkan
susunan yang sama dengan isi file aslinya, namun berbeda dengan output program yang
menggunakan fungsi getline(). Perbedaan ini disebabkan karena pada fungsi get(),
simbol enter ("\n") dianggap sebagai karakter input yang diambil, sedangkan pada
fungsi getline(), simbol enter digunakan sebagai penanda batas data yang diambil
dan simbol enter itu sendiri tidak termasuk data yang diambil oleh fungsi getline().
174
Setelah itu dengan fungsi anggota open(), buka file dengan cara memberikan nama file
dan mode operasi ios::out sebagai argumen pada fungsi open().
//deklarasi objek
ofstream nama_objek;
//membuka file
nama_objek.open("nama_file_teks.txt", ios::out)
atau membuka file bersamaan dengan deklarasi objek, dapat dilakukan dengan cara
berikut:
Untuk memeriksa apakah file berhasil dibuka, dapat menggunakan fungsi anggota
is_open(). Jika file berhasil dibuka maka is_open() akan mengembalikan nilai 1
atau true. Perhatikan dua buah contoh program berikut yang melakukan operasi yang
sama, yaitu memeriksa apakah berhasil membuka file yang diberikan atau tidak.
Perbedaannya hanya pada cara penulisan perintah untuk mendeklarasikan objek dan
membuka file.
main()
{
ofstream myFile;
myFile.open("test.txt", ios::out);
if(myFile.is_open()) {
cout << "File berhasil dibuka";
} else
cout << "File tidak berhasil dibuka";
myFile.close();
}
175
//deklarasi objek sekaligus membuka file
#include <iostream>
#include <fstream>
using namespace std;
main()
{
ofstream myFile ("test.txt", ios::out);
if(myFile.is_open()) {
cout << "File berhasil dibuka";
} else
cout << "File tidak berhasil dibuka";
myFile.close();
}
Jika file test.txt belum ada dalam direktori aktif, maka akan dibuat file baru dengan
nama test.txt. Namun jika file tersebut sebelumnya sudah ada, maka file tersebut
akan dibuka dan isi file yang sudah ada sebelumnya akan terhapus.
Sedangkan operasi penulisan file dilakukan dengan cara menulis nama objek
ofstream diikuti operator penyisipan << dan data yang akan ditulis. Menggunakan
contoh program sebelumnya, nama objek ofstream adalah myFile, maka perintah
untuk menulis ke dalam file dapat ditulis sebagai berikut:
Kalimat yang ditulis dalam tanda petik dapat juga diganti dengan nama variabel, jika
data yang akan ditulis disimpan dalam sebuah variabel. Variabel yang digunakan dapat
bertipe apapun, baik string, char, int, float dan lainnya. Namun setelah datanya
tersimpan ke dalam file teks, semua data akan disimpan sebagai string.
Berikut ini adalah contoh program yang menyimpan bilangan 100 random ke
dalam file teks. Fungsi yang digunakan untuk membangkitkan bilangan random adalah
rand() yang dideklarasikan dalam file header stdlib.h. Agar bilangan random selalu
acak setiap kali diaktifkan, maka perlu ditentukan nilai seed (bibit) yang berbeda setiap
kali program dijalankan. Untuk itu digunakan fungsi time() yang dideklarasikan dalam
file header time.h. data selanjutnya disimpan dalam file teks dengan nama
176
data100.txt. Setiap bilangan random ditulis dalam baris terpisah, untuk itu digunakan
simbol enter untuk melakukan ganti baris.
int main ()
{
int i, n=100;
srand(time(NULL));
ofstream myfile ("data100.txt");
if (myfile.is_open()) {
//Menulis bilangan random
for(i=0; i<n; i++)
myfile << rand()<<"\n";
myfile.close();
} else
cout << "File tidak dapat dibuka";
return 0;
}
Jika program ini dijalankan maka pada direktori aktif akan muncul file data100.txt
yang berisi seratus buah bilangan integer yang dihasilkan secara random.
Perhatikan pada contoh di atas, bahwa pada perintah untuk membuka file tidak
disertakan modus tujuan file tersebut diaktifkan. Hal ini tidak menjadi masalah karena
dalam C++ stream file memiliki nilai default masing-masiang ketika stream tersebut
digukanan seperti ditunjukkan pada tabel 25.
177
11.7 Implementasi ofstream dan ifstream
Untuk memperoleh pemahaman yang lebih lengkap dari penggunaan file stream
ini, perhatikanlah contoh kasus berikut:
Dari contoh kasus ini dapat disusun beberapa variasi algoritma penyelesaian, baik
secara garis besar maupun secara detail, diantaranya adalah:
Algoritma ke-1:
Algoritma ke-2:
178
Lakukan konversi string ke integer dengan menggunakan fungsi atoi() dan
simpan hasil konversi ke dalam array
Tutup file
3. Periksa setiap elemen array apakah bilangan genap atau ganjil
4. Cetak seluruh data dalam array dan cetak banyaknya bilangan genap dan bilangan
ganjil
5. Selesai
.
.
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <time.h>
using namespace std;
void simpanRandom();
void bacaRandom(int []);
void periksaBilangan(int[], int*, int*);
int main()
{
int genap=0, ganjil=0, data[100];
179
//fungsi untuk membangkitkan dan menyimpan bilangan random
//ke dalam file teks
void simpanRandom()
{
int i=0, n=100;
srand(time(NULL));
ofstream myfile ("data100.txt");
if (myfile.is_open()) {
//Menulis bilangan random
for(i=0; i<n; i++)
myfile << rand()<<"\n";
myfile.close();
} else
cout << "File tidak dapat dibuka";
myfile.close();
} else
cout << "File tidak dapat dibuka";
}
*gnp = genap;
*gjl = ganjil;
}
180
Contoh program menggunakan C
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
void simpanRandom();
void bacaRandom(int []);
void periksaBilangan(int[], int*, int*);
int main()
{
int genap=0, ganjil=0;
int i, data[100];
void simpanRandom()
{
FILE *fp;
int i, n=100;
srand(time(NULL));
181
//fungsi untuk membaca file teks dan menyimpan
//datanya ke dalam array
void bacaRandom(int arr[])
{
FILE *fp;
char c[10];
int i=0;
fp = fopen("data100.txt","r");
if(fp != NULL )
while (fgets(c, 10, fp))
arr[i++] = atoi(c);
else
printf("file tidak ditemukan!");
fclose(fp);
}
*gnp = genap;
*gjl = ganjil;
}
Jika program ini dijalankan, maka bentuk outputnya pada layar adalah:
Angka random yang muncul akan berbeda-beda setiap kali program dijalankan.
182
BAB XII
IMPLEMENTASI ALGORITMA
12.1 Sorting
Sorting merupakan proses mengatur atau menyusun sekelompok data sejenis ke
dalam urutan menaik (increasing) atau menurun (decreasing). Sorting termasuk dalam
kategori algoritma yang prosesnya terdefinisi dengan jelas. Algoritma sorting juga secara
luas dianalisa dan dipahami dengan baik. Meskipun dalam C sudah disediakan fungsi
standar qsort() untuk melakukan sorting, pendekatan sorting yang berbeda akan
memilik karakteristik yang berbeda pula. Beberapa metode sorting mungkin secara rata-
rata lebih baik dibanding metode lainnya, namun tidak ada satu metode yang sempurna
yang cocok untuk semua situasi.
Terdapat dua ketegori umum dari algoritma sorting, yaitu algortima yang
mengurutkan objek yang dapat diakses secara random seperti array dan algoritma yang
mengurutkan objek yang diakses secara sekuensial seperti halnya linked list. Dalam bab
ini kita hanya akan membahas kategori pertama saja, karena kategori ini yang paling
relevan dengan kebanyakan programmer pemula.
Hal yang sering terjadi ketika mengurutkan informasi, hanya sebagian saja dari
informasi tersebut yang digunakan sebagai kunci pengurutan. Kunci ini merupakan
bagian bagian dari data yang digunakan untuk menentukan data mana yang diletakkan
183
terlebih dahulu dan mana yang dikemudiankan. Artinya, kunci digunakan sebagai
pembanding untuk selanjutnya dilakukan pertukaran data jika diperlukan.
Sebagai contoh, misalkan kita akan melakukan sortir dengan bubble sort pada
array 5 element yang berisi angka "5 1 4 2 8". Sortir dilakukan untuk mendapatkan angka
dengan urutan dari yang terkecil hingga yang terbesar besar. Dalam setiap tahap, elemen
yang ditulis dengan huruf tebal adalah elemen yang sedang dibandingkan. Sehingga
tahapan sortir dengan bubble sort adalah:
184
Tahap pertama:
(51428) ( 1 5 4 2 8 ), lakukan pertukaran karena 5 > 1.
(15428) ( 1 4 5 2 8 ), lakukan pertukaran karena 5 > 4
(14528) ( 1 4 2 5 8 ), lakukan pertukaran karena 5 > 2
(14258) ( 1 4 2 5 8 ),
Tahap kedua:
(14258) (14258)
(14258) ( 1 2 4 5 8 ), lakukan pertukaran karena 4 > 2
(12458) (12458)
(12458) (12458)
Pada tahap ini, sebenarnya semua elemen array sudah dalam keadaan terurut,
namun algoritma bubble sort tidak mengetahui bahwa kondisi yang diinginkan sudah
tercapai, sehingga diperlukan satu tahap lagi untuk memastikan bahwa tidak ada lagi
proses pertukaran data untuk menyatakan proses sortir sudah selesai.
Tahap ketiga:
(12458) (12458)
(12458) (12458)
(12458) (12458)
(12458) (12458)
Bubble sort menghentikan prosesnya karena pada tahap ketiga ini sudah tidak
terjadi pertukaran data.
185
bubbleSort()
true
temp = arr[j]
arr[j] = arr[j+1]
arr[j+1] = temp
return
// dengan C/C++
void bubbleSort(int arr[], int n)
{
int i, j, temp;
186
Dengan memanfaatkan fungsi bacaRandom() dari bab 11 untuk input data, maka fungsi
main untuk program ini dapat dibuat sebagai berikut:
// dengan C
#include <stdio.h>
#include <stdlib.h>
main()
{
int data[100];
int i;
printf("\n\n");
for(i=0; i<100; i++)
printf("%d\t", data[i]);
}
187
Kinerja suatu algoritma biasanya diukur dengan berapa banyak suatu operasi
dilakukan. Dalam kasus sorting, operasi yang diukur kinerjanya adalah jumlah
pembandingan data serta banyaknya pertukaran data yang dilakukan. Modifikasi perlu
dilakukan pada fungsi bubbleSort() di atas untuk mengetahui kinerjanya. Yaitu
dengan menambahkan variabel jmCek untuk menghitung jumlah pembandingan dan
variabel jmTukar untuk menghitung jumlah pertukaran yang terjadi. Kedua variabel ini
dideklarasikan dalam fungsi main(), dan nilainya diubah dalam fungsi bubbleSort()
dengan cara mengirimkannya sebagai parameter alamat. Flowchart untuk fungsi
bubbleSort() yang mengakomodasi perubahan ini dapat dilihat pada gambar 44.
bubbleSort()
*jmCek = *jmCek+1
true
*jmTukar = *jmTukar+1
temp = arr[j]
arr[j] = arr[j+1]
arr[j+1] = temp
return
188
Sedikit modifikasi juga dilakukan dalam fungsi main() untuk mencetak jumlah data,
jumlah pembandingan dan jumlah pertukaran data yang dilakukan. Perubahan program
sesuai dengan flowchart pada gambar 44 adalah sebagai berikut:
// dengan C
#include <stdio.h>
#include <stdlib.h>
main()
{
int data[100], n=100;
int i, jmCek=0, jmTukar=0;
if(arr[j]>arr[j+1]) {
//simpan jumlah pertukaran
*jmTukar = *jmTukar + 1;
//lakukan pertukaran
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
189
Contoh output dari program ini adalah
Pada layar output terlihat bahwa jumlah pembandingan untuk melakukan sortir terhadap
100 data adalah sebanyak 5050 kali. Jumlah pembandingan ini dapat dihitung dengan
menggunakan rumus n2/2 + n/2 dimana n adalah jumlah data. Sehingga untuk data
sebanyak 100 maka perhitungannya menjadi 1002/2 + 100/2=5050. Bayangkan
jumlah data yang disortir sebanyak 100000 atau lebih, maka jumlah pembandingan yang
diperlukan adalah sebanyak 1000002/2 + 100000/2=5000050000. Jika diasumsikan
untuk melakukan satu kali pembandingan data diperlukan waktu sebesar seperseribu
detik, maka untuk melakukan sortir dengan bubble sort setidaknya memerlukan waktu
5000050 detik. Inilah alasannya mengapa dikatakan kinerja bubble sort akan menurun
drastis seiring dengan terjadinya peningkatan jumlah data yang dikerjakan.
Algoritma ini bekerja dengan cara mencari nilai terkecil (atau terbesar,
tergantung urutan yang diinginkan) yang ada dalam array. Pertukaran dilakukan pada
190
elemen paling kiri setelah data terkecil dari seluruh elemen ditemukan. Jika tidak ada
data yang lebih kecil dari data yang berada pada posisi paling kiri maka proses
pertukaran tidak dilakukan. Setelah itu, proses dilanjutkan dengan data pada posisi
terkecil berikutnya. Bagian kiri yang sudah terurut ini adalah bagian yang sudah tersortir
dan sisanya adalah data yang tidak tersortir.
Berikut adalah contoh penggunaan selection sort pada array lima elemen dengan
data berikut:
Berdasarkan algoritma ini, dan dengan menambahkan fungsi untuk menghitung jumlah
pembandingan dan jumlah penukaran data, maka dapat dibangun flowchart seperti pada
gambar 45.
191
selectionSort()
A
iMin = i
*jmCek = *jmCek+1
true
*jmTukar = *jmTukar+1
arr[iMin] > arr[j]
temp = arr[ i ]
arr[ i ] = arr[ iMin ]
true
arr[ iMin ] = temp
iMin = j
B i
j
B A return
Program untuk selection sort mengikuti flowchart pada gambar 45, dengan data
yang diambil dari file data100.txt dan dibaca menggunakan fungsi bacaRandom()
dari bab 11 adalah sebagai berikut:
#include <stdio.h>
#include <stdlib.h>
main()
{
int data[100], n=100;
int i, jmCek=0, jmTukar=0;
192
//lakukan sortir dengan selection sort
selectionSort(data, n, &jmCek, &jmTukar);
if(arr[iMin]>arr[j])
iMin = j;
}
if(i != iMin) {
//simpan jumlah pertukaran
*jTukar = *jTukar + 1;
//lakukan pertukaran
temp = arr[i];
arr[i] = arr[iMin];
arr[iMin] = temp;
}
}
}
Proses pembandingan dalam selection sort yang dilakukan dalam loop j bertujuan untuk
mengambil nilai indeks dari array yang menyimpan data yang lebih kecil, Indeks untuk
data terkecil ini diperoleh setelah loop j selesai dikerjakan. Selanjutnya diperiksa apakah
nilai indeks terkecil (iMin) ini berbeda dengan nilai indeks pada loop i (nilai i), jika
193
benar maka lakukan pertukaran data, jika tidak maka lanjutkan sampai nilai i sama
dengan n-1. Output dari program ini jika dijalankan adalah
Data yang disortir adalah ada yang sama yang digunakan dalam bubble sort pada bagian
sebelumnya. Pada layar output terlihat bahwa jumlah pembandingan untuk melakukan
sortir terhadap 100 data adalah sebanyak 4950 kali. Jumlah pembandingan ini dapat
dihitung dengan menggunakan rumus n2/2 - n/2 dimana n adalah jumlah data.
Sehingga untuk data sebanyak 100 maka perhitungannya menjadi 1002/2 -
100/2=4950.
Gambar 46 mengilustrasikan proses dari insertion sort. Pada awalnya array berisi
9 elemen data, berturut-turut yaitu: 54, 26, 93, 17, 77, 31, 44, 55, 20.
194
Asumsi, 54 adalah elemen
data yang sudah terurut
sisipkan 26
sisipkan 93
sisipkan 17
sisipkan 77
sisipkan 31
sisipkan 44
sisipkan 55
sisipkan 20
Mula-mula diasumsikan bahwa subarray berisi satu elemen yang sudah terurut
(posisi 0). Pada setiap pengujian selanjutnya, untuk setiap elemen antara posisi 1 sampai
n-1, elemen ini akan dibandingkan dengan elemen yang sudah ada pada subarray yang
sudah terurut tadi. Pemeriksaan dilakukan dari kanan ke kiri. Jika ditemukan elemen
yang lebih besar dari elemen yang sedang diperiksa, maka elemen tersebut digeser ke
kanan, dan dilakukan terus-menerus hingga ditemukan tempat yang cocok untuk elemen
yang sedang diperiksa.
195
proses berhenti karena 26 tidak lebih besar dari 31, lalu 31 diletakkan pada tempat yang
kosong setelah angka 26, sehingga sekarang subarray berisi enam elemen yang sudah
terurut.
31 akan disisipkan ke
bagian yang sudah terurut
Dari ilustrasi di atas, kemudian dapat dibangun flowchart untuk insertion sort
seperti dapat dilihat pada gambar 48. Loop i digunakan untuk membaca array dari
elemen ke-1 sampai elemen ke n-1, hal ini dikarenakan elemen pada posisi ke-0
dianggap sebagai subarray yang sudah terurut. Kemudian indeks i disimpan ke dalam
variabel pos, dan data yang terdapat pada posisi ke-pos dalam hal ini arr[pos]
disimpan dalam variabel nilai.
Loop while digunakan untuk mencari posisi untuk tempat penyisipan, yaitu
dengan cara memeriksa kondisi apakah pos>0 dan arr[pos-1] > nilai. Jika
kondisi ini terpenuhi berarti ditemukan data pada subarray yang lebih besar dari nilai
yang sedang diperiksa, dengan demikian dilakukan pergeseran data. Jika loop while
berhenti karena pos=0, berarti nilai adalah yang elemen terkecil dari subarray yang
sudah terurut.
196
insertionSort()
pos = i
nilai = arr[ pos ]
pos>0 &&
arr[pos-]>nilai
true
*jTukar = *jTukar+1
arr[pos] = arr[pos-1]
pos--
arr[pos] = nilai
return
Seperti pada contoh program bubble sort dan selection sort, di sini juga akan
digunakan fungsi bacaRandom() untuk membaca file data100.txt yang isinya
kemudian disimpan dalam array data. Data yang akan diproses dengan insertion sort
berjumlah 100 data, yang merupakan data yang sama dengan yang digunakan pada dua
metoda sorting sebelumnya. Output yang ditampilkan adalah data yang sudah tersortir
saja, ditambah informasi tentang jumlah pembandingan dan jumlah pertukaran yang
197
terjadi. Berikut adalah contoh program yang dibangun mengacu pada flowchart pada
gambar 48.
#include <stdio.h>
#include <stdlib.h>
main()
{
int data[100], n=100;
int i, jmCek=0, jmTukar=0;
198
Output pada layar jika program ini dijalankan adalah sebagai berikut:
Bubble sort, selection sort dan insertion sort merupakan algortima sorting
sederhana yang mudah dipelajari dan dipahami. Meski dengan teknik tertentu kinerja
dari ketiga jenis sorting ini masih dapat ditingkatkan, namun tetap tidak cocok untuk
jumlah data besar. Pemahaman nonsep dasar yang baik tentang pengurutan dan
pertukaran data yang dijelaskan dalam sorting sederhana ini akan sangat membantu
dalam memahami dan menggunakan metoda sorting lain yang lebih cepat dan efisien,
12.2 Searching
Searching merupakan aktivitas untuk melokalisasi atau menemukan data atau
informasi tertemtu diantara dalam kumpulan data atau informasi yang dimiliki. Ada
metode yang cocok untuk melakukan pencarian data pada kumpulan data yang tidak
terurut sementara metode yang lainnya untuk data yang sudah terurut. Yang dimaksud
kumpulan data disini adalah array yang menyimpan sekelompok data sejenis.
Untuk menemukan informasi dalam array yang tidak tersortir diperlukan metode
opencarian secara sekuensial yang membaca array mulai dari elemen pertama dan
berhenti jika data yang dicari sudah ditemukan atau sampai elemen array terakhir. Selain
dapat digunakan pada data yang tidak terurut, metode sekuensial juga dapat digunakan
untuk melakukan pencarian pada kumpulan data yang sudah terurut. Namun jika datanya
sudah terurut kita dapat menggunakan binary search, yang akan melokalisasi data dengan
lebih cepat.
199
12.2.1 Sequential Search
Sequntial search merupakan metoda pencarian data yang sangat sederhana.
Prinsip kerjanya adalah dengan cara mencocokkan data atau kunci yang dicari dengan
data yang tersimpan dalam array mulai dari elemen pertama sampai data ditemukan atau
sampai array berakhir, yang berarti data tidak ditemukan.
Misalkan data berada dalam array bernama data[] dan variabel dcari berisi
data yang sedang dicari, berikut ini adalah contoh fungsi untuk melakukan sequential
search.
#include <stdio.h>
#include <stdlib.h>
main()
{
int data[100], i, dcari;
return 0;
}
200
Array data[] diisi dengan data integer yang diambil dari file data100.txt
yang dibaca menggunakan fungsi bacaRandom(). Kemudian data yang dicari
dimasukkan melalui keyboard dan disimpan dalam variabel dcari. Pencarian dilakukan
dengan cara memanggil fungsi seqSearch() yang akan mengembalikan nilai 1 jika
data yang dicari terdapat dalam array dan nilai 0 jika data tidak ditemukan. Fungsi
seqSearch() memerlukan dua buah parameter untuk melakukan tugasnya, parameter
pertama adalah nama array dan parameter kedua adalah data yang dicari.
Cara kerjanya metode ini adalah dengan memeriksa elemen yang berada di
tengah array. Posisi tengah array didapatkan dengan cara membagi panjang array dengan
2. Jika panjang array adalah n, maka posisi tengah array adalah n/2 untuk n bernilai
genap dan n/2+1 untuk n bernilai ganjil.
Jika nilai elemen tengah ini lebih besar dari pada data yang dicari berarti data
berada pada separuh bagian pertama dari array, sebaliknya jika nilai elemen ini lebih
201
kecil berarti data yang dicari berada pada separuh bagian kedua dari array. Ulangi
prosedur ini sampai data ditemukan atau tidak ada lagi elemen yang dapat diperiksa.
Sebagai contoh, misalkan akan dicari angka 4 pada array berisi data
1 2 3 4 5 6 7 8 9
binary search pertama kali memeriksa elemen yang berada ditengah, yakni 5. Karena
nilainya lebih besar dari pada 4 maka pencarian dilanjutkan pada separuh bagian pertama
dari array, yaitu
1 2 3 4 5
elemen yang berada ditengah sekarang adalah 3, yang berarti lebih kecil dari 4, maka
separuh bagian pertama diabaikan dan dilanjutkan dengan memeriksa separuh bagian
kedua yang tersisa, yaitu
4 5
elemen yang berada ditengah sekarang adalah 4, yang berarti data yang dicari sudah
ditemukan.
202
Sebelum fungsi binarySearch() dapat digunakan, terlebih dahulu data harus terurut,
untuk itu digunakan fungsi selectionSort() untuk melakukan sorting. Dan fungsi
bacaRandom() digunakan untuk membaca data dari file teks sebelum proses sorting
dilakukan. Berikut adalah fungsi main yang digunakan untuk memanfaatkan
binarySearch()
#include <stdio.h>
#include <stdlib.h>
main()
{
int data[100], i, dcari;
int jmCek=0, jmTukar=0;
Jika program ini dijalankan, kemudian dimasukkan angak 12294 sebagai angka yang
dicari, maka output dari program ini adalah
203
204
Daftar Pustaka
Schildt, Herbet, C The Complete Reference, 4th Edition, The McGraw-Hill Companies,
2000
Vine, Michael, C Programming for The Absolute Beginner, 2nd Edition, Thomson
Course Technology, Boston, 2008
205