BAB 3 STRUKTUR DATA : ARRAY DAN POINTER 3.1. ARRAY Larik atau array digunakan untuk menangani data yang banyak, berukuran dan bertipe sama. Karena susunannya, array sering di sebut tabel satu di mensi, dimana masing-masing sel atau elemen array dapat di akses melalui index-nya, perhatikan gambar di bawah ini. X adalah suatu larik dengan n elemen, index awal adalah 1 dan index akhir adalah n. Dengan demikian index menyatakan posisi elemen/sel dalam larik, perhatikan gambar 3.1. 1 2 3 4 n X: ↓ ↓ ↓ ↓ ↓ X(1) X(2) X(31) X(4) X(n) Gambar 3.1. Layout suatu array Untuk mengakses elemen larik berarti kita menunjuk posisi index dari elemen yang di maksud. Misal X(1) berarti kita akan menunjuk pada elemen ke 1 dari larik X. Operasi yang dapat dilakukan pada larik adalah operasi seperti variable biasa dengan menyesuaikan tipe datanya. Larik di sebut struktur data statis, karena kecenderungannya, variable yang di definisikan dengan tipe ini tidak dapat mengalami perubahan pada saat running program, artinya ukuran dari larik tidak dapat lagi mengembang atau menyusut saat program berjalan, jadi saat running program variable ini langsung memesan space memori seperti saat di definisikan dalam source code sebelum di kompilasi. Deklarasi array satu dimensi adalah sebagai berikut : Bahasa Pascal Arr : array [low…high] of datatype; Bahasa C datatype Arr[high]; Untuk mengoperasikan dan memanipulasi akan di jelaskan dengan beberapa contoh yang sangat mudah di pahami di bawah ini, baik cara mengakses index, melakukan pembacaan, melakukan penugasan dan sebagainya. Struktur Data Dasar Dalam Pascal Dan C 19 Algoritma Untuk membaca data dilakukan dengan : Bahasa Pascal Read(n) For i=1 to n do read(x[i]) Bahasa C Scanf(“%d”,n); For(i=0;i<n;i++) scanf(“%d”,x[i]) 1. Algoritma untuk membaca data dengan menghindari data yang sama : Bahasa Pascal write('Berapa Data [max 10]: ');readln(n); K:=1; Repeat write('Masukan bilanga integer : ');readln(b); Ada:=false; For i:=1 to k-1 do If b=x[i] then ada :=true; if not ada then Begin x[k]:=b; K:=k+1; end Else write('data sudah ada'); Until (k>n); Bahasa C scanf("%d",&n); k=0; do{ scanf("%d",&b); ada=1; for(i=0;i<k;i++) if(b==x[i])ada=0; if(ada!=0){ x[k]=b; k++; }else printf("data sudah ada\n"); }while(k<n); 2. Algoritma untuk menentukan data terbesar (max): Bahasa Pascal Max=x[1] For i=2 to n do If x[i]>max then max=x[i] Bahasa C max=x[0] for(i=1;i<n;i++) If(x[i]>max)max=x[i]; 3. Algoritma untuk menentukan data terbesar (max) dan terkecil (min) sekaligus: Bahasa Pascal Max=x[1]; Min=x[1]; For i=2 to n do If x[i]> max then max=x[i] else If x[i]<min then min=x[i] Bahasa C max=x[0]; Struktur Data Dasar Dalam Pascal Dan C 20 min=x[0]; for(i=1;i<n;i++) if(x[i]>max)max=x[i]; else if(x[i]<min)min=x[i]; Jika cara no 3 digunakan juga untuk menentukan data terkecil maka : - untuk mencari max diperlukan (n-1) kali perbandingan - untuk mencari nilai min diperlukan (n-1) kali perbandingan total perbandingan yang diperlukan untuk menentukan max dan min sekaligus adalah sebanyak (n-1)+(n-1)=2n-2 kali. sedangkan cara no 4, jumlah perbandingan yang diperlukan adalah: (n-1)<= jumlah perbandingan<=2n-2. Algoritma untuk menentukan modus : - urutkan - bandingkan dengan data sesudahnya, apakah sama atau tidak - cari banyak data terbesar Bahasa pascal read(n) for i=1 to n do read(x[i]) for i=1 to n-1 do for j=i+1 to n do if x[i] > x[j] then tukar (x[i],x[j]) k=1 l=k b[l]=b[k] A[l] Repeat For i=k+1 to n do Begin If b[l]=x[i] then A[l]=A[l]+1 Else Begin l=l+1 B[l]=x[i] A[l]=1 // Exit for i=n end end Until k>=n Modus=A[i] For i=2 to l do If A[i] > modus then modus=B[i] Struktur Data Dasar Dalam Pascal Dan C Tukar(var x1,x2:integer) Var t:integer; Begin t=x1 x1=x2 x2=t end 21 tukar(int *x1,int *x2){ int t; t=*x1; *x1=*x2 ; *x2=t; } Bahasa C scanf(n) for(i=1;i<n;i++) scanf(x[i]) for(i=1;i<n;i++) for(j=i+1;j<n;j++) if(x[i]>x[j]) tukar (&x[i],&x[j]); k=1; l=k; b[l]=b[k]; a[l] do{ for(i=k+1;i<n;i++){ if(b[l]==x[i])a[l]=a[l]+1; Else { l=l+1; b[l]=x[i] a[l]=1 // Exit for i=n } } }while(k<=n); modus=a[i]; For(i=2;i<l;i++) If(a[i]>modus)modus=b[i]; 3.1.1. Array Berdimensi Pada pembahasan sebelumnya, suatu array yang memiliki dimensi satu, sangat sederhana dan mudah untuk melakukan operasi terhadapnya. Di bagian ini akan di coba membahas array berdimensi lebih dari satu, bias dua atau lebih, tetapi focus dari pembahasan ini lebih cenderung pada tata cara penulisan dan pengaksesannya, khususnya pada array dimensi dua (sering di sebut sebagai matrik), karena mempunyai kolom dan baris. Hampir sama dengan array satu dimensi, pada array jenis ini dapat di deklarasikan sebagai berikut, Bahasa Pascal Bahasa C Const Lowb=1;lowk=1; Highb=10;highk=10; ADIM2_1 : array [lowb..highb,lowk..highk] of datatype; ADIM2_2 : array [lowb..highb] of array [,lowk..highk] of datatype; #define baris 10 #define kolom 10 datatype ADIM2[baris][kolom]; Struktur Data Dasar Dalam Pascal Dan C 22 Untuk dimensi lebih dari dua maka kita tinggal menambahkan index-nya, missal dalam c, int d[3][3][3], dan seterusnya.Operasi untuk memanipulasi array berdimensi lebih dari satu, seperti pengaksesan index, pembacaan maupun penugasan sama dengan array satu dimensi. Sebagai contoh misalnya sebagai berikut : Bahasa Pascal Bahasa C Const Lowb=1;lowk=1; lowt=1; Highb=10;highk=10; hight=10; ADIM2 : array [lowb..highb,lowk..highk, lowt..hight] of datatype; #define baris 10 #define kolom 10 #define tinggi 10 datatype ADIM2[baris][kolom][tinggi]; Kita dapat mendefinisikan larik dua dimensi atau lebih, missal array 3 X 2 di peroleh seperti, 3 5 8 1 2 7 Di dalam larik dimensi satu dapat di simpan sebagai berikut , 3 1 5 2 8 7 Ini disebut bentuk baris. Tiap array di wakili di acu dengan a[0], yang terdiri dari 3 elemen yaitu index a[1] berisi 5 2, index a[2] berisi 8 7. Tiap elemen a[0] di akses dengan a[0][0] dan a[0][1], dengan demikian nilai a[0][0] dan a[0][1] adalah 1. Dalam pascal tidak jauh beda hanya menggabungkan index-nya menjadi satu dalam kurung kotak a[0,1] dan a[1,0]. Program Bahasa C #include <stdio.h> void printarr(int a[][]); void printdetail(int a[][]); void print_ptr(int a[][]); main() { int a[3][2]; \\ A for(int i = 0;i<3;i++) for(int j=0;j<2 ;j++) { { a[i]=i; } } printdetail(a); } Struktur Data Dasar Dalam Pascal Dan C 23 void printarr(int a[][]) { for(int i = 0;i<3;i++) for(int j=0;j<2;j++) { { printf("nilai array %d\n",a[i][j]); } } } void printdetail(int a[][]) { for(int i = 0;i<3;i++) for(int j=0;j<2;j++) { { printf( "nilaiarray %d dan alamatnya %8u\n", a[i][j],&a[i][j]); } } } void print_ptr(int a[][]) { int *b; \\ B b=a; \\ C for(int i = 0;i<6;i++) \\ D { printf("nilai array %d dan alamatnya %16lu\n",*b,b); b++; // increase by 2 bytes \\ E } } Penjelasan 1. Statement A mendeklarasikan array 2 dimensi berukuran 3 × 2. 2. Ukuran array adalah 3 × 2, atau 6. 3. Tiap elemen array diakses dengan dua subscript. 4. Kita dapat memakai dua loop untuk mengakses array. Karena i dipakai untuk mengakses baris , loop terluar mencetak elemen baris, jadi tiap nilai i, pada semua kolom di cetak. 5. Kita dapat mengakses elemen array memakai pointer. 6. Statement B merupakan penugasan alamat dasar dari array ke pointer. 7. Statemen for loop C meng-incremen pointer dan mencetak nilai yang di tunjuk oleh pointer. Jumlah iterasi selesai setelah 6 kali yang merupakan jumlah dari array tersebut. 8. Dengan menggunakan output, kita dapat mem-verifikasi bahwa C menggunakan aturan baris untuk memproses array dua dimensi. Struktur Data Dasar Dalam Pascal Dan C 24 3.2. POINTER Sebagai review atas apa yang telah kita pelajari di bab-bab sebelumnya bahwa algoritma merupakan kumpulan berhingga langkah-langkah untuk menyelesaikan masalah menggunakan komputer dengan kriteria , a) Setiap langkah harus didefinisikan dengan jelas, tidak mendua, b) mempunyai minimal satu keluaran, input boleh tidak ada, c) proses harus berhenti. Sedangkan struktur data adalah susunan data di RAM yang meliputi, a) hubungan diantara data (Stack, Queue, larik, tree), b) prosedur/fungsi/operasi yang dapat dilakukan terhadap data tersebut. Dan yang terakhir adalah program yaitu: rangkaian instruksi yang disusun untuk menyelesaikan masalah menggunakan computer. Dari ketiga definisi diatas dapat disimpulkan bahwa Algoritma, SD dan Program merupakan langkah-langkah untuk menyelesaikan masalah menggunakan komputer dalam bentuk algoritma dan bagaimana susunan datanya di RAM akan di implementasikan ke dalam suatu program komputer. Dalam bab ini akan di tinjau pointer dalam bahasa pascal dan c, sesuai dengan implementasi struktur data yang akan di sajikan pada bab selanjutnya, sebagai dasar pemahaman. 3.2.1. Struktur data dinamis (pointer) dalam bahasa pascal Variabel statis merupakan suatu variable yang kedudukannya di memori bersifat tetap selama program berjalan, dan tidak dapat diubah-ubah sehingga ukuran memori yang diperlukan oleh program tersebut bersifat statis, biasanya representasi dari data yang statis ini menggunakan suatu larik atau array. Sedangkan varibel dinamis adalah suatu variable yang dialokasikan pada saat diperlukan dan dapat dihapus saat program sedang berjalan, dengan demikian ukuran memori yang dibutuhkan oleh program bersifat dinamis. Pointer merupakan struktur data yang dinamis karena variable yang di deklarasikan menunjuk pada lokasi alamat memori tertentu dalam RAM. Jadi variable pointer tidak berisi suatu nilai tetapi berisi suatu alamat memori tertentu. A 568 a A 356 b 356 500 c Gambar 3.2 Pembuatan dan penugasan variabel biasa dan pointer Struktur Data Dasar Dalam Pascal Dan C 25 Gambar 3.2. a merupakan variabel statis yag berisi suatu nilai statis, sedangkan variable A pada gambar 3.2. b merupakan variable dinamis yang menunjuk pada suatu alamat tertentu (356), dimana alamat yang ditunjuk tersebut berisi nilai data 500 (gambar 3.2.c). Nilai data yang ditunjuk ini biasanya disebut node atau simpul. Deklarasi struktur data pointer berada pada bagian type, Type varpoint=^integer; var s: varpoint; new(s); s ? Gambar 3.3 Alokasi variable pointer s adalah variable bertipe pointer, dengan nama tipe varpoint, sedangkan varpoint adalah tipe data baru yang kita definisikan sendiri yang berjenis suatu pointer ke integer. Tanda ^ (carat/caping) untuk pascal dan untuk c tanda asterisk (bintang), harus ditulis apa adanya yang menunjukkan bahwa variable tersebut bertipe pointer. Gambar 3.3 diatas menunjukan suatu pointer s yang di alokasikan oleh new. Contoh lainnya, misalkan : Bahasa Pascal Type Ptr=^data Data=record Nama:string[25]; Alamat:string[30]; End; Var P1,P2:ptr; A,B.C:string[30]; P1 dan P2 merupakan variable pointer yang belum menunjuk kesuatu simpul dalam hal ini diberi tanda seperti deklarasi contoh sebelumnya, untuk mengalokasikan node (simpul) pada variable pointer digunakan statement new, sedang untuk membebaskan pointer digunakan dispose untuk pascal. Kedua statemen ini, merupakan prosedur standar dari pascal untuk mengalokasikan dan mendealokasikan suatu variable pointer. New(P1); New(P2);dispose(p1);dispose(p2); Struktur Data Dasar Dalam Pascal Dan C 26 A B C P1 P2 Bag. Statis Gambar 3.4 Layout variable statis dan dinamis dalam memori Gambar 3.4 di atas mencoba menggambarkan apa yang di lakukan kode sebelumnya. Sekarang coba perhatikan, Bahasa Pascal Type Ptr=^node node=record info:string[25]; next:ptr; End; Var P1,P2:ptr; Next merupakan field bertipe pointer yang menunjuk pada record node, ini disebut suatu linked list atau daftar berkait atau senarai berantai, dimana variable next menunjuk pada node selanjutnya (di dalam kotak garis putus-putus) begitu seterusnya. Jika digambarkan sebagai berikut. P1 Var pointer • Field info • • / Field next NIL Gambar 3.5. Deskripsi suatu list pointer yang berisi suatu record node Struktur Data Dasar Dalam Pascal Dan C 27 Dengan new(p1) dan new(p2) , maka kita membuat dua node/simpul. Karena node yang di buat berupa suatu record maka elemen record tersebut tentu saja belum bernilai, dan elemen pointer lainnya dalam node tersebut juga tidak menunjuk kemanapun. P1 P2 Var pointer ? Node/Simpul Tidak bernilai Var pointer / ? Field next berisi NIL / Node/Simpul Tidak bernilai Field next berisi NIL Gambar 3.6. Dua variable pointer suatu record node yang sedang di alokasikan Pada variable pointer dapat dioperasikan dengan dua cara yaitu mengkopi pointer, dan mengkopi isi dari alamat yang ditunjuk oleh pointer itu sendiri, syarat utamnya adalah bahwa operasi dapat dilakukan untuk tipe data yang sama-sama pointer. Perhatikan lagi. (1) P1^.info:=’pointer’; (2) P2:=P1; P1 P2 pointer / ? / Gambar 3.7. Penugasan suatu pointer dan pengkopian pointer Statemen pertama (1) adalah seperti gambar diatas, sedangkan statement kedua (2) adalah seperti gambar sebagai berikut : P1 pointer / ? / P2 Gambar 3.8. Pengkopian pointer terhadap pointer lainnya Ini disebut mengkopi pointer, sekarang perhatikan statement berikut: P1^:=P2^;(*p1)=(*p2); Struktur Data Dasar Dalam Pascal Dan C 28 Hasilnya adalah seperti dibawah ini, yang disebut mengkopi isi nilai data pointer. P1 P2 pointer / Pointer / Gambar 3.9. Penugasan isi nilai pointer ke pointer lainnya Untuk menghapus pointer gunakan perintah: Dispose(p1);dispose(p2); 3.2.2. Struktur data dinamis (pointer) dalam bahasa c Di dalam bahasa c pointer atau variable pointer merupakan momok bagi sebagian pemrogram pemula, untuk memahami bagian ini, ada baiknya kita mencoba mempelajari variabel biasa lebih dahulu. Variabel adalah sesuatu di dalam program yang mempunyai nama dan nilai yang di kandungnya, juga mempunyai tipe serta ukuran atau bobot. Misal di definisikan variable sebagai berikut : int k; dari definisi di atas compiler dan linker menangani setidaknya 2 byte di memori yang menangani nilai integer, dia juga mengeset table symbol. Di dalam tabel tersebut akan di tambahkan symbol k dan alamat relative selebar 2 byte. Dan jika kita menuliskan pernyataan seperti k=5 maka kita berharap bahwa pada saat run time pernyataan tersebut akan di eksekusi dimana nilai 5 akan di tempatkan pada lokasi memori yang di cadangkan untuk nilai dari k. Jadi jelas ada aturan lvalue=rvalue, dimana nilai 5 di asosiasikan dengan symbol k, jadi pernyataan 5=k adalah tidak di ijinkan, karena rvalue tidak dapat di pakai di sebelah kiri suatu penugasan (‘=’). Sekarang perhatikan, int k = j = k = j, k; 2; 7; <-- baris 1 j; <-- baris 2 Kompiler mengintepretasikan j pada baris satu sebagai alamat dari variable j (lvalue) sehingga akan mengkopi nilai 7 ke alamat tersebut. Pada baris ke dua j di intepretasikan sebagai rvalue, sehingga k disini mengkopi nilai yang ditunjuk oleh alamat pada j, yaitu 7. Dalam bahasa c Struktur Data Dasar Dalam Pascal Dan C 29 Gambar 3.10. Deskripsi lengkap operasi pointer dalam bahasa c Pada gambar 3.10.a suatu deklarasi variable, i dan j adalah suatu integer, sedang p dan q adalah pointer ke suatu integer, di tandai adanya symbol ‘*’ (asterik) sebelum nama variabelnya. Di asumsikan alamat dari ke empat variable tersebut adalah 1080,1082,1084, 1086, dan adanya penugasan nilai 15 ke i pada saat deklarasi variabelnya. Sekarang kita dapat melakukan penugasan seperti p=i (atau p=(int*)) (jika kompiler memiliki kemampuan tersebut), akan tetapi karena variabel p di buat dan disimpan pada alamat dan sebagai variabel pointer, maka untuk menugasi p dengan i di tulis dengan p=&i, ampersand (tanda ‘dan’) di depan variabel i berarti suatu alamat dan bukan nilainya. Gambar 3.10.b mengambarkan hal tersebut, di dalam gambar 3.10.c panah dari p ke i mengindikasikan bahwa p adalah pointer yang menunjuk alamat i. itu Struktur Data Dasar Dalam Pascal Dan C 30 juga dapat membedakan nilai p, yang merupakan suatu alamat, dari nilai dari suatu lokasi alamat yang ditunjuk oleh suatu pointer, seperti gambar 3.10.d. Tanda bintang (asterik atau ’*’) merupakan operator tidak langsung yang mengacu pada isi dari p, dengan kata lain alamat yang di tunjuk oleh p akan di isi nilai 20. Gambar 3.9.e hingga 3.10.h merupakan contoh-contoh statemen penugasan dan bagaimana nilainya di simpan dalam memori computer. Contoh lainnya seperti di berikan di bawah ini, int *ptr; ptr merupakan nama variable pointer, ‘*’ merupakan suatu pointer dan int adalah tipe data yang di tunjuk oleh ptr, yaitu variable untuk menyimpan alamat suatu integer. Jika kita tulis ptr=NULL definisi ini berarti variable tersebut bernilai NULL, tidak menunujuk kemanapun, NULL adalah macro yang tidak menunjuk ke alamat manapun. Jadi variable pointer hanya menyimpan alamat dalam memori. Sehingga jika kita ingin mendapatkan nilai dari variable k, maka kita harus mengkopi alamat yang di tunjuk oleh variabel tersebut, ptr=&k, operator unary & disini mengambil lvalue (alamat) dari k walaupun k sebagai rvalue dari operator penugasan ‘=’, sehingga pernyataan ptr=&k di baca sebagai variable ptr menunjuk ke variable k. Lain persoalan lagi jika kita akan mengisikan nilai langsung ke suatu variable pointer seperti pernyataan berikut : *ptr=10; Akan mengkopi nilai 10 ke alamat yang di tunjuk oleh ptr, untuk menampilkan nilai variable pointer sama dengan saat mendapatkannya, perhatikan : printf(“%d \n”,*ptr); pernyataan di atas akan mencetak ke layar nilai integer 10. Sekarang coba amati program pendek di bawah ini dan analisa : #include <stdio.h> int j, k; int *ptr; int main(void) { j = 1; k = 2; ptr = &k; printf("\n"); printf("j bernilai %d dan di simpan di %p\n", j, (void *)&j); printf("k bernilai %d dan di simpan di %p\n", k, (void *)&k); printf("ptr bernilai %p dan di simpan di %p\n",ptr,(void*)&ptr); printf("Nilai integer yang di tunjuk oleh ptr adalah %d\n", *ptr); return 0; } Struktur Data Dasar Dalam Pascal Dan C 31 3.2.3. Pointer dan Array Pada contoh sebelumnya (gambar 3.10), pointer merujuk pada suatu blok memori yang menangani integer. Situasi yang lebih menarik lagi adalah saat pointer menunjuk ke struktur data yang di buat dan di mosifikasi secara dinamik, dan situasi ini akan di kenakan pada suatu array atau larik. Kita sudah tahu bahwa array merupakan data statis yang jumlahnya tetap, berukuran dan bertipe yang seragam, yang sudah di ketahui sebelum program berjalan, artinya programmer sudah tahu kapasitas yang harus di berikan pada saat mendefinisikan variabel dalam bentuk array, tetapi apakah hal tersebut sudah mencukupi atau tidak, programmer akan tahu saat terjadi overflow. Pada gambar 3.10.d p menunjuk ke lokasi 1080, tetapi juga mengakses 1082,1084. Contohnya mengakses nilai dari variabel j yang merupakan tatangga dari i adalah cukup menambahkan ukuran suatu variabel integer ke alamat i yang di simpan dalam p untuk mengakses nilai j dari p. Perhatikan pernyataan berikut : int a[5]; *p; deklarasi diatas menunjukan bahwa a adalah suatu pointer ke blok memori yang dapat menangani 5 integer, pointer ini sufatnya tetap, sehingga a dapat di perlakukan sebagai konstan, dengan demikian suatu penugasan terhadap variabel a dapat di tulis sebagai, a=p; atau a++; hal ini menyebabkan kesalahan compiler, karena a adalah pointer, notasi pointer yang dapat di gunakan untuk mengakses variabel a adalah misalnya dengan suatu loop, for (x=a[0];i=1;i<5;i++) x+=a[i]; atau dengan pointer dapat di tulis, for (x=*a;i=1;i<5;i++) x+=*(a+i); atau for (x=*a;p=a+1;p<a+5;p++) x+=*p; Disini a+1 merupakan lokasi sel selanjutnya dari array a sehingga a+1 sama dengan &a[1]. Dengan demikian jika a sama dengan 1020 maka a+1 bukan 1021 tetapi 1022 karena pointer aritmetik tergantung pada periode tipe entitas pointernya, contoh : char b[5];long c[5]; Struktur Data Dasar Dalam Pascal Dan C 32 setelah deklarasi variable di atas misalkan b berada pada 1050 dan c di 1055 , b+1 sama dengan 1051 karena satu karakter memerlukan satu byte dan c+1 sama dengan 1059 karena panjang dari long int adalah 4 byte. Inilah alasannya kenapa ekspresi c+1 merujuk pada alamat memori c+1*sizeof(long). Kita dapat mendeklarasikan suatu variabel pointer array dengan penugasan seperti berikut, int *p; p= malloc(sizeof(int [n])); Disini kita cukup tempat untuk mendefinisikan array integer, pointer p dapat di perlakukan sebagai variabel array, sehingga notasi array dapat di pakai disini for (sum =p[0],i=1;i<n;i++) sum+=p[i]; atau for (sum =*p,i=1;i<n;i++) sum+=*(p+1); atau for (sum =*p,q=p+1;q<p+n;q++) sum+=*q; Untuk membahas pointer dan array lebih mendalam kami persilahkan untuk membuka buku yang lebih detail membahas hal tersebut, semangat dari buku ini adalah sekedar mengingatkan kepada para pembaca untuk lebih memahami array, operasi dan hubungannya dengan pointer, yang akan kita pakai untuk membahas bab selanjutnya. Juga pada pengantar sudah di jelaskan bahwa buku ini akan lebih bermanfaat bila di pergunakan pambaca yang sudah memahami pointer, untuk itulah halaman ini boleh di lewati bagi pembaca yang sudah mahir konsep pointer dan array. 3.2.4. Pointer dan Structure Untuk keperluan studi dalam buku ini maka kita langsung membahas hubungan pointer dan structur (record), karena struktur ini banyak di gunakan dalam pembahasan selanjutnya, tanpa mengurangi peranan array, yang kita anggap lebih mudah di fahami sendiri atau dengan mereferensi dari buku lainnya. Dalam bahasa c kumpulan tipe data primitive yang berbeda dan berukuran beda pula dapat di rangkum dalam suatu bentuk komposit yang di kenal sebagai struct atau record, perhatikan contoh di bawah ini : struct tpeg { char lname[20]; /* nama akhir */ char fname[20]; /* nama depan */ Struktur Data Dasar Dalam Pascal Dan C 33 int usia; /* usia */ float gaji; /* misal. 12.500 per jamr */ }; tpeg adalah suatu record yang terdiri dari 4 field di dalamnya, struct ini dapat di referensi sebagai tipe bentukan baru yang kita ciptakan sendiri, untuk di acu oleh variable lainnya. Jika kita akan membuat variable baru yang mempunyai tipe struct tpeg, kita akan deklarasikan sebagai berikut : struct tpeg pegawai; Deklarasi dan pembuatan struct dapat dilakukan dengan banyak cara, begitu pula deklarasi variabelnya jug sama dengan deklarasi variable biasa dalam tipe data primitive. struct { char lname[20]; /* nama akhir */ char fname[20]; /* nama depan */ int usia; /* usia */ float gaji; /* misal. 12.500 per jamr */ } tpeg; //penamaan struct setelah deklarasi struct-nya typedef struct tpeg TPegawai;//pembentukan tipe data baru Sekarang perhatikan contoh program di bawah ini #include <stdio.h> #include <string.h> struct { char lname[20]; /* nama akhir */ char fname[20]; /* nama depan */ int usia; /* usia */ float gaji; /* misal. 12.500 per jamr */ } tpeg; //penamaan struct setelah deklarasi struct-nya struct tpeg my_struct; /* deklarasi structure my_struct */ int main(void) { strcpy(my_struct.lname,"Joko"); strcpy(my_struct.fname,"Teddy"); printf("\n%s ",my_struct.fname); printf("%s\n",my_struct.lname); return 0; } Keterbatasan penggunaan structure adalah jika kita mempunyai data yang cukup besar dan menginginkan untuk mencetak, dengan membuat fungsi untuk mencetak, maka pengiriman parameter structure tidak di ijinkan dalam ANSI C, sehingga kita perlu pointer ke structure untuk mengirimkannya ke dalam fungsi. Dan unutk melakukannya kita akan membuat suatu variable pointer yang menunjuk ke struct yang di maksudkan. Misal dengan menulis : Struktur Data Dasar Dalam Pascal Dan C 34 struct tpeg *peg; karena tipe data pointer peg adalah sama dengan tipe data my_struct sehingga kita dapat menunjuk struct kita menjadi peg=&my_struct; sehingga kita dapat mengakses anggota dari struct my_struct dengan de-referensi, perhatikan pernyataan di bawah ini, (*peg).usia=29; Cara lain untuk mengakses anggota struct yang di tunjuk dengan pointer adalah, peg->usia=29; Sehingga program di atas akan di modifikasi menjadi, #include <stdio.h> #include <string.h> struct { char lname[20]; /* nama akhir */ char fname[20]; /* nama depan */ int usia; /* usia */ float gaji; /* misal. 12.500 per jamr */ } tpeg; //penamaan struct setelah deklarasi struct-nya struct tag my_struct; /* membuat variabel structure */ void cetak_nama(struct tpeg *p); /* function prototype */ int main(void) { struct tpeg *peg; /* pointer ke structure */ peg = &my_struct; /* pointer menjunjuk ke almt my_struct */ strcpy(my_struct.lname,"Joko"); strcpy(my_struct.fname,"Teddy"); printf("\n%s ",my_struct.fname); printf("%s\n",my_struct.lname); my_struct.age = 29; cetak_nama(peg); /* mengirimkan pointer */ return 0; } void cetak_nama(struct tpeg *p) { printf("\n%s ", p->fname); /* p menunjuk ke structure */ printf("%s ", p->lname); printf("%d\n", p->age); } Dalam bahasa ansi c untuk megalokasikan variable pointer di gunakan pernyataan sebagai berikut (Gambar 3.11) struct tpeg *p; p=(struct tpeg*)malloc(sizeof(struct tpeg)); p=NULL; free(p); Struktur Data Dasar Dalam Pascal Dan C 35 malloc (memory allocation) adalah fungsi untuk mengalokasikan memori dari suatu besaran tipe data dalam byte, perhatikan fungsi sizeof, fingsi ini akan mengembalikan besar byte dari suatu tipe data yang di kirimkan, dalam contoh diatas adalah struct tpeg. Sedangkan (struct tpeg*) adalah suatu typecast atau konversi tipe, karena variable p adalah suatu pointer yang menunjuk ke struct tpeg, maka ukuran dari tipe yang bukan pointer (struct tpeg) akan di konversi sesuai tipe data yang tugasinya (*p). Jadi pernyataan di atas boleh di baca sebagai “alokasikan di memori untuk variable pointer p sebesar ukuran dari struct tpeg”.Setelah dialokasikan maka kita dapat membebaskan/menghapus dari memori dengan keyword free(p). Struct tpeg p lname fname usia gaji Gambar 3.11. Pointer Structure Pointer dan struktur sangat berguna pada List yang non-contigous, misalnya seperti di potongan kode bawah ini : 1. typedef struct node *link; 2. struct node{ 3. char info; 4. link next; 5. }; 6. link awal; 7. . 8. . 9. void insurut(link *L,char c); //insert urut 10. struct node *baru,*bantu; 11. baru=(struct node*)malloc(sizeof(struct node)); 12. baru->info=c; 13. baru->next=NULL; 14. . 15. . 16. } 17. . 18. . 19. . 20. insurut(&awal,'e'); Struktur Data Dasar Dalam Pascal Dan C 36 Nomer baris 1-6 adalah mendefinisikan sekaligus membuat tipe data baru berupa pointer dengan nama link, yang bertipe struct node, struct node adalah suatu record yang berisi 2 elemen.Elemen pertama adalah info bertipe char dan elemen ke dua adalah next bertipe ponter link. Baris 6 mendefinisikan variable awal dengan tipe pointer link. Secara abstraksi akan tampak seperti gambar 3.11/ seperti di bawah ini, awal INFO NEXT Gambar 3.12. definisi pointer ke struct Untuk no 9-13, di definisikan suatu fungsi untuk menyisipkan , suatu karakter ke dalam suatu list, parameter yang ada adalah suatu pointer link, yang berupa suatu struct node, karena penririman parameter struct akan lebih baik di definisikan sebagai pointer, alasan lain karena kita akan merubah parameter actual dari fungsi ini. Di dalam fungsi berturut-turut di lakukan definisi variabel baru dan bantu yang bertipe pointer ke struct, yang akan di gunakan dalam operasi penyisipan. Alokasi memori di lakukan sebesar struct yang di buat dan di konversikan secara pointer. Baris 20 adalah bagaimana melakukan pemanggilan fungsi dan mengirimkan parameter dengan operator ampersand (&), yang di maksudkan sebagai pengiriman secara acuan (alamat di memori yang di tunjuk oleh variabel yang di kirimkan), serta nilai yang akan di isikan ke dalam suatu list. Struktur Data Dasar Dalam Pascal Dan C 37