Menukar Isi Dua Variabel (ed. 2) 1/5
Lecture Notes
Menukar Isi Dua Variabel Thompson Susabda Ngoen
Algoritma dan Pemrograman
Salah satu kegiatan pengolahan data adalah menukar isi dua variabel, misalnya pada sorting (proses pengurutan). Terdapat beberapa cara untuk menukar isi variabel, yang dapat kita kelompokkan menjadi dua: dengan pemindahan data dan dengan proses aritmetika terhadap data. Pertukaran Isi Dengan Pemindahan Data Cara ini kita tiru dari kehidupan sehari-hari. Untuk menukar isi wadah A dan B, mula-mula kita mengeluarkan isi wadah A dan menaruhnya di tempat lain misalnya wadah C. Kemudian isi wadah B dipindahkan ke wadah A. Terakhir isi wadah C (yang semula berasal dari wadah A) dipindahkan ke wadah B. Pada cara ini kita meggunakan variabel perantara, bisa dengan satu variabel perantara atau dua variabel perantara. Gambar 1 mengilustrasikan proses menukar isi variabel a dan b. Pertukaran pada gambar kiri menggunakan dua variabel perantara, yaitu C dan D. Pertukaran pada gambar kanan menggunakan satu variabel perantara yaitu C saja.
c = a;
c = a;
d = b;
a = b;
a = d;
b = c;
b = c;
Gambar 1. Pertukaran Data Dengan Bantuan Dua dan Satu Variabel Perantara
Proses pertukaran isi variabel dengan bantuan satu variabel perantara tentu lebih efisien baik dari segi kebutuhan memori maupun kecepatan proses walaupun tidak signifikan. Pertukaran Isi Dengan Proses Aritmetika 1. Dengan Penjumlahan 1 2 3 4 5 6
# include <stdio.h> int main () { int a, b, tambah;
123456789012345 1 30 100 2 100 30 3
scanf("%d %d", &a, &b); tambah = a + b;
INSTITUT BISNIS dan INFORMATIKA INDONESIA
Menukar Isi Dua Variabel (ed. 2) 2/5
7 8 9 10 11
a = tambah - a; b = tambah - a; printf("%d %d\n", a, b); return 0; }
Perhatikan instruksi baris ke-7. Instruksi a = tambah - a sebenarnya menghitung a = (a + b) - a atau a bernilai b. Instruksi baris ke-8: b = tambah - a menyebabkan b = (a + b) - b = a. 2. Dengan Pengalian 1 2 3 4 5 6 7 8 9 10 11
# include <stdio.h> int main () { int a, b, kali;
123456789012345 1 40 50 2 50 40 3
scanf("%d %d", &a, &b); kali = a * b; a = kali / a; b = kali / a; printf("%d %d\n", a, b); return 0; }
Perhatikan instruksi baris ke-7. Instruksi a = kali / a sebenarnya menghitung a = (a * b) / a atau a bernilai b. Instruksi baris ke-8: b = kali / a menyebabkan b = (a * b) / b = a. 3. Dengan Pengurangan 1 2 3 4 5 6 7 8 9 10 11 12 13 14
# include <stdio.h> int main () { int a, b, kurang;
123456789012345 1 15 70 2 70 15 3
scanf("%d %d", &a, &b); kurang = abs(a - b); if (a > b) { a -= kurang; b += kurang; } else { a += kurang; b -= kurang; } printf("%d %d\n", a, b); return 0; }
4. Dengan Penjumlahan, Tanpa Variabel Perantara Pada cara pertama hasil penjumlahan ditampung dengan sebuah variabel lain. Program berikut menampung hasil penjumlahan di salah satu variabel asal. 1 2 3 4 5 6 7 8 9
# include <stdio.h> int main () { int a, b;
123456789012345 1 15 70 2 70 15 3
scanf("%d %d", &a, &b); a = a + b; b = a - b; a = a - b; printf("%d %d\n", a, b);
INSTITUT BISNIS dan INFORMATIKA INDONESIA
Menukar Isi Dua Variabel (ed. 2) 3/5
10 11
return 0; }
Perhatikan instruksi baris ke-7. Instruksi b = a - b sebenarnya menghitung b = (a + b) - b atau b bernilai a. Instruksi baris ke-8: a = a - b menyebabkan a = (a + b) - a = b. Tabel 1. Pertukaran Data Dengan Penjumlahan Tanpa Bantuan Variabel Perantara Instruksi
Isi Variabel a b 15 90 90 75
a = a + b; b = a - b; a = a - b;
75 75 15 15
5. Dengan Pengalian, Tanpa Variabel Perantara Berbeda dengan program 4, program berikut mengalikan kedua variabel asal dan meletakkan hasilnya di salah satu variabel asal tersebut. 1 2 3 4 5 6 7 8 9 10 11
# include <stdio.h> int main () { int a, b;
123456789012345 1 70 15 2 15 70 3
scanf("%d %d", &a, &b); a = a * b; b = a / b; a = a / b; printf("%d %d\n", a, b); return 0; }
Perhatikan instruksi baris ke-7. Instruksi b = a / b sebenarnya menghitung b = (a * b) / b atau b bernilai a. Instruksi baris ke-8: a = a / b menyebabkan a = (a * b) / a atau a bernilai b. Tabel 2. Pertukaran Data Dengan Perkalian Tanpa Bantuan Variabel Perantara Instruksi a = a * b; b = a / b; a = a / b;
Isi Variabel a b 70 1050 1050 15
15 15 70 70
Ada hal yang luput dari pengamatan kita pada program 4 dan 5. Apakah kedua program masih memberikan hasil yang benar jika nilai yang diproses mendekati nilai maksimum? Seperti kita ketahui setiap tipe data pada bahasa pemrograman mempunyai batas nilai minimum dan maksimum. Perancang bahasa C tidak menetapkan jumlah byte yang pasti untuk sebuah variabel bertipe data tertentu melainkan hanya menetapkan jumlah byte minimum. Implementor bahasa (pembuat compiler) diberi kebebasan untuk menentukan ukuran byte suatu tipe data. Compiler Turbo C++ 3.0 dan Borland C++ 3.1 yang dirancang untuk digunakan di atas sistem operasi MSDOS (yang menggunakan sistem pengalamatan memori 16 bit)
INSTITUT BISNIS dan INFORMATIKA INDONESIA
Menukar Isi Dua Variabel (ed. 2) 4/5
menggunakan memori dua byte untuk menampung data bilangan bulat (int). IDE Dev-C++ 4.9.9.2 yang berjalan di atas sistem operasi Windows XP menggunakan compiler GCC yang mengalokasi memori 4 byte untuk menampung data bilangan bulat. Compiler menyediakan sebuah berkas header bernama limits.h. Pada berkas ini dideklarasikan beberapa macro yang memberi nama kepada nilai terkecil dan terbesar, misalnya INT_MIN dan INT_MAX. Jika nilai yang dimasukkan ke dalam sebuah variabel lebih besar daripada daya tampung variabel tersebut (yang sesuai dengan tipe data variabel tersebut) maka akan menyebabkan overflow. Pada cara keempat apabila kedua variabel a dan b diberi nilai mendekati nilai maksimum maka akan menimbulkan overflow ketika dijumlahkan. Bilangan terbesar yang dapat ditampung variabel bertipe char pada bahasa C adalah 127. Hasil run program berikut masih benar meskipun terjadi overflow. Bagaimana menjelaskan kejanggalan ini? # include <stdio.h> int main () { char a = 50, b = 100; printf("%d %d\n", a, b); a = a + b; // overflow b = a - b; a = a - b; printf("%d %d\n", a, b); return 0;
123456789012345 1 50 100 2 100 50 3 4 5 6 7 8 9
}
Untuk menjelaskan kejanggalan ini kita perlu memahami cara komputer merepresentasi bilangan. Komputer merepresentasi (menyimpan di memori) bilangan baik integer maupun character dengan format binary digit 2’s complement. Nilai absolut bilangan dikonversi menjadi digit biner. Jika bilangan bernilai negatif maka ubah semua bit terkiri menjadi 1 dan sebaliknya, kemudian tambahkan nilai 1. Sebagai contoh 50 direpresentasi dengan 00110010 dan -50 direpresentasi dengan 11001110. Komputer menginterpretasi bit dengan cara yang sama. Bit yang paling kiri menandakan jenis bilangan, 0 berarti positif dan 1 berarti negatif. Jika bit terkiri bernilai 0 maka nilai bilangan adalah hasil konversi langsung. Jika bit terkiri bernilai 1 maka ubah semua bit 0 menjadi 1 dan sebaliknya, kemudian tambahkan nilai 1. Digit biner 11001110 akan diubah menjadi 00110001 lalu menjadi 00110010 yang artinya bernilai -50. Tabel 3. Representasi Bilangan Instruksi
a = a + b; b = a - b; a = a - b;
Representasi Internal a b
Isi Variabel a b
00110010 10010110 10010110 01100100
50 -106 -106 100
01100100 01100100 00110010 00110010
100 100 50 50
Instruksi a = a + b menyebabkan a bernilai 150, direpresentasikan dengan 10010110 yang juga diartikan sebagai -106. Instruksi b = a - b menyebabkan b bernilai -206, direpresentasi dengan 00110010 yang juga diartikan sebagai 50. Instruksi a = a - b menyebabkan a bernilai -156, direpresentasi dengan 01100100 yang juga diartikan sebagai 100. Bagaimana dengan program kelima? Hasil perkalian variabel a dan b mungkin menyebabkan overflow sehingga bernilai negatif. Jika nilai variabel a dan b relatif besar
INSTITUT BISNIS dan INFORMATIKA INDONESIA
Menukar Isi Dua Variabel (ed. 2) 5/5
maka hasil perkaliannya bisa menyebabkan over-overflow, bernilai positif kembali tetapi salah. Tabel 4 menyajikan hasil perkalian berbagai nilai yang ditampung dengan variabel bertipe char dan int. Perkalian dua nilai positif yang menyebabkan overflow menghasilkan nilai negatif. Bila nilai negatif ini dibagi dengan nilai semula yang positif tentu memberikan hasil yang salah. Tabel 4. Overflow Pada Perkalian Berbagai Nilai a
b
a*b char int
5 10 15 20 25 30
15 15 15 15 15 15
75 -106 -31 44 119 -62
75 150 225 300 375 450
Virtual Atau Faktual? Apakah kelima cara terakhir ini dapat diterapkan di dalam kehidupan nyata? Misalkan kita mempunyai dua kardus yang masing-masing di dalamnya terdapat sejumlah buku. Isi kedua kardus dapat saling ditukar jika total buku kedua kardus dapat muat di dalam satu kardus, dengan perkataan lain tidak menimbulkan overflow. Anda mempunyai dua gelas. Di dalam kedua gelas terdapat cairan sejenis. Dengan asumsi total volume cairan kedua gelas dapat ditampung di dalam satu gelas, dapatkan Anda menukar isi kedua gelas tersebut tanpa bantuan gelas lain sebagai perantara? Rasanya tidak dapat kecuali jika pada kedua gelas tersebut terdapat skala ukuran. Di manakah “skala ukuran” pada program komputer? Jika kita mempunyai dua larik karakter, yang bertama berisi string algoritma dan yang kedua berisi string pemrograman. Kita ingin menukar isi kedua variabel ini tanpa bantuan variabel lain. Apa hasil penjumlahan algoritma dan pemrograman? Pada salah satu folder di komputer Anda terdapat dua berkas, sebut saja yang pertama bernama struktur.c dan yang kedua bernama data.c. Nama kedua berkas ini mau saling ditukar. Apakah hal ini dapat dilakukan tanpa bantuan nama berkas lain, maksudnya misalkan salah satunya diubah dulu menjadi nama.c?
INSTITUT BISNIS dan INFORMATIKA INDONESIA