void2

Pada Bagian 1 telah dibahas mengenai dasar proses pertukaran data yang disertai beberapa contoh program untuk mempraktekkannya. Contoh program pertama menukarkan nilai antara dua variabel integer dan contoh program kedua adalah contoh fungsi swap(int *a, int *b) yang berfungsi menukar nilai antar dua variabel integer yang bersifat lokal maupun global.

Pada Bagian 2 ini kita akan membahas lebih lanjut tentang teknik pertukaran data dengan membuat beberapa program. Dengan program-program tersebut diharapkan kita bisa lebih memahami teknik-teknik pertukaran data, khususnya menggunakan bahasa C/C++.

Program yang pertama adalah program pertukaran data antara variabel string atau array of char. Kode program dalam tulisan ini telah diuji menggunakan kompiler Borland C/C++ 5.5, MinGW 2.95, MinGW 4.8.1, Digital Mars 8.57 dan Open Watcom 1.9. Dan juga diuji menggunakan interpreter Ch versi 7.0. Nah, berikut adalah kode programnya.

/*
   stringswap.c
   chandra@teknikelektrolinks.com
*/
#include <stdio.h>
#include <string.h>

int main()
{
   char string1[50];
   char string2[50];
   char tmp[50];

   strcpy(string1, "Ini STRING-1");
   strcpy(string2, "Ini STRING-2 yang lebih panjang");
   printf("Data SEBELUM dipertukarkan...\n");
   printf("string1 = %s\n", string1);
   printf("string2 = %s\n\n", string2);
   printf("Lebar string1 = %d\n", strlen(string1));
   printf("Lebar string2 = %d\n\n", strlen(string2));

   //swapstring
   strcpy(tmp, string1);
   strcpy(string1, string2);
   strcpy(string2, tmp);

   printf("Data SETELAH dipertukarkan...\n");
   printf("string1 = %s\n", string1);
   printf("string2 = %s\n\n", string2);
   printf("Lebar string1 = %d\n", strlen(string1));
   printf("Lebar string2 = %d\n\n", strlen(string2));

   return 0;
}

Hasil running program di atas adalah sebagai berikut:

image

Nampak bahwa nilai variabel string1 telah bertukar dengan nilai variabel string2. Kebetulan screenshot di atas adalah hasil running program menggunakan interpreter Ch.

Pada contoh di atas, variabel string1, string2 dan tmp dideklarasikan sebagai array-of-char dengan jumlah karakter 50. Proses pertukaran data menggunakan fungsi pemanipulasi string strcpy(char *tujuan, const char *sumber). Fungsi ini merupakan fungsi asli bahasa C sehingga kode program di atas sukses dikompilasi dengan semua kompiler dan Ch Interpreter.

Nilai variabel string1 dan string2 sukses dipertukarkan meskipun panjang string-nya tidaklah sama. Jadi meskipun lebar string tidak sama, akan tetapi lebar variabelnya (50 karakter) masih melebihi lebar masing-masing string (12 dan 31 karakter).

Sedikit modifikasi program dapat dilakukan untuk kompiler modern seperti kompiler C++ (MinGW) 4.8.1. Ganti tiga baris perintah strcpy() dengan assignment yang lebih sederhana sebagai berikut:

tmp = string1;
string1 = string2;
string2 = tmp;

Lebih gampang dan lebih mudah dimengerti. Cara ini berlaku pada kompiler C++ yang telah menerapkan fitur operator-overloading sehingga operator ‘=’Β  bisa digunakan sebagai string assignment.

Sekarang mari kita sedikit bereksperimen. πŸ˜€

Ketiga variabel array-of-char di atas memiliki dimensi yang sama yakni 50 karakter. Nah, apa yang terjadi jika string1 dan tmp kita ganti dimensinya menjadi lebih kecil sehingga tidak dapat menampung data string yang dipertukarkan sebagai berikut.

char string1[20];
char string2[50];
char tmp[10];

Dari hasil kompilasi menggunakan berbagai kompiler yang telah disebutkan di atas, maka modifikasi program tetap berjalan mulus saja tanpa kesalahan. Namun terkadang juga menghasilkan kesalahan yang tidak terduga. Kondisi semacam ini dinamakan buffer overflow atau buffer overrun dan sudah seharusnya dihindari.

Namun demikian, interpreter Ch memberikan hasil yang sedikit berbeda. Berikut adalah hasil interpretasi Ch pada kode program yang telah dimodifikasi di atas.

image

Interpreter Ch memberikan pesan kesalahan bahwa lebar s1 kurang dari s2, akan tetapi fungsi tetap dijalankan dan menghasilkan string yang terpotong sesuai dengan lebar variabel masing-masing. Jadi dalam hal ini interpreter Ch lebih aman. Mungkin karena Ch adalah interpreter yang mengecek dan mengeksekusi perintah baris per baris. Entahlah… πŸ™‚

Bukan C jika hanya bisa menyelesaikan persoalan dengan satu cara. Bahasa C adalah bahasa pemrograman paling fleksibel yang memberikan kebebasan penuh kepada programmer, namun sekaligus bahasa pemrograman yang paling rawan bug jika tidak berhati-hati.

Program Dengan Fungsi strdup()

Untuk mengatasi kekurangan fungsi strcpy(), maka bisa digunakan fungsi strdup() yang berfungsi menduplikasi string dengan sebelumnya mengalokasikan memori sesuai dengan lebar string yang akan diduplikasi. Dengan menggunakan fungsi strdup(), maka programmer berkewajiban untuk membebaskan memori yang telah terpakai dengan fungsi free().

Berikut adalah kode program menggunakan fungsi strdup(). Pada program ini variabel string1, string2 dan tmp dialokasikan secara dinamis.

/*
   stringswap.c
   chandra@teknikelektrolinks.com
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
   char *string1;
   char *string2;
   char *tmp;

   string1 = strdup("Ini STRING-1");
   string2 = strdup("Ini STRING-2 yang lebih panjang");
   
   printf("Data SEBELUM dipertukarkan...\n");
   printf("string1 = %s\n", string1);
   printf("string2 = %s\n\n", string2);
   printf("Lebar string1 = %d\n", strlen(string1));
   printf("Lebar string2 = %d\n\n", strlen(string2));

   //swapstring
   tmp = strdup(string1);
   string1 = strdup(string2);
   string2 = strdup(tmp);

   printf("Data SETELAH dipertukarkan...\n");
   printf("string1 = %s\n", string1);
   printf("string2 = %s\n\n", string2);
   printf("Lebar string1 = %d\n", strlen(string1));
   printf("Lebar string2 = %d\n\n", strlen(string2));
   
   free(string1);
   free(string2);
   free(tmp);

   return 0;
}

Hasil eksekusi program adalah sebagai berikut.

image

Sangat menarik, bukan? πŸ˜€

Program Spesifik Versi C++

Bagaimanakah contoh program di atas jika ditulis secara spesifik menggunakan C++ ? Berikut ini adalah program versi C++ dari program di atas.

/*
   stringswap.cpp
   chandra@teknikelektrolinks.com
*/

#include <iostream.h>
#include <string.h>

using namespace std;

int main()
{
   string string;
   string string2;
   string tmp;

   string1 = "Ini STRING-1";
   string2 = "Ini STRING-2 yang lebih panjang";

   cout << "Data SEBELUM dipertukarkan..." << endl;
   cout << "string1 = " << string1 << endl;
   cout << "string2 = " << string2 << endl << endl;
   cout << "Lebar string1 = " << string1.length() << endl;
   cout << "Lebar string2 = " << string2.length() << endl << endl;

   tmp = string1;
   string1 = string2;
   string2 = tmp;

   cout << "Data SETELAH dipertukarkan..." << endl;
   cout << "string1 = " << string1 << endl;
   cout << "string2 = " << string2 << endl <<  endl;
   cout << "Lebar string1 = " << string1.length() << endl;
   cout << "Lebar string2 = " << string2.length() << endl;

   return 0;
}

Alih-alih menggunakan array-of-char, pada program C++ di atas menggunakan object string untuk mendeklarasikan variabel string1, string2 dan tmp. Kita juga bisa melakukan pertukaran data variabel string secara langsung menggunakan operator assignment ‘=’.

Berikut adalah hasil eksekusi program spesifik C++ yang saya kompilasi menggunakan CodeBlocks MinGW 4.8.1.

image

Nah, selanjutnya kita akan membuat fungsi pertukaran data untuk variabel tipe string.

Fungsi yang pertama adalah untuk contoh program yang paling atas, yakni yang menggunakan variabel string1 dan string2 sebagai array-of-char yang dideklarasikan dengan lebar data 50 karakter. Berikut adalah program selengkapnya.

/*
   stringswap.c
   chandra@teknikelektrolinks.com
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void swapstr(char *s1, char *s2)
{
   char *tmp = s1;
   s1 = s2;
   s2 = tmp;
}

int main()
{
   char string1[50];
   char string2[50];

   strcpy(string1, "Ini STRING-1");
   strcpy(string2, "Ini STRING-2 yang lebih panjang");

   printf("Data SEBELUM dipertukarkan...\n");
   printf("string1 = %s\n", string1);
   printf("string2 = %s\n\n", string2);
   printf("Lebar string1 = %d\n", strlen(string1));
   printf("Lebar string2 = %d\n\n", strlen(string2));

   swapstr(&string1, &string2);

   printf("Data SETELAH dipertukarkan...\n");
   printf("string1 = %s\n", string1);
   printf("string2 = %s\n\n", string2);
   printf("Lebar string1 = %d\n", strlen(string1));
   printf("Lebar string2 = %d\n\n", strlen(string2));

   return 0;
}

Fungsi swapstr() dipanggil dengan cara swapstr(&string1, &string2). Operator pointer & didepan variabel string1 dan string2 berarti mengirimkan alamat penunjuk string1 dan string2, bukan nilainya.

Pada fungsi swapstr(), dideklarasikan sebuah variabel bantu bertipe string pointer char *tmp yang diinisialisasi dengan alamat dari string1 (yang dilewatkan melalui parameter s1). Sehingga tmp akan menunjuk alamat memori yang berisi data “Ini STRING-1”.

Selanjutnya, perintah s1 = s2; berfungsi meng-copyΒ s2 ke s1 sehingga setelah perintah ini dieksekusi s1 akan menunjuk alamat memori yang berisi data “Ini STRING-2 yang lebih panjang”. Dengan kata lain, string1 akan berisi “Ini STRING-2 yang lebih panjang”.

Perintah berikutnya, s2 = tmp; berfungsi meng-copy alamat tmp ke s2 yang mana berarti string2 akan berisi “Ini STRING-1”. Dengan demikian, maka proses pertukaran data telah selesai.

Fungsi di atas hanya berlaku pada variabel bertipe array-of-char. Bagaimanakah fungsi untuk variabel bertipe string pointer? Berikut adalah kode contoh programnya.

/*
   stringswap.c
   chandra@teknikelektrolinks.com
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void swapstr(char **s1, char **s2)
{
   char *tmp = *s1;
   *s1 = *s2;
   *s2 = tmp;
}

int main()
{
   char *string1;
   char *string2;

   string1 = strdup("Ini STRING-1");
   string2 = strdup("Ini STRING-2 yang lebih panjang");

   printf("Data SEBELUM dipertukarkan...\n");
   printf("string1 = %s\n", string1);
   printf("string2 = %s\n\n", string2);
   printf("Lebar string1 = %d\n", strlen(string1));
   printf("Lebar string2 = %d\n\n", strlen(string2));

   swapstr(&string1, &string2);

   printf("Data SETELAH dipertukarkan...\n");
   printf("string1 = %s\n", string1);
   printf("string2 = %s\n\n", string2);
   printf("Lebar string1 = %d\n", strlen(string1));
   printf("Lebar string2 = %d\n\n", strlen(string2));

   free(string1);
   free(string2);
   
   return 0;
}

Perbedaan dengan fungsi sebelumnya adalah adanya penambahan operator pointer * seperti diperlihatkan pada kode program di atas. Hal ini karena variabel yang akan dipertukarkan adalah bertipe pointer. Jadi &string1 akan berisi pointer dari pointer yang menunjuk kepada data “Ini STRING-1”.

Sedikit sebagai tantangan, Anda bisa menganalisa sendiri fungsi swapstr() kedua menggunakan debugger. πŸ™‚

Terakhir, akan saya berikan contoh fungsi untuk program spesifik C++ yang menggunakan tipe data objejct string.

/*
   stringswap.cpp
   chandra@teknikelektrolinks.com
*/

#include <iostream>
#include <string>

using namespace std;

void swapstr(string *s1, string *s2)
{
   string tmp = *s1;
   *s1 = *s2;
   *s2 = tmp;
}

int main()
{
   string string1;
   string string2;

   string1 = "Ini STRING-1";
   string2 = "Ini STRING-2 yang lebih panjang";

   cout << "Data SEBELUM dipertukarkan..." << endl;
   cout << "string1 = " << string1 << endl;
   cout << "string2 = " << string2 << endl << endl;
   cout << "Lebar string1 = " << string1.length() << endl;
   cout << "Lebar string2 = " << string2.length() << endl << endl;

   swapstr(&string1, &string2);

   cout << "Data SETELAH dipertukarkan..." << endl;
   cout << "string1 = " << string1 << endl;
   cout << "string2 = " << string2 << endl << endl;
   cout << "Lebar string1 = " << string1.length() << endl;
   cout << "Lebar string2 = " << string2.length() << endl;
 return 0;
}

Fungsi swapstr() yang digunakan mirip dengan fungsi swapstr() untuk variabel bertipe array-of-char dan fungsi swap() untuk variabel bertipe int pada tulisan Bagian 1.

Nah, cukup sekian dulu Bagian 2 ini. Pada Bagian 3 akan kita bahas mengenai cara menukar data variabel bertipe data struct sesuai dengan judulnya.

Semoga bermanfaat, selamat belajar dan selamat berkarya!

πŸ˜€