Modul Ajar & Praktikum Pemrograman Lanjut TIF...

64
Modul Ajar & Praktikum Pemrograman Lanjut TIF 4117 Program Studi Teknik Informatika Fakultas Teknik Universitas Brawijaya 2011

Transcript of Modul Ajar & Praktikum Pemrograman Lanjut TIF...

Modul Ajar & PraktikumPemrograman Lanjut

TIF 4117

Program Studi Teknik InformatikaFakultas Teknik

Universitas Brawijaya2011

DAFTAR ISI1 BAB 1: POINTER DASAR ................................................................................................................... 4

1.1 PENDAHULUAN.................................................................................................................................................................. 51.2 REFERENSI ....................................................................................................................................................................... 51.3 DEKLARASI VARIABEL POINTER ......................................................................................................................................... 61.4 PENDEFINISIAN POINTER DAN PROSES REFERENSI............................................................................................................. 71.5 AKSES POINTER DAN PROSES DEREFERENSI ...................................................................................................................... 81.6 SIMBOL *: DEKLARASI VS DEREFERENSI.......................................................................................................................... 101.7 VOID POINTER ............................................................................................................................................................... 101.8 NULL POINTER ............................................................................................................................................................... 111.9 ARITMETIKA POINTER ..................................................................................................................................................... 121.10 POINTER SEBAGAI PARAMETER FORMAL FUNGSI............................................................................................................. 131.11 TUGAS .......................................................................................................................................................................... 14

2 BAB 2: ARRAY .................................................................................................................................15

2.1 PENDAHULUAN................................................................................................................................................................ 162.2 ARRAY SATU DIMENSI .................................................................................................................................................... 16

2.2.1 Deklarasi Array Satu Dimensi............................................................................................................................ 162.2.2 Inisialisasi Array Satu Dimensi .......................................................................................................................... 162.2.3 Akses array satu dimensi ................................................................................................................................... 182.2.4 Array dan Pointer................................................................................................................................................ 192.2.5 Array sebagai Parameter Fungsi ...................................................................................................................... 21

2.3 ARRAY MULTIDIMENSI .................................................................................................................................................... 212.3.1 Deklarasi Array Dua Dimensi ............................................................................................................................ 222.3.2 Inisialisasi Array Dua Dimensi........................................................................................................................... 222.3.3 Akses Array Dua Dimensi .................................................................................................................................. 242.3.4 Array Dua Dimensi sebagai Parameter Fungsi ............................................................................................... 24

2.4 TUGAS ........................................................................................................................................................................... 25

3 BAB 3: POINTER LANJUTAN - ALOKASI MEMORI DINAMIK........................................................... 26

3.1 PENDAHULUAN................................................................................................................................................................ 273.2 PENGALOKASIAN MEMORI SECARA DINAMIK .................................................................................................................... 27

3.2.1 Fungsi malloc ................................................................................................................................................... 273.2.2 Operator new ...................................................................................................................................................... 29

3.3 DEALOKASI ATAU PEMBEBASAN MEMORI.......................................................................................................................... 293.3.1 Fungsi free ........................................................................................................................................................ 303.3.2 Operator delete ............................................................................................................................................... 30

3.4 REALOKASI MEMORI ....................................................................................................................................................... 313.5 TUGAS ........................................................................................................................................................................... 32

4 BAB 4: STRING................................................................................................................................ 33

4.1 PENDAHULUAN................................................................................................................................................................ 344.2 DEKLARASI STRING......................................................................................................................................................... 34

4.2.1 Deklarasi via Array of Characters ..................................................................................................................... 344.2.2 Deklarasi via Pointer........................................................................................................................................... 34

4.3 INISIALISASI DAN PENDEFINISIAN STRING ....................................................................................................................... 364.3.1 Inisialisasi via Array ............................................................................................................................................ 364.3.2 Inisialisasi via Pointer ......................................................................................................................................... 38

4.4 PENANGANAN STRING ..................................................................................................................................................... 414.4.1 Fungsi strlen ................................................................................................................................................... 414.4.2 Fungsi strcmp ................................................................................................................................................... 414.4.3 Fungsi strcpy ................................................................................................................................................... 414.4.4 Fungsi strncpy ................................................................................................................................................. 424.4.5 Fungsi strcat ................................................................................................................................................... 42

3

4.4.6 Fungsi strncat ................................................................................................................................................. 434.4.7 Fungsi atof ........................................................................................................................................................ 434.4.8 Fungsi atoi ........................................................................................................................................................ 444.4.9 Fungsi atol ........................................................................................................................................................ 44

4.5 TUGAS ........................................................................................................................................................................... 45

5 BAB 5: STRUCT................................................................................................................................ 46

5.1 PENDAHULUAN................................................................................................................................................................ 475.2 STRUKTUR ATAU STRUCT................................................................................................................................................. 475.3 DEKLARASI TIPE STRUCT DAN VARIABEL BERTIPE STRUCT ................................................................................................ 475.4 KEYWORD TYPEDEF ........................................................................................................................................................ 485.5 INISIALISASI DAN AKSES ANGGOTA STRUCT..................................................................................................................... 495.6 RUANG LINGKUP STRUCT ................................................................................................................................................ 505.7 POINTER TO STRUCT....................................................................................................................................................... 505.8 UNION ........................................................................................................................................................................... 515.9 TUGAS ........................................................................................................................................................................... 53

6 BAB 6: OPERASI FILE...................................................................................................................... 54

6.1 PENDAHULUAN................................................................................................................................................................ 556.2 FILE ............................................................................................................................................................................... 556.3 PORTAL I/O STANDAR: STDIN DAN STDOUT..................................................................................................................... 566.4 PENANGANAN FILE: TINGKAT TINGGI VS TINGKAT RENDAH ............................................................................................. 566.5 POSISI PROGRAM PADA FILE ........................................................................................................................................... 576.6 MEMBUKA FILE ............................................................................................................................................................... 576.7 MENUTUP FILE ............................................................................................................................................................... 586.8 MENULIS FILE ................................................................................................................................................................ 59

6.8.1 Fungsi fprintf ................................................................................................................................................. 596.8.2 Fungsi fputc...................................................................................................................................................... 596.8.3 Fungsi fputs...................................................................................................................................................... 60

6.9 MEMBACA FILE ............................................................................................................................................................... 606.9.1 Fungsi fscanf ................................................................................................................................................... 606.9.2 Fungsi fgetc...................................................................................................................................................... 606.9.3 Fungsi fgets...................................................................................................................................................... 616.9.4 Fungsi feof ........................................................................................................................................................ 61

6.10 CONTOH APLIKASI ........................................................................................................................................................ 616.11TUGAS ........................................................................................................................................................................... 63

7 DAFTAR PUSTAKA ........................................................................................................................... 64

4

1 BAB 1: Pointer Dasar

Pokok bahasan:

Referensi

Deklarasi dan definisi pointer

Referensi dan dereferensi

Void pointer

Null pointer

Aritmetika pointer

Pointer sebagai parameter fungsi

5

1.1 Pendahuluan

Sebuah pointer (kadang-kadang diterjemahkan sebagai “penunjuk”) adalah sebuah variabel yangbertipe khusus, yaitu yang menyimpan alamat dari sebuah variabel lainnya. Pointer memiliki peranyang sangat penting dalam C/C++. Secara khusus, pointer berperan vital dalam implementasistruktur data seperti array, string, dan linked list. Selain itu, pointer juga dapat digunakan untukpengiriman parameter fungsi dan untuk menunjuk pada alamat fungsi. Untuk tujuan yang terakhirini pembahasannya di luar fokus bab ini.

Dalam memahami pointer, ada beberapa konsep dasar atau terkait yang perlu dipelajari.Diantaranya adalah referensi, pendeklarasian pointer, inisialisasi dan pendefinisian pointer, aksespointer, dereferensi, null ponter, void pointer, dan penggunaan pointer untuk pengirimanparameter fungsi.

1.2 Referensi

Seperti yang telah diketahui, setiap variabel yang dideklarasikan akan dialokasikan tempat tertentupada memori. Keberadaan variabel ini memudahkan kita untuk menggunakan data yang tersimpanpada memori, tanpa memedulikan lokasi fisik data tersebut. Untuk mengakses atau mengubahdata tersebut cukup merujuknya melalui nama variabelnya. Tetapi sebenarnya kita masih bisamengakses lokasi data tersebut melalui alamat variabelnya jika diperlukan. Alamat variabel inisering juga disebut dengan “referensi” dari variabel tersebut. Dalam bahasa C/C++, proses me-“referensi” atau mengakses alamat sebuah variabel dapat menggunakan operator alamat ataureferensi yang direpresentasikan dengan simbol ampersand (&).

Contoh di bawah ini menunjukkan cara mengakses alamat dari variabel menggunakan operator &.

123456789101112131415

#include <stdio.h>#include <stdlib.h>

int main(){int a = 17;double b = 13.5;

printf("Isi variabel: \n");printf("\t a = %d",a);printf("\t b = %.2lf",b);

printf("\n\nAlamat variabel: \n");printf("\t a = %d ",&a);printf("\t b = %d ",&b);system(“pause”);

6

1617

return 0;}

Gambar 1.1

Sebagai latihan, ketiklah contoh di atas untuk menjadi sebuah program. Setelah menjalankanprogram tersebut dan memperhatikan hasilnya, cobalah untuk mengubah format keluaran &a dan&b pada baris ke-13 dan ke-14 dari %d menjadi %p lalu amati hasilnya. Ambillah kesimpulan dariperubahan tersebut.

Saat variabel a dan b dideklarasikan dan diinisialisasikan dengan nilai masing-masing 17 dan 13.5,di memori dialokasikan tempat yang sesuai, seperti yang diilustrasikan pada gambar 1.2.

Gambar 1.2

Nilai alamat dari a dan b yang tertulis di sini hanya sebagai contoh; nilai yang sebenarnya dapatberbeda dalam setiap menjalankan program. Alamat a dan b dapat diakses dengan ekspresimasing-masing &a dan &b.

1.3 Deklarasi Variabel Pointer

Sebelum diisikan dengan alamat dari variabel lainnya, sebuah pointer perlu dideklarasikan terlebihdahulu. Sintaksis pendeklarasiannya adalah sebagai berikut.

tipedatavariabelyangditunjuk *namavariabelpointer;atau

tipedatavariabelyangditunjuk * namavariabelpointer;Perhatikan penggunaan simbol bintang/asterisk (*) di atas. Simbol ini membedakan deklarasisebuah variabel non-pointer dengan deklarasi variabel pointer. Tipe data variabel yang ditunjukpointer dapat berupa sembarang tipe. Aturan penamaan variabel pointer harus mengikuti aturanyang sama dengan penamaan variabel biasa.

Contoh deklarasi pointers:

int* pi; // pointer to integerfloat* pf; // pointer to float

7

Pointer yang telah dideklarasikan hanya dapat diisikan dengan alamat dari variabel yang bertipedata sesuai dengan deklarasi pointernya. Sebagai contoh, sebuah pointer to integer hanya dapatmenyimpan alamat dari variabel yang bertipe data integer.

1.4 Pendefinisian Pointer dan Proses Referensi

Saat dideklarasikan, sebuah pointer menunjuk pada alamat yang ‘acak’ atau tidak terdefinisi.Dalam keadaan demikian usaha untuk mengakses pointer ini dapat berakibat fatal karena pointerini mungkin berisi alamat dari memori yang sedang dikelola oleh sistem atau aplikasi lain. Olehkarena itu, untuk menggunakan sebuah pointer kita harus memastikan bahwa dia berisi alamatyang benar atau yang kita inginkan.

Inisialisasi atau pendefinisian sebuah pointer dapat dilakukan dengan salah satu dari dua cara.Pertama, dengan proses referensi ke variabel yang sudah ada. Kedua, dengan alokasi memoridinamik. Sub bab ini hanya akan membahas cara yang pertama. Cara yang kedua akandidiskusikan di bab lainnya.

Sintaksis proses referensi sebuah pointer ke variabel lain yang sudah ada adalah:

namavariabelpointer = &namavariabellainnya;Perhatikan pemakaian operator referensi (&) pada pernyataan di atas. Tentunya, kedua variabel diatas sudah harus dideklarasikan sebelumnya.

Contoh di bawah ini menunjukkan inisialisasi pointer dengan cara referensi ke variabel lainnya.Jalankanlah program ini dan perhatikan hasilnya.

12345678910111213141516171819

#include <stdio.h>#include <stdlib.h>

int main(){int x; // Nilai x acakint *px; // Nilai px acak

printf("\nKondisi x dan px sebelum inisialisasi ");printf("\nNilai x: %d", x);printf("\nAlamat x: %d", &x);printf("\nNilai px = %d", px);printf("\nAlamat px = %d\n", &px);

px = &x;x = 10;

printf("\nKondisi x dan px setelah inisialisasi ");printf("\nNilai x: %d", x);printf("\nAlamat x: %d", &x);

8

202122232425

printf("\nNilai px = %d", px);printf("\nAlamat px = %d", &px);

system("pause");return 0;

}Gambar 1.3

Beberapa proses yang terjadi saat program ini dijalankan dapat diilustrasikan pada gambar 1.4berikut.

int x;

int *px;

px=&x;

x=10;

deklarasi

inisialisasi pointerp dengan referensi

10

x

px

px x

px xinisialisasi x

x tidak terdefinisi

px tidak terdefinisi

Gambar 1.4

1.5 Akses Pointer dan Proses Dereferensi

Pengaksesan pointer dengan cara memanggil nama variabel pointer sama dengan mengaksesalamat variabel yang ditunjuknya. Untuk mengakses nilai yang dikandung oleh variabel yangditunjuknya, kita dapat menggunakan simbol bintang (*) yang diletakkan sebelum nama variabelpointer. Proses ini disebut dereferensi.

Perhatikan contoh dereferensi pada kode di bawah ini.

1234567891011

#include <stdio.h>#include <stdlib.h>

int main(){int x; // Nilai x acakint *px = &x; // Deklarasi dan inisialisasi pxx = 11;

printf("\nKondisi x dan px setelah inisialisasi");printf("\nNilai x: %d", x);printf("\nNilai px: %d", px);

9

1213141516171819202122232425

// dereferensi untuk mengakses nilai x via pointer pxprintf("\nNilai *px = %d", *px);// dereferensi untuk mengubah nilai x via pointer px*px = 5;printf("\nKondisi x dan px setelah x diubah");printf("\nNilai x: %d", x);printf("\nNilai px: %d", px);printf("\nNilai *px = %d", *px);

system("pause");return 0;

}Gambar 1.5

Beberapa proses yang terjadi saat kode di atas ini dijalankan dapat diilustrasikan pada gambarberikut:

int x;

int px=&x;

*px=5;

deklarasi x

deklarasi &inisialisasi p

5

x

px x

px xdereferensi px

x tidak terdefinisi

x=11;inisialisasi x

11px x

Gambar 1.6

Amati penggunaan dereferensi pada baris ke-14 dan ke-16 pada gambar 1.4, lalu ambilkesimpulan tentang perbedaan kegunaannya. Amati juga perbedaan antara px dan *px.

Cobalah untuk menambahkan variabel baru y bertipe integer dan inisialisasikan dengan sebuahnilai, misalnya 100. Referensikan alamat y ini ke pointer px setelah baris ke-19, kemudian cetaknilai px dan *px. Amati dan simpulkan hasilnya.

Setelah itu coba ubah nilai y melalui px, misalnya menjadi 1000, dan cetak nilai y dan *px untukmengamati perubahan y.

10

1.6 Simbol *: Deklarasi vs Dereferensi

Perlu diingat benar bahwa simbol bintang (*) dalam pembahasan pointer memiliki dua semantik(makna) dan penggunaan yang berbeda. Makna pertama adalah untuk menunjukkan bahwasebuah variabel merupakan sebuah pointer. Makna ini didapat dari pendeklarasian pointertersebut. Contoh * untuk deklarasi dapat dilihat di baris ke-6 gambar 1.2 dan baris ke-6 gambar1.3, seperti di bawah ini.

int *px; // Deklarasi px: px adalah sebuah “pointer to integer”int *px = &x; // Deklarasi dan inisialisasi px

Makna kedua adalah untuk mengambil isi dari alamat yang disimpan oleh pointer tersebut. Prosesini disebut dengan “dereferensi” seperti yang telah dijelaskan sebelumnya. Contoh * untukdeklarasi dapat dilihat di baris ke-14 dan baris ke-16 gambar 1.3, seperti di bawah ini.

// dereferensi untuk mengakses nilai x via pointer pxprintf("\nNilai *px = %d", *px);// dereferensi untuk mengubah nilai x via pointer px*px = 5;

Dua makna yang berbeda dari simbol * ini sangat penting untuk diperhatikan dan diingat karenasering disalahpahami.

1.7 Void Pointer

Void pointer adalah pointer dengan tipe khusus. Dalam C/C++ void melambangkan ketiadaan tipedata, sehingga void pointer adalah pointer yang menunjuk pada nilai yang tidak bertipe data.

Dengan demikian void pointer dapat menunjuk pada data dari sembarang tipe, seperti integer,float, double, char atau string. Tetapi void pointer ini memiliki keterbatasan. Karena pointer inibersifat ‘void’, data yang ditunjuknya tidak dapat secara langsung didereferensikan. Agar dapatdidereferensikan, pointer ini (atau alamat yang tersimpan di dalamnya) harus dikonversi paksa (di-cast ) dahulu menjadi pointer yang dapat menunjuk pada tipe data kongkrit.

Untuk memahami konsep void pointer dan proses casting di atas, kerjakan dan analisis kode dibawah ini.

123456789

#include <stdio.h>#include <stdlib.h>

int main(){void* pv; // Pointer terhadap voidint* pi; // Pointer terhadap integerdouble* pd; // Pointer terhadap doubleint ivalue = 100;double dvalue = 50.55;

11

101112131415161718192021222324252627282930313233

// pv dapat menunjuk pada variabel bertipe data integerpv = &ivalue;printf("pv=%d, sizeof(pv)=%d\n",pv, sizeof(pv));

// pernyataan ini salah krn pv tidak dapat didereferensikanprintf("*pv=%d, sizeof(*pv)=%d\n",*pv, sizeof(*pv));

// pv dapat menunjuk pada variabel bertipe data doublepv = &dvalue;printf("pv=%d, sizeof(pv)=%d\n",pv, sizeof(pv));

// pernyataan ini salah krn pv tidak dapat didereferensikanprintf("*pv=%.2lf, sizeof(*pv)=%d\n",*pv, sizeof(*pv));

// pd menerima hasil casting dari pvpd = (double*)pv;printf("pd=%d, sizeof(pd)=%d\n",pd, sizeof(pd));// pernyataan ini benar, pd dapat didereferensikanprintf("*pd=%.2lf, sizeof(*pd)=%d\n",*pd, sizeof(*pd));

system("pause");return 0;

}Gambar 1.7

1.8 Null Pointer

Sebuah null pointer adalah sebuah pointer yang memiliki nilai khusus yang menununjukkan bahwapointer tersebut tidak menyimpan alamat memori manapun. Nilai ini dihasilkan dari penugasannilai NULL atau 0 ke sebuah pointer. Contoh:

int *p;p = NULL; // atau p = 0;

Null pointer berbeda dengan void pointer. Null pointer adalah pointer yang tidak menunjuk padaalamat memori manapun, sedangkan void pointer adalah pointer yang dapat menunjuk padasebuah alamat memori tanpa tipe data tertentu. Istilah null diasosiasikan dengan nilai yangdisimpan pada pointer, sedangkan void mengacu pada tipe data yang ditunjuk oleh pointer.

12

1.9 Aritmetika Pointer

Operasi aritmetika dapat juga diterapkan pada pointer, tetapi dengan lebih banyak keterbatasandaripada operasi aritmetika pada tipe data integer, float, atau, double. Hanya penjumlahan danpengurangan yang berlaku pada operasi aritmetika pointer. Perilaku kedua operasi ini bergantungpada ukuran tipe data yang ditunjuk oleh pointer yang bersangkutan.

Dalam bahasa C/C++ tipe-tipe data yang berbeda dapat memiliki ukuran yang berbeda pulatergantung pada kompilator (compiler) dan jenis platform target programnya. Sebagai contoh,dengan kompilator dan platform tertentu, char akan berukuran 1 byte, short 2 bytes, danlong 4 bytes.

Misalkan kita mendefiniskan 3 buah pointer berikut:char *mychar;short *myshort;long *mylong;dan kita ketahui bahwa pointer-pointer tersebut masing-masing menunjuk pada alamat 1000,2000 and 3000 pada memori. Lalu kita tuliskan:

mychar++; //ekivalen mychar +=1;myshort++; //ekivalen myshort +=1;mylong++; //ekivalen mylong +=1;Setelah itu mychar akan bernilai 2002 (bukan 1001), myshort bernilai 2002 (bukan 2001), danmylong 3004 (bukan 3001), walaupun masing-masing hanya ditambah dengan 1. Alasannyaadalah penambahan satu tersebut menyebabkan masing-masing pointer menunjuk pada elemenyang bertipe data sama pada lokasi memori berikutnya. Jadi, penambahan satu di sini bermaknaperpindahan 1 unit tipe data pada elemen berikutnya, seperti yang diilustrasikan pada gambar dibawah ini.

Gambar 1.8

13

1.10 Pointer sebagai Parameter Formal Fungsi

Pointer dapat dimanfaatkan sebagai parameter formal dalam sebuah fungsi. Pointer ini akanmenyimpan alamat dari variabel yang dilewatkan sebagai parameter aktual pada pemanggilanfungsi tersebut. Dengan demikian nilai variabel yang bersangkutan dapat diubah di dalam fungsimelalui proses dereferensi. Mekanisme pengiriman alamat variabel sebagai parameter pada fungsidisebut dengan passing by reference.

Sebagai contoh, kerjakan dan amati kode di bawah ini. Kode ini menyediakan 2 buah fungsi,masing-masing untuk konversi nilai dari standar satuan metrik (cm) ke standar satuan Inggris(inch) dan sebaliknya. Penggunaan pointer sebagai parameter fungsi dapat diamati pada definisifungsi inchToCm() di baris ke-7 sampai ke-9. Contoh passing by reference dapat dilihat padabaris ke-21. Bandingkanlah dengan mekanisme passing by value pada baris ke-17, menggunakanfungsi yang didefinisikan pada baris ke-4 sampai ke-6.

1234567891011121314151617181920212223242526

#include <stdio.h>#include <stdlib.h>

double cmToInch(double a){return a*0.393700787;

}void inchToCm(double* a){

*a *= 2.54;}

int main(){// Panjang dalam cmdouble panjang=15;printf("panjang: %.2lf cm\n",panjang);

// Konversi dari cm ke inch, passing by valuepanjang = cmToInch(panjang);printf("panjang: %.2lf inch\n",panjang);

// Konversi kembali dari inch ke cm, passing by referenceinchToCm(&panjang);printf("panjang: %.2lf cm\n",panjang);

system("PAUSE");return 0;

}

Gambar 1.9

14

1.11 Tugas

Tugas yang relevan dengan topik bab ini diberikan oleh dosen/asisten praktikum.

Tugas bab ini dapat dikombinasikan dengan tugas bab lain atas arahan dan ijin dosen/asistenpraktikum.

Tugas bab ini dikumpulkan kepada dosen/asisten sesuai format yang diminta.

15

2 BAB 2: Array

Pokok bahasan:

Array satu dimensi

o Deklarasi

o Inisialisasi

o Akses

o Array dan pointer

o Array sebagai parameter fungsi

Array dua dimensi

o Deklarasi

o Inisialisasi

o Akses

o Array sebagai parameter fungsi

16

2.1 Pendahuluan

Array (kadang-kadang diterjemahkan sebagai “larik”) adalah serangkaian elemen-elemen yangberasal dari tipe data yang sama, disusun secara berurutan di dalam memori, dan masing-masingdapat diakses dengan menambahkan indeks pada nama array tersebut.

Tipe data dari elemen array dapat berupa tipe data sederhana maupun tipe data kompleks. Setiapelemen array mempunyai nomor indeks yang unik dan disimpan secara berurutan di dalammemori. Array dapat berdimensi satu, dua, tiga, ataupun lebih, sesuai dengan kebutuhanpemrogram.

2.2 Array Satu Dimensi

2.2.1 Deklarasi Array Satu Dimensi

Penamaan array harus mengikuti aturan-aturan penamaan variabel. Seperti halnya variabelsederhana, array pun harus dideklarasikan dahulu sebelum digunakan. Deklarasi array berisi tipedata array, nama array, dan jumlah elemen yang dimilikinya. Sintaksis deklarasi array adalahsebagai berikut:

tipedataelemen namaarray[jumlahelemen];Contoh deklarasi array bernama A dengan 5 elemen integer:

int A[5];Dalam bahasa C/C++, elemen pertama suatu array diberi indeks nol, elemen kedua diberi indekssatu, dan seterusnya. Array billy dapat digambarkan sebagai berikut:

AA[0] A[1] A[2] A[3] A[4]int int int int int

Gambar 2.1

Dalam deklarasi yang tidak langsung menyertakan inisialisasi array, jumlah elemen dalam arrayharuslah didefinisikan. Sebagai contoh, pernyataan berikut tidaklah valid.

int A[]; // invalid, compile error

2.2.2 Inisialisasi Array Satu Dimensi

Setelah dideklarasikan, array dapat didefinisikan atau diisi dengan nilai-nilai. Inisialisasi array dapatdilakukan dengan beberapa cara berikut.

17

1. Inisialisasi dalam satu pernyaatan dengan deklarasi

Contoh:

int Ai[4] = {2,4,5,7};float Af[] = {2.2,4,6.5,8};char Ac[] = {‘i’,’a’};int B[4] = {1,3};

Sebagai catatan, jika jumlah elemen array dalam kurung tegak [] di sebelah kiri tandapenugasan (=) dideklarasikan, maka jumlah elemen ini harus sama dengan atau lebih besardaripada jumlah dari elemen yang dinisialisaskikan dalam kurung kurawal {} di sebelah kanantanda penugasan. Hal ini terlihat pada contoh inisialisasi array Ai dan B di atas.

Sementara itu, jika jumlah elemen array dalam kurung tegak [] di sebelah kiri tandapenugasan (=) tidak dideklarasikan, maka jumlah elemen array-nya adalah jumlah darielemen yang dinisialisasikan dalam kurung kurawal {} di sebelah kanan tanda penugasan.Contohnya adalah pada inisialisasi array Af dan Ac di atas.

Jika jumlah elemen array dalam kurung tegak [] di sebelah kiri tanda penugasan (=) lebihbesar daripada jumlah dari elemen yang dinisialisasikan dalam kurung kurawal {} di sebelahkanan tanda penugasan, maka jumlah elemen yang valid adalah yang di sebelah kiri tandapenugasan. Elemen yang tidak tertulis akan by default diber nilai nol (0). Contohnya adalahpada inisialisasi array B di atas. Elemen-elemen dari B adalah 1, 3, 0, dan 0.

Ai 2 4 5 7Ai[0] Ai[1] Ai[2] Ai[3]Int int int int

Af 2.2 4 6.5 8Af[0] Af[1] Af[2] Af[3]Float float float float

Ac 'i' 'a'Ac[0] Ac[1]Char char

Ai 1 3 0 0Ai[0] Ai[1] Ai[2] Ai[3]int int int int

Gambar 2.2

2. Inisialisasi elemen-elemen array secara individu melalui indeksnya masing-masing

18

Sintaksis pengisian nilai ke dalam indeks tertentu dari sebuah array:

namaarray[indeksarray] = nilai;Contoh:

double Ad[3]; // deklarasi arrayAd[0] = 3.3; // inisialisasi elemen dari Ad pada indeks ke-0Ad[1] = 1.5; // inisialisasi elemen dari Ad pada indeks ke-1Ad[2] = 2.43; // inisialisasi elemen dari Ad pada indeks ke-2

Ad 3.3 1.5 2.43Ad[0] Ad[1] Ad[2]

double double double

Gambar 2.3

Jika nilai-nilai elemen array memiliki pola tertentu, inisialisasinya dapat memanfaatkanmekanisme seleksi dan/atau perulangan. Contohnya, array X yang berisi bilangan bulat antara1 dan 5, inklusif. Deklarasi dan inisialisasi tersebut adalah sebagai berikut:

int X[5];for(int i=0; i<5; i++){

X[i]=i+1;}

2.2.3 Akses array satu dimensi

Setelah sebuah array didefinisikan, elemen array dapat diakses dengan cara memanggil nama dannomor indeksnya, seperti ekspresi berikut ini:

namaarray[indeksarray]Sebagai contoh, lihat pernyataan berikut:

int Ai[4] = {2,4,5,7}; // deklarasi Aiprintf(“Elemen pada indeks ke-2 dari Ai: %d\n”, Ai[2]);//akses A[2]

Contoh lainnya, sebuah array S yang tiap elemennya dicetak ke monitor dapat ditulis sebagaiberikut:

char S[]={‘s’,’a’,’l’,’a’,’m’};for(int i=0; i<5; i++){

printf(“Elemen pada indeks ke-%d dari S: %c\n”,i,S[i]);}

19

2.2.4 Array dan Pointer

Array memiliki hubungan erat dengan pointer. Dalam banyak kesempatan, array dikatakan“ekivalen” dengan pointer. Ekivalen di sini tidak berarti sama persis. Keduanya berbeda, tetapidapat digunakan secara berkaitan. Perhatikan contoh berikut:

int A[4] = {2,4,5,7}; // deklarasi ASeperti telah diketahui, elemen pada indeks ke-0 dan ke-1 dalam Ai dapat diakses dan dimodifikasidengan cara berikut:

A[0]=3; A[1]=10;Dengan ekivalensi antara array dan pointer, kedua elemen di atas dapat diakses dan dimodifikasidengan cara berikut:

*A=3; *(A+1)=10;Hal ini dapat terjadi karena variabel array A dapat dianggap sebagai sebuah variabel pointer A.Sebagai sebuah pointer, A berisikan alamat elemen pertama (indeks ke-0) dari array A, yaituA[0].

Untuk lebih memahami hubungan pointer dan array, kerjakan dan analisis kode pada gambar 2.4berikut.

123456789101112131415161718192021222324

#include <stdio.h>#include <stdlib.h>

int main(){// Deklarasi dan inisialisasi Aint A[4]={2,4,5,7};

// Akses dan modifikasi dengan 'cara array'A[0]=10; A[1]=20;

// Akses dan modifikasi dengan 'cara pointer'*(A+2)=30; *(A+3)=40;

// Tampilkan nilai A, alamat A, alamat A[0]printf("A: %d, &A: %d, &A[0]: %d\n\n",A,&A,&A[0]);

// Cetak tiap elemen ke monitor dengan 'cara array'for(int i=0; i<4; i++){

printf("Elemen pada indeks ke-%d dari A: %d\n",i,A[i]);printf("Alamat elemen pada indeks ke-%d dari A: %d\n",

i,&A[i]);}

// Deklarasi pointer variabel

20

252627282930313233343536373839

int *p;// Inisialisasi p dengan Ap = A;

// Cetak tiap elemen ke monitor dengan 'cara array'for(int i=0; i<4; i++){

printf("Elemen pada indeks ke-%d dari p: %d\n",i,p[i]);}

// Pernyataan di bawah ini invalid, A adalah pointer konstan// A = p;

system("PAUSE");return 0;

}Gambar 2.4

Perhatikan bagaimana dua cara yang berbeda untuk mengisikan nilai pada elemen array (baris ke-9 dan ke-12) ternyata memberikan efek yang sama. Perhatikan juga baris ke-17 sampai ke-22.Cobalah untuk membuat kode yang memiliki tujuan yang sama dengan yang berada pada baris ini,tetapi dengan ‘cara pointer’.

Kemudian lihatlah baris ke-24 sampai selesai. Di sana sebuah pointer p dideklarasikan, diinisialisasidengan A, dan seluruh elemennya ditampilkan menggunakan ‘cara array’. Hal ini menunjukkanbahwa p memiliki tipe data yang kompatibel dengan A. Ketika baris ke-27 dieksekusi, hubungan pdan A dapat diilustrasikan sebagai berikut:

Gambar 2.5

Sekarang perhatikan baris ke-35. Coba hilangkan tanda // sehingga pernyataan A = pdikompilasi. Perhatikan hasilnya. Walaupun A dapat dilihat sebagai pointer, tetapi dia tidak dapatditugasi (assigned) atau diisikan dengan nilai pointer lain. Sekali array dideklarasikan, pointernyaakan selalu menunjuk pada elemen yang sama, yaitu elemen pertama (indeks ke-0) dari arraytersebut, tidak dapat diubah ke alamat memori lain. Dengan demikian variabel array disebut jugasebagai sebuah pointer konstan.

Amati juga keluaran program ini oleh baris ke-15. Dari pengamatan nilai A dan alamat A[0],terlihat bahwa A dapat dilihat sebagai pointer yang menunjuk pada atau berisi alamat A[0]. Ada

21

hal lain yang menarik di sini. Alamat A ternyata juga memiliki nilai yang sama dengan nilai A danalamat A[0]. Hal ini mungkin nampak membingungkan. Masalah ini tidak akan dibahas lebihdalam di sini. Kesimpulan sementara yang dapat ditarik adalah bahwa C/C++ memangmemperlakukan array seperti ini untuk mendukung konsep bahwa array bisa dilihat sebagaisebuah pointer dan dia adalah pointer konstan.

2.2.5 Array sebagai Parameter Fungsi

Array dapat dikirimkan sebagai parameter sebuah fungsi. Untuk bisa menerima parameter arrayini, fungsi itu perlu didefinisikan dengan parameter formal pointer yang menunjuk pada tipe datayang sesuai dengan tipe data elemen array tersebut. Dengan kata lain, array tersebut harusdikirim by reference. Prototipe fungsi tersebut dituliskan dalam sintaksis berikut:

tipedatakembalian namafungsi(tipedata *parameterformal);atau

tipedatakembalian namafungsi(tipedata parameterformal[]);atau

tipedatakembalian namafungsi(tipedata parameterformal[jumlahelemen]);Gambar berikut mencontohkan penggunaan array sebagai parameter fungsi.

12345678910111213

#include <stdio.h>#include <stdlib.h>

void cetakElemen(int *A, int index){printf("Elemen pada indeks ke-%d: %d\n",index,A[index]);

}

int main(){int X[]={7,8,9,10};cetakElemen(X,2);system("pause");return(0);

}Gambar 2.6

2.3 Array Multidimensi

Selain berdimensi satu, array juga dapat bermultidimensi. Array multidimensi disebut juga ‘array ofarrays’. Contoh array multidimensi adalah array dua dimensi.

22

2.3.1 Deklarasi Array Dua Dimensi

Deklarasi array dua dimensi terdiri dari tipe data array, nama array, jumlah elemen pada dimensipertama, dan jumlah elemen pada dimensi kedua. Sintaksis deklarasi array adalah sebagai berikut:

tipedataelemen namaarray[jumlahelemendimensi1][jumlahelemendimensi2];Array dua dimensi sering dimodelkan sebagai sebuah matriks dua dimensi yang memiliki baris dankolom. Dimensi pertama array tersebut direpresentasikan sebagai baris dan dimensi kedua sebagaikolom. Contoh deklarasi sebuah array dua dimensi:

int A[2][3]; // array dengan 2 baris dan 3 kolomArray A ini dapat dibayangkan seperti sebuah matriks pada gambar 2.7.

Kolom 0 Kolom 1 Kolom 2Baris 0 A[0][0] A[0][1] A[0][2]Baris 1 A[1][0] A[1][1] A[1][2]

Gambar 2.7

Walaupun array dua dimensi ini bisa dilihat sebagai matriks dua dimensi, tetapi dalam memorielemen-elemen array ini tersusun secara linier dengan urutan seperti pada gambar 2.8.

namaelemen nilai alamatA[0][0] 2293520A[0][1] 2293524A[0][2] 2293528A[1][0] 2293532A[1][1] 2293536A[1][2] 2293540

Gambar 2.8

2.3.2 Inisialisasi Array Dua Dimensi

Sebagaimana array satu dimensi, inisialisasi array dua dimensi dapat dilakukan dengan beberapacara berikut.

1. Inisialisasi dalam satu pernyaatan dengan deklarasi

Contoh:

int A[3][4] = {{2,4,5,5},{7,9,11,5},{0,2,2,1}};int B[2][3] = {3,5,7,9,0,4};int C[2][3] = {1,10,5,6};

23

int D[3][2] = {{1},{10,5},{6}};Aturan pengisian nilai elemen dalam array dua dimensi mengikuti aturan “row major order”(RMO). Untuk mengetahui bagaimana RMO bekerja untuk setiap array di atas, perhatikanilustrasi untuk definisi A, B, C, dan D di bawah ini, lalu ambil kesimpulannya.

int A[3][4] = {{2,4,5,5},{7,9,11,5},{0,2,2,1}};

A Kolom 0 Kolom 1 Kolom 2 Kolom 3Baris 0 2 4 5 5Baris 1 7 9 11 5Baris 2 0 2 2 1

int B[2][3] = {3,5,7,9,0,4};B Kolom 0 Kolom 1 Kolom 2

Baris 0 3 5 7Baris 1 9 0 4

Jadi int B[2][3] = {3,5,7,9,0,4}; ekivalen dengan

int B[2][3] = {{3,5,7},{9,0,4}};

int C[2][3] = {1,10,5,6};C Kolom 0 Kolom 1 Kolom 2

Baris 0 1 10 5Baris 1 6 0 0

Jadi int C[2][3] = {1,10,5,6}; ekivalen dengan

int C[2][3] = {1,10,5,6};

int D[3][2] = {{1},{10,5},{6}};D Kolom 0 Kolom 1

Baris 0 1 0Baris 1 10 5Baris 2 6 0

Jadi, int D[3][2] = {{1},{10,5},{6}}; ekivalen dengan

int D[3][2] = {{1},{10,5},{6}};

2. Inisialisasi elemen-elemen array secara individu melalui indeksnya masing-masing

24

Sintaksis pengisian nilai ke dalam indeks tertentu dari sebuah array:

nama_array[indeks_pada_dimensi1][indeks_pada_dimensi2]=nilai;Contoh:

double A[2][3]; // deklarasi arrayA[0][0] = 3.3; // inisialisasi A[0][0]A[1][1] = 1.5; // inisialisasi A[1][1]A[2][0]= 2.43; // inisialisasi A[2][0]// dst.

Jika nilai-nilai elemen array memiliki pola tertentu, inisialisasinya dapat memanfaatkanmekanisme seleksi dan/atau perulangan. Contohnya, deklarasi dan inisialisasi array 2x2 B yangberelemen integer dengan nilai masing-masing 0,0,1, dan 1, sebagai berikut:

int B[2][2];for(int i=0; i<2; i++){

for(int j=0; j<2, j++){B[i][j]=i;

}}

2.3.3 Akses Array Dua Dimensi

Setelah sebuah array dua dimensi didefinisikan, elemen array dapat diakses dengan caramemanggil nama dan nomor indeks sesuai dimensinya, seperti ekspresi berikut ini:

namaarray[indekspadadimensi1][indekspadadimensi2]Sebagai contoh, lihat pernyataan berikut:

int A[2][3] = {2,4,5,7}; // deklarasi Aprintf(“A[2][3]: %d\n”, A[2][3]); // akses A[2][3]Contoh lainnya, sebuah array B yang tiap elemennya dicetak ke monitor dapat ditulis sebagaiberikut:

char B[2][2]={1,1,5,2,4};for(int i=0; i<2; i++){

for(int j=0; j<2;i++){printf(“B[%d][%d]:%d\n”,i,j,B[i][j]);

}

2.3.4 Array Dua Dimensi sebagai Parameter Fungsi

Seperti pada array satu dimensi, pengiriman parameter array dua dimensi pada fungsi jugadilakukan by reference. Prototipe fungsi tersebut dapat dituliskan dalam sintaksis berikut:

tipedatakembalian namafungsi(tipedata **parameterformal);atau

25

tipedatakembalian namafungsi(tipedata parameterformal[][jumlahelemen]);atau

tipedatakembalian namafungsi(tipedata parameterformal[jumlahelemen][jumlahelemen]);Gambar 2.9 berikut mencontohkan penggunaan array sebagai parameter fungsi.

1234567891011121314151617

#include <stdio.h>#include <stdlib.h>

void cetak(int A[2][3]){for(int i=0; i<2; i++){

for(int j=0; j<3; j++){printf("A[%d][%d]=%d\n",i,j,A[i][j]);

}}

}

int main(){int Y[2][3]={1,2,3,4};cetak(Y);system("pause");return(0);

}

Gambar 2.9

2.4 Tugas

Tugas yang relevan dengan topik bab ini diberikan oleh dosen/asisten praktikum.

Tugas bab ini dapat dikombinasikan dengan tugas bab lain atas arahan dan ijin dosen/asistenpraktikum.

Tugas bab ini dikumpulkan kepada dosen/asisten sesuai format yang diminta.

26

3 BAB 3: Pointer Lanjutan - Alokasi Memori Dinamik

Pokok bahasan:

Alokasi memori dengan malloc dan new

Dealokasi memori dengan free dan delete

Realokasi memori dengan realloc

27

3.1 Pendahuluan

Pada bab sebelumnya telah dijelaskan tentang konsep dasar pointer dan bagamainamendeklarasikan dan mendefinisikannya dengan cara referensi. Contoh-contoh yang diberikansetelah itu untuk inisialisasi atau pendefinisian pointer hanya menggunakan cara referensi, yaitumembuat atau mengubah nilai pointer itu sehingga menunjuk ke variabel yang sudah adasebelumnya. Sesungguhnya ini hanya salah satu cara, masih ada yang lainnya. Kita dapatmembuat pointer tersebut menunjuk ke lokasi data yang baru yang belum dimiliki oleh variabelmanapun. C/C++ menyediakan fasilitas untuk mengaplikasikan cara kedua di atas.

3.2 Pengalokasian Memori Secara Dinamik

Proses membuat pointer menunjuk ke lokasi data yang baru yang belum dimiliki oleh variabelmanapun dinamakan alokasi memori dinamik dan pointernya sendiri sering disebut dengan pointerdinamik. Kondisi ini disebut dinamik karena dua hal. Pertama, jumlah rangkaian memori yangdialokasikan dapat diubah oleh pemrogram atau berdasarkan masukan pengguna, selamamemorinya tersedia. Dengan demikian kita dapat membuat semacam array ‘dinamik’ yang jumlahelemennya dapat diubah-ubah, mengatasi keterbatasan array konstan yang jumlah elemennyaselalu tetap. Kedua, pengalokasian memori ini dilakukan saat eksekusi program atau run-time. Halini memungkinkan kita untuk meminta pengguna memasukkan jumlah elemen dari array ‘dinamik’tersebut.

Konsep yang akan dibahas berikutnya adalah fasilitas C/C++ yang dapat digunakan untukimplementasi alokasi memori dinamik

3.2.1 Fungsi mallocUntuk mengalokasikan memori secara dinamik kita dapat menggunakan fungsi malloc yangterdapat pada pustaka standar C. Prototipe fungsi ini memiliki sintaksis berikut:void * malloc(size_t size);Parameter:

Parameter fungsi ini (size) adalah ukuran blok memori dalam bytes yang dipesan kemalloc.

Kembalian:

Jika pemesanan memori sukses, fungsi ini mengembalikan sebuah pointer yang menunjukpada awal blok tersebut. Isi dari blok-blok tersebut tidak diinisialisasikan (tidak terdefinisi).

28

Tipe data kembalian fungsi ini adalah void*, yang dapat di-cast (dikonversi paksa) ke tipedata yang bisa didereferensikan.

Jika alokasi memori gagal, sebuah null pointer akan dikembalikan.

Perhatikan contoh penggunaan malloc pada gambar 3.1 di bawah ini.

123456789101112131415161718192021222324252627282930313233

#include <stdio.h>#include <stdlib.h>

int main(){int *A, *B;

A=(int*)malloc(sizeof(int));if(A!=NULL){

*A = 100;printf("*A=%d\n",*A);

}else{

printf("Alokasi memori gagal.");}

B=(int*)malloc(5*sizeof(int));if(B!=NULL){

for(int i=0; i<5; i++){*(B+i) = i;printf("*(B+%d)=%d\t",i,*(B+i));printf("B[%d]=%d\n",i,B[i]);

}}else{

printf("Alokasi memori gagal.");}free(A);A = NULL;free(B);B = NULL;system("pause");return 0;

}Gambar 3.1

Pada contoh di atas dua buah pointer dideklarasikan kemudian dialokasikan memori yang ditunjukoleh mereka. Perhatikan baris ke-7 dan ke-16, lalu amati perbedaan dari keduanya. Ambilkesimpulan dari perbedaan tersebut dan bandingkanlah dengan gambar 3.2 di bawah ini.

29

Gambar 3.2

Perhatikan juga pernyataan kondisional pada baris ke-7 sampai ke-15, dan pada baris ke-16sampai ke-22. Pikirkanlah kenapa pernyataan kondisional ini diperlukan.

Cobalah amati baris ke-20 dan ke-21 berikut keluarannya pada monitor. Ambillah kesimpulan darikedua pernyataan pada baris-baris tersebut.

3.2.2 Operator newOperator new adalah operator dalam C++ (bukan C) yang memiliki kegunaan yang sama denganmalloc. Operator ini memiliki sintaksis penggunaan yang lebih singkat daripada milik malloc,seperti berikut:

namapointer = new tipedata;atau

namapointer = new tipedata[jumlahelemen];Cobalah untuk mengubah kode pada gambar 3.1 untuk alokasi memori dinamik dari mallocmenjadi new.

3.3 Dealokasi atau Pembebasan Memori

Memori yang dialokasikan dengan malloc atau new dapat bertahan sampai program usai. Selamaitu, walaupun sudah tidak digunakan lagi, memori tersebut tidak dibebaskan secara otomatis olehprogram atau sistem operasi. Pemrogram harus membebaskan memori itu secara eksplisit. C/C++menyediakan sarana ini dengan fungsi free (C) dan operasi delete (C++) yang akan dijelaskansebentar lagi.

Sebagai catatan, kebanyakan program menggunakan memori untuk keperluan singkat. Suatu saatdia dibutuhkan, setelah itu tidak lagi. Karena kapasitas memori terbatas, sebaiknya memori yangsudah tidak dipakai dibebaskan agar dapat digunakan untuk operasi yang lainnya.

30

3.3.1 Fungsi freeProtitpe fungsi free memiliki bentuk sebagai berikut:

void free(void * ptr);Parameter:

Parameter fungsi ini (ptr) adalah pointer yang menunjuk pada blok memori yang akandibebaskan dan sebelumnya dialokasikan dengan malloc atau fungsi lainnya, . Jika ptrbernilai NULL, maka fungsi ini tidak melakukan apa-apa.

Kembalian:

Fungsi ini tidak memberikan nilai kembalian.

Catatan:

Walaupun fungsi ini membebaskan blok memori yang ditunjuk oleh ptr, nilai ptr tetap samadengan sebelumnya (alamat memori yang sudah dibebaskan), bukan NULL. Blok memoribebas sudah dapat digunakan oleh operasi lain. Mungkin ini agak membingungkan, tetapiseperti inilah implementasi fungsi free pada bahasa C. Untuk mencegah kesalahan dalampenggunan ptr berikutnya (agar ptr tidak dikira bernilai NULL), setelah operasi freetuliskan:

ptr = NULL;atau

ptr = 0;Contoh penggunaan fungsi ini dapat dilihat pada baris ke-27 sampai ke-30 pada gambar 3.1sebelumnya.

3.3.2 Operator deleteOperator ini memiliki fungsi yang sama dengan free pada C. Sintaksis penggunaan operator iniadalah:

/* untuk pointer yang menunjuk pada satu blok memori yang berisi 1 unittipe data tertentu */delete ptr;atau

/* untuk pointer yang menunjuk pada satu blok memori yang berisi lebihdari 1 unit tipe data tertentu*/delete [] ptr;

31

Cobalah untuk mengubah kode pada gambar 3.1 untuk pembebasan memori dinamik, dari freemenjadi delete.

3.4 Realokasi Memori

Sebuah pointer yang sudah dialokasikan dengan malloc atau fungsi lainnya dapat direalokasikankembali untuk mengubah ukuran dari memori yang ditunjuknya. Fungsi yang dapat digunakanadalah realloc dan bentuk dari prototipenya adalah sebagai berikut:

void * realloc(void * ptr, size_t size);

Parameter:

ptr: Pointer yang akan direalokasikan dan sebelumnya menunjuk pada blok memori yangdialokasikan dengan malloc atau fungsi lainnya. Jika ptr bernilai NULL, maka fungsi iniakan mengalokasikan blok memori baru dan pointer yang menunjuk pada blok inidikembalikan oleh fungsi ini.

size: Ukuran baru memori yang akan dialokasikan dalam bytes. Jika size bernilai 0,maka blok memori yang sebelumnya dialokasikan untup ptr akan dibebaskan dan sebuahNULL pointer akan dikembalikan oleh fungsi ini.

Kembalian:

Fungsi ini mengembalikan sebuah pointer yang menunjuk pada blok memori yang telahdirealokasikan. Blok memori ini mungkin berlokasi sama dengan yang sebelumnya atauberada pada lokasi baru.

Tipe pointer ini adalah void*, yang dapat di-cast (dikonversi paksa) ke tipe data pointeryang diinginkan agar dapat didereferensi.

Isi dari blok memori yang lama akan dipertahankan sampai sejumlah ukuran blok memoriyang baru. Jika ukuran blok memori yang baru lebih besar dari yang lama, isi dari bagianmemori yang baru ini tidak terdefinisi.

Jika Jika fungsi ini gagal merealokasikan blok memori yang diminta, sebuah NULL pointerakan dikembalikan dan ptr tetap menunjuk pada blok memori yang lama.

Sebagai contoh aplikasi fungsi realloc, cobalah untuk menambahkan kode di antara baris ke-26dan ke-27 pada gambar 3.1 yang merealokasikan pointer A dan B masing-masing ke 5 unitmemori baru sesuai tipe data masing-masing. Selanjutnya isikan blok memori baru dari A dengan5 bilangan ganjil mulai dari bilangan 1 dan blok memori baru dari B dengan 5 bilangan genapmulai dari bilangan 2. Tampilkan seluruh isi blok memori dari A dan B ke layar monitor.

32

3.5 Tugas

Tugas yang relevan dengan topik bab ini diberikan oleh dosen/asisten praktikum.

Tugas bab ini dapat dikombinasikan dengan tugas bab lain atas arahan dan ijin dosen/asistenpraktikum.

Tugas bab ini dikumpulkan kepada dosen/asisten sesuai format yang diminta.

33

4 BAB 4: String

Pokok bahasan:

Array of characters

Deklarasi string

Inisialisasi dan pendefinisian string

Penanganan string

34

4.1 Pendahuluan

Sebuah string pada dasarnya adalah serangkaian karakter yang disusun berurutan. Sementara itukarakter sendiri adalah simbol yang diambil dari satu set alphabet tertentu. Dalam bahasa C, stringini dapat diimplementasikan dalam array yang berlemen karakter alias array of characters denganserangkaian karakter yang diakhiri dengan karakter null. Selanjutnya untuk mendeklarasikan danmendefinisikan string, ada beberapa cara yang dapat dilakukan, seperti yang akan dibahas dalamsub bab berikutnya.

Dalam bahasa C++, string sudah diimplementasikan sebagai sebuah tipe data tersendiri yangdidefinisikan dalam pustaka standar C++. String dengan model ini berada di luar bahasan bab ini.

4.2 Deklarasi String

4.2.1 Deklarasi via Array of Characters

Sebagai array of characters, string dapat dideklarasikan dengan sintaksis sebagai berikut:

tipedatachar namastring[jumlahelemen];Sebagai contoh, untuk mendeklarasikan sebuah string bernama str yang akan memilikimaksimum 15 buah karakter (termasuk karakter null), pernyataannya adalah:

char str[5];Saat pernyataan ini dijalankan, str dialokasikan 5 unit memori bertipe char seperti diilustrasikanpada gamber 4.1 berikut. Cara menginisialisasi string ini akan dibahas pada sub bab berikutnya.

strstr[0] str[1] str[2] str[3] str[4]char char Char char char

Gambar 4.1

4.2.2 Deklarasi via Pointer

Seperti telah diketahui, array adalah pointer konstan. Variabel bertipe array menyimpan alamatdari elemennya yang pertama (indeks ke-0) sejak dideklarasikan sampai seterusnya. Selain itu,array juga memiliki ‘ekivalensi’ dengan pointer umumnya (sub bab 2.2.4). Karena kedekatan ini,sebuah pointer to character dapat dideklarasikan untuk menunjuk pada sebuah string dengan carareferensi ke array string yang ada maupun dengan alokasi memori dinamik.

35

Referensi

Proses ini sebenarnya tidak sepenuhnya merupakan deklarasi sebuah string. Hal ini karena stringyang ditunjuk oleh pointer yang bersangkutan sebenarnya sudah dideklarasikan sebelumnya viaarray of characters. Di bawah ini adalah contoh deklarasi sebuah pointer yang kemudian disetuntuk menunjuk pada sebuah string yang belum terdefinisi.

char str[5];char * p;p = str;

str[0]

str[2]

str[1]

str[3]str[4]

char str[5];

char *p; p

str[0]

str[2]

str[1]

str[3]str[4]

pp = str;

Gambar 4.2

Inisialisasi string ini akan dibahas pada sub bab selanjutnya.

Alokasi memori dinamik

Untuk mengalokasi memori secara dinamik, kita dapat menggunakan fungsi malloc atau fungsilain yang relevan (lihat bab 3). Memori yang dialokasikan akan digunakan untuk menampungkarakter pada string yang bersangkutan. Berikut contoh deklarasi pointer to char andpengalokasian memorinya untuk membuat sebuah string.

char * p;p = (char*)malloc(5*sizeof(char));Proses ini dapat diilustrasikan sebagai berikut:

36

char *p; p

p[0]

p[2]

p[1]

p[3]p[4]

pp=(char*)malloc(5*sizeof(char));// jika alokasi memori berhasil

Gambar 4.3

Inisialisasi string ini akan dibahas pada sub bab selanjutnya.

4.3 Inisialisasi dan Pendefinisian String

Setelah dideklarasikan, string dapat diinisialisasikan atau didefinisikan dengan beberapa caraberikut.

4.3.1 Inisialisasi via Array

1. Inisialisasi dalam satu pernyaatan dengan deklarasi

Contoh:

char s1[] = {‘h’,’i’,’\0’};char s2[8] = {‘h’,’e’,’l’,’l’,’o’,’\0’};char s3[] = “salam”;

Inisialisasi s1 dan s2 adalah inisialisasi dengan cara yang ‘primitif’, yaitu dengan menuliskansetiap karakter satu per satu dalam {}. Aturan array untuk penulisan jumlah elemen array(lihat bab 2) tetap berlaku. Yang harus diingat juga adalah bahwa sebuah string (yang valid)harus diakhiri dengan karakter null atau karakter nol (‘\0’).

37

Gambar 4.4

Perhatikan hasil inisialisasi s2 pada gambar 4.4. Di sini s2 diinisialisi dengan 6 karakter tertulis(termasuk karakter null), tetapi sebenarnya s2 tetap memiliki 8 karakter seperti deklarasinya.Sisa karakter yang tidak didefinisikan menempati s2[6] dan s2[7] digambarkan dengankotak yang diarsir, biasanya diisikan dengan nilai default karakter null.

Sementara itu, s3 diinisialisasi dengan konstanta atau literal string “salam”. Inisialisasi iniekivalen dengan pernyataan berikut:

char s3[] = {‘s’,’a’,’l’,’a’,’m’,’\0’};Jika diilustrasikan, inisialisasi ini akan menghasilkan kondisi berikut:

Gambar 4.5

2. Inisialisasi elemen-elemen array secara individu melalui indeksnya masing-masing

Cara ini juga masih dianggap cara yang ‘primitif’. Sintaksis pengisian nilai ke dalam indekstertentu dari sebuah array string:

namastring[indeksarray] = nilai;Contoh:

char str[3]; // deklarasi string via arraystr[0] = ‘h’; // inisialisasi elemen dari str pada indeks ke-0str[1] = ‘i’; // inisialisasi elemen dari str pada indeks ke-1str[2] = ‘\0’; // inisialisasi elemen dari str pada indeks ke-2

38

3. Inisialisasi dengan menyalin dari sebuah konstanta string atau isi string lainnya dengan fungsistrcpy

Cara ini lebih sering dipakai karena lebih praktis. Contoh penyalinan string:

char str1[15];char str[] = “Selamat pagi”;strcpy(str1,”Hello World”);// Coba cek isi str1printf(“str1: %s\n”, str1);strcpy(str1,str2);// Coba cek isi str1printf(“str1: %s\n”, str1);Untuk membuat program yang aman, panjang string yang akan disalin ke array targetharuslah sama dengan atau lebih kecil daripada ukuran array target penyalinan dikurangi satu.Hal ini untuk menghindari inisialisasi atau pendefinisian nilai yang melewati batas array.

Perlu diingat, ukuran array selalu konstan sejak dideklarasikan. strcpy tidak dapatmenambah ukuran array target penyalinan untuk menampung string yang lebih panjangdaripada batas array ini.

4.3.2 Inisialisasi via Pointer

Inisialisasi string via pointer digunakan untuk array string yang ditunjuk oleh pointer denganreferensi atau yang dideklarasikan melalui pointer dinamik.

Referensi

Inisialisasi dengan cara ini melanjutkan deklarasi string via pointer yang sudah dibahassebelumnya (sub bab 4.2.2). Jika terdapat pernyataan berikut:

char str[5];char * p;p = str;maka kita dapat menggunakan pointer p untuk mengisikan string str baik secara per karaktermelalui indeksnya atau per string dengan fungsi strcpy. Contoh:

// pengisian per karakter untuk membuat string “you”p[0]=’y’; p[1]=’o’; p[2]=’u’; p[3]=’\0’;// Coba cek isi p dan strprintf("p: %s, str: %s\n", p,str);for(int i=0; i<5; i++){

printf("p[%d]:%c, \t", i,p[i]);printf("str[%d]:%c\n", i,str[i]);

}

39

// mengganti isi string str dengan “kamu” via strcpystrcpy(p,”kamu”);// Coba cek lagi isi p dan strprintf("p: %s, str: %s\n", p,str);for(int i=0; i<5; i++){

printf("p[%d]:%c, \t", i,p[i]);printf("str[%d]:%c\n", i,str[i]);

}

str[0]

str[2]

str[1]

str[3]str[4]

char str[5];

char *p; p

str[0]

str[2]

str[1]

str[3]str[4]

pp = str;

str[0]

str[2]

str[1]

str[3]

‘y’

‘o’

‘u’

‘\0’str[4]

pp[0] = ‘y’;p[1] = ‘o’;p[2] = ‘u’;p[3] = ‘\0’;

str[0]

str[2]

str[1]

str[3]

‘k’

‘a’

‘m’

‘u’

‘\0’str[4]

pstrcpy(p,”kamu”);

Gambar 4.6

Alokasi memori dinamik

Setelah sebuah pointer dialokasikan memori secara dinamik dengan cara berikut:

char * p;

40

p = (char*)malloc(5*sizeof(char));maka, seperti juga pada cara referensi, kita bisa mengisikan mengisikan string str baik secara perkarakter melalui indeksnya atau per string dengan fungsi strcpy. Contoh:

// pengisian per karakter untuk membuat string “you”p[0]=’y’; p[1]=’o’; p[2]=’u’; p[3]=’\0’;// Coba cek isi pprintf(“p: %s\n”, p);for(int i=0; i<5; i++){

printf("p[%d]:%c, \t", i,p[i]);printf("str[%d]:%c\n", i,str[i]);

}// mengganti isi string str dengan “saya” via strcpystrcpy(p,”saya”);// Coba cek lagi isi pprintf(“p: %s\n”, p);for(int i=0; i<5; i++){

printf("p[%d]:%c, \t", i,p[i]);printf("str[%d]:%c\n", i,str[i]);

}char *p; p

p[0]

p[2]

p[1]

p[3]p[4]

pp=(char*)malloc(5*sizeof(char));// jika alokasi memori berhasil

p[0]

p[2]

p[1]

p[3]

‘y’

‘o’

‘u’

‘\0’p[4]

pp[0] = ‘y’;p[1] = ‘o’;p[2] = ‘u’;p[3] = ‘\0’;

p[0]

p[2]

p[1]

p[3]

‘s’

‘a’

‘y’

‘a’

‘\0’p[4]

pstrcpy(p,”saya”);

Gambar 4.7

41

4.4 Penanganan String

Ada banyak fungsi dalam pustaka standar C yang dapat dipakai untuk menangani danmemanipulasi string. Di antaranya adalah strlen, strcmp, strcpy, strncpy, strcat.

4.4.1 Fungsi strlenDeklarasi:

size_t strlen(const char *str);Fungsi ini menghitung panjang string str, mengembalikan jumlah karakter pada string, tapi tidaktermasuk karakter null pemberhenti string. size_t adalah unsigned int.

Contoh:

int len;char *string;len = strlen (string);

4.4.2 Fungsi strcmpDeklarasi:

int strcmp(const char *str1, const char *str2);Fungsi ini membandingkan dua buah string, yang ditunjuk oleh str1dan yang ditunjuk oleh str2.

Jika str1 and str2 memiliki nilai string yang sama (equal, bukan identical), fungsi inimengembalikan 0.

Jika str1 < str2 (sesuai urutan alfabetiknya pada tabel ASCII), fungsi ini mengembalikan nilaikurang dari 0.

Jika str1 > str2 (sesuai urutan alfabetiknya pada tabel ASCII), fungsi ini mengembalikan nilai lebihdari 0.

Contoh:

int value;char *s1,*s2;value = strcmp(s1,s2);

4.4.3 Fungsi strcpyDeklarasi:

42

char *strcpy(char *str1, const char *str2);Fungsi ini menyalin string yang ditunjuk oleh str2 ke str1. Penyalinan ini sampai dan mencakupkarakter null pemberhenti pada str2. Jika str1 dan str2 overlap , perilakunya tidak terdefinisi.

Fungsi ini mengembalikan argument str1.

Contoh:

char *to,*from;to = strcpy (to,from);

4.4.4 Fungsi strncpyDeklarasi:

char *strncpy(char *str1, const char *str2, size_t n);Fungsi ini menyalin sampai sejumlah n karakter dari string yang ditunjuk oleh str2 ke str1.Penyalinan berhenti saat n karakter tersalin atau karakter null pemberhenti pada str2 dicapai. Jikakarakter null dicapai, karakter null akan terus disalin ke str1 sampai sejumlah n karakter tersalin.

Fungsi ini mengembalikan argumen str1.

Contoh:

char *to,*from;int n;to = strncpy (to,from,n);

4.4.5 Fungsi strcatDeklarasi:

char *strcat(char *str1, const char *str2);Fungsi ini menyambungkan (concatenate) string yang ditunjuk oleh str2 ke akhir dari string yangditunjuk oleh str1. Karakter null pemberhenti dari str1 ditumpuki (overwritten). Penyalinanberhenti ketika karakter pemberhenti dari str2 telah tersalin. Jika terjadi overlapping, hasilnyatidak terdefinisi.

Fungsi ini mengembalikan argumen str1.

Contoh:

char *s1 = "string one";char *s2 = "string two";

int main (){

43

char buffer[255];strcat(buffer,s1);strcat(buffer,s2);

}

4.4.6 Fungsi strncatDeklarasi:

char *strncat(char *str1, const char *str2, size_t n);Fungsi ini menyambungkan (concatenate) string yang ditunjuk oleh str2 ke akhir dari string yangditunjuk oleh str1 sampai sepanjang n karakter. Karakter null pemberhenti dari str1 ditumpuki(overwritten). Penyalinan berhenti ketika sejmlah n karakter telah tersalin atau karakterpemberhenti dari str2 telah tersalin. Sebuah karakter null pemberhenti selalu ditambahkan kestr1. Jika terjadi overlapping, hasilnya tidak terdefinisi.

Fungsi ini mengembalikan argumen str1.

Contoh:

char *onto,*new,*this;new = strncat(onto,this,n);

4.4.7 Fungsi atofDeklarasi:double atof(const char *str);Fungsi ini mengonversi string yang ditunjuk oleh str ke tipe double (floating-point number).Karakter whitespace yang ada di awal string diabaikan (space, tab, carriage return, new line,vertical tab, atau formfeed). Konversi berhenti saat karakter tak dikenal dicapai.

Jika sukses, fungsi ini akan mengembalikan angka hasil konversi. Jika konversi tidak dapatdilakukan, fungsi ini akan mengembalikan 0. Jika nilai yang dikonversi di luar jangkauan tipedouble, HUGE_VAL akan dikembalikan dengan tanda yang sesuai dan ERANGE disimpan kevariable errno. Jika nilai yang dikonversi terlalu kecil untuk dikembalikan sesuai dengan tipedouble, maka nol akan dikembalikan dan ERANGE disimpan dalam variabel errno.

Contoh:

double x;char *stringptr;

x = atof(stringptr);

44

4.4.8 Fungsi atoiDeklarasi:

int atoi(const char *str);Fungsi ini mengonversi string yang ditunjuk oleh str ke tipe double (floating-point number).Karakter whitespace yang ada di awal string diabaikan (space, tab, carriage return, new line,vertical tab, atau formfeed). Konversi berhenti saat karakter tak dikenal dicapai.

Jika sukses, fungsi ini akan mengembalikan angka hasil konversi. Jika konversi tidak dapatdilakukan, fungsi ini akan mengembalikan 0. Jika nilai yang dikonversi di luar jangkauan tipedouble, HUGE_VAL akan dikembalikan dengan tanda yang sesuai dan ERANGE disimpan kevariable errno. Jika nilai yang dikonversi terlalu kecil untuk dikembalikan sesuai dengan tipedouble, maka nol akan dikembalikan dan ERANGE disimpan dalam variabel errno.

Fungsi ini mengonversi string yang ditunjuk oleh str ke integer (type int). Any initial whitespacecharacters are skipped (space, tab, carriage return, new line, vertical tab, or formfeed). Thenumber may consist of an optional sign and a string of digits. Conversion stops when the firstunrecognized character is reached.

On success the converted number is returned. If the number cannot be converted, then 0 isreturned.

Contoh:

int i;char *stringptr;

i = atoi(stringptr);

4.4.9 Fungsi atolDeclaration:

long int atol(const char *str);The string pointed to by the argument str is converted to a long integer (type long int). Anyinitial whitespace characters are skipped (space, tab, carriage return, new line, vertical tab, orformfeed). The number may consist of an optional sign and a string of digits. Conversion stopswhen the first unrecognized character is reached.

On success the converted number is returned. If the number cannot be converted, then 0 isreturned.

long i;char *stringptr;

45

i = atol(stringptr);

4.5 Tugas

Tugas yang relevan dengan topik bab ini diberikan oleh dosen/asisten praktikum.

Tugas bab ini dapat dikombinasikan dengan tugas bab lain atas arahan dan ijin dosen/asistenpraktikum.

Tugas bab ini dikumpulkan kepada dosen/asisten sesuai format yang diminta.

46

5 BAB 5: Struct

Pokok bahasan:

Struktur (struct)

Deklarasi tipe struct dan variabel bertipe struct

Inisialisasi dan akses anggota struct

Keyword typedef

Union (union)

Deklarasi tipe struct dan variabel bertipe struct

Inisialisasi dan akses anggota struct

47

5.1 Pendahuluan

Seiring dengan semakin kompleksnya sebuah program, data yang berada di dalamnya pun jugamenjadi bertambah kompleks. Variabel dari tipe data primitif dan array sudah tidak lagi dapatmemenuhi kebutuhan program ini. Yang dibutuhkan adalah sebuah struktur data, yang dapatmengombinasikan berbagai tipe data dalam sebuah struktur yang bermakna. Dari sinilahdiperkenalkan sebuah tipe data baru yaitu tipe struct, atau dalam bahasa lain record.

Tipe struct ini biasanya dibahas bersama dengan tipe lain yaitu union. Sebenarnya kedua tipeini memiliki tujuan yang berbeda. Bab ini akan membahas keduanya.

5.2 Struktur atau structstruct adalah sebuah paket yang terdiri dari satu atau lebih variabel yang dikelompokkan dibawah sebuah nama. struct berbeda dengan array dalam hal tipe data anggotanya; sebuahstruct dapat memiliki anggota-anggota dari tipe data yang berbeda, sementara array hanyaberisi elemen-elemen yang bertipe data sama.

5.3 Deklarasi tipe struct dan variabel bertipe structBentuk umum deklarasi tipe struct adalah sebagai berikut:

struct tipestruktur{tipeanggota1 namaanggota1;tipeanggota2 namaanggota1;...

};Kemudian jika kita hendak membuat sebuah variabel bertipe struct di atas, bentuk penulisannyaadalah:

struct tipestruktur namavariabel;Contoh deklarasi sebuah tipe struct dengan nama tertentu dan deklarasi variabel dari tipe structtersebut adalah sebagai berikut:

// deklarasi tipe struct Employeestruct Karyawan{

char id[15];char nama[20];char alamat[50];double gaji;

};// deklarasi variabel emp1 dan emp2 bertipe struct Employee

48

struct Karyawan k1;struct Karyawan k2;Perlu ditekankan bahwa struct adalah sebuah kategori tipe data yang para anggotanya dapatmemiliki tipe data berbeda-beda sesuai kebutuhan kita. Oleh karena itu, sebelum kita dapatmenggunakan sebuah struct sebagai tipe data sebuah variabel, tipe struct ini perlu kitadeklarasikan dahulu.

Pada contoh di atas struct Karyawan digunakan untuk memodelkan tipe data seorangkaryawan, yaitu memiliki id, nama, alamat, dan gaji. Selanjutnya struct Karyawan ini dapatdigunakan untuk membuat data seorang karyawan tertentu. Pada contoh di atas, k1 dan k2,masing-masing mewakili data seorang karyawan. Id, nama, alamat, dan gaji masing-masingkaryawan ini dapat diisikan atau diakses kemudian. Proses inisialisasi dan akses data ini akandibahas pada sub bab berikutnya.

Bandingkanlah metode di atas dengan jika kita memodelkan data karyawan di atas menggunakanarray. Betapa terbatasnya data karyawan yang dapat kita modelkan dengan array karena arrayhanya dapat berisi anggota atau elemen yang berasal dari tipe data yang sama.

Penulisan deklarasi di atas dapat juga disingkat menjadi:

struct Karyawan{char id[15];char nama[20];char alamat[50];double gaji;

} k1, k2;Dalam C++ deklarasi sebuah variabel yang bertipe data struct boleh menghilangkan keywordstruct, sehingga untuk contoh di atas:

struct Karyawan k1;cukup dituliskan menjadi:

Karyawan k1;

5.4 Keyword typedeftypedef digunakan untuk mengasosiasikan suatu tipe dengan simbol tertentu untuk menghindaripenulisan tipe data yang berulang. Perhatikan contoh berikut:

typedef int bilbulat;struct Karyawan{

char id[15];char nama[20];char alamat[50];

49

double gaji;};typedef Karyawan Pegawai;typedef struct {

char nim[15];char nama[20];int angkatan;

} Mahasiswa;

// sekarang bilbulat adalah suatu tipe data// x dideklarasikan sebagai bilbulat (i.e. integer)bilbulat x;x = 10;// sekarang Pegawai adalah suatu tipe data// p1 dideklarasikan sebagai Pegawai (i.e. struct Karyawan)Pegawai p1;// sekarang Mahasiswa adalah suatu tipe data// m1 dideklarasikan sebagai Pegawai MahasiswaMahasiswa m1;Dengan typedef di atas kita mendenisikan tiga tipe data: bilbulat, Pegawai, dan Mahasiswa.Setelah itu kita menggunakannya seperti tipe data biasa untuk mendeklarasikan variabel.

5.5 Inisialisasi dan Akses Anggota struct

Anggota struct dapat diinisialisasi atau diakses dengan memanggil nama variabel structtersebut diikuti dengan simbol tertentu (i.e. operator titik (.) atau operator panah (->), tergantungbagaimana variabel struct dideklarasikan) dan nama anggota yang bersangkutan. Jika variabelstruct tidak dedeklarasikan melalui pointer, maka anggotanya dapat diakses dengan sintaksisekspresi berikut:

namavariabelstruct.anggotastruct

Perhatikan contoh deklarasi struct Karyawan dan k1 sebelumnya. Untuk menginisialisasianggota k1, penulisannya adalah:

struct Karyawan k1;strcpy(k1.id, “20110521”);strcpy(k1.nama, “Lin Dan”);strcpy(k1.alamat, “Jl RRC Jakpus”);k1.gaji = 5250000;

50

5.6 Ruang Lingkup struct

struct mengikuti aturan ruang lingkup sebagaimana tipe data lainnya. Sebuat tipe structdapat menjadi global atau lokal tergantung pada di mana dia dideklarasikan. Demikian jugavariabel bertipe struct tersebut; jika dia dideklarasikan secara lokal, dia hanya dapat diakses didalam blok (yang dilingkupi oleh tanda {}) tempat dia dideklarasikan.

void buatVariabelStruct(){/* Pernyatan di bawah ini ilegal, karena A adalah struct lokalterhadap fungsi main*/struct A a;

}int main(){

struct A{int x;float y;

};

struct A a;}

5.7 Pointer to struct

Selain mendeklarasikan variabel bertipe struct, kita juga dapat membuat sebuah pointer yangmenunjuk pada obyek atau data struct, yang disebut dengan pointer to struct. Sebagai contoh,dengan menggunakan contoh struct Karyawan di atas, kita bisa mendeklarasikan sebuahpointer pk1 sebagai berikut:

struct Karyawan *pk1;Kemudian, sebelum kita dapat menginisialisasi para anggota pk1, kita harus mengalokasikan dulukepada pk1 memori dengan jumlah yang memadai. Jika kita hanya menginginkan pk1 untukmenunjuk pada satu (unit) struct Karyawan, maka alokasi memori untuk pk1 dapat dituliskansebagai berikut:

pk1 = (struct Karyawan*)malloc(sizeof(struct Karyawan));Perhatikan bahwa untuk pk1 hanya dialokasikan 1 x sizeof(struct Karyawan) bytes.Selanjutnya jika alokasi ini berhasil, para anggota pk1 dapat diinisialisasikan sebagai berikut:

strcpy(pk1->id, “007”);strcpy(pk1->nama, “James Bond”);strcpy(pk1->alamat, “London, UK”);pk1->gaji = 1000;

51

Perhatikan penggunaan simbol panah (->) di atas. Simbol ini digunakan untuk mengakses anggotastruct yang ditunjuk oleh pointer. Tanda ini bisa juga digantikan dengan kombinasi tanda bintang(*) dan titik (.) seperti pada contoh di bawah ini.

strcpy((*pk1).id, “007”);strcpy((*pk1).nama, “James Bond”);strcpy((*pk1).alamat, “London, UK”);(*pk1).gaji = 1000;

5.8 Union

Seperti struct, union dapat digunakan untuk mendeklarasikan sekelompok data yang memilikitipe berlainan. Bedanya, pada union semua data anggota tersebut menduduki lokasi memoriyang sama. Karena sebenarnya pada satu saat sebuah alamat hanya dapat menyimpan satumacam tipe data, maka pada satu saat union hanya dapat berisi salah satu dari anggotanya. Jadi,union ini berperilaku seperti sebuah kontainer berukuran tertentu yang dapat menyimpanberbagai macam tipe data.

Kegunaan utama dari union adalah untuk menghindari fragmentasi memori dengan membuatsebuah ukuran data standar pada memori. Dengan demikian kita dapat memastikan bahwa setiapbagian memori yang telah dibebaskan dari alokasi dinamik dapat dialokasikan lagi untuk variabelyang memiliki tipe union sama. Ini adalah strategi umum pemrograman sistem yang memilikibanyak variabel yang berkaitan dan dialokasikan secara dinamik.

Deklarasi, inisialisasi, akses, ruang lingkup, dan penggunaan pointer serta array pada unionmemiliki sintaksis yang sama dengan pada struct.

Untuk mengilustrasikan persamaan dan perbedaan antara struct dan union, jalankanlah kodedi bawah ini.

123456789101112131415

#include <stdio.h>#include <stdlib.h>#include <string.h>

// deklarasi tipe struct SAkunstruct SAkun{

int id;char nama[15];

};// deklarasi tipe union UAkununion UAkun{

int id;char nama[15];

};

52

1617181920212223242526272829303132333435363738394041424344454647484950515253545556575859

int main(){// deklarasi variabel bertipe struct SAkunstruct SAkun akun1;// inisialissi data anggota akun1akun1.id = 11;strcpy(akun1.nama,”Bachdim”);

// cetak data anggota akun1printf("akun1.id: %d\n", akun1.id);printf("akun1.nama: %s\n\n", akun1.nama);

// cetak alamat akun1 dan alamat anggota akun1printf("&akun1: %d\n", &akun1);printf("&akun1.id: %d\n", &akun1.id);printf("&akun1.nama:%d\n\n", &akun1.nama);

// cetak ukuran akun1 dan ukuran data anggota akun1printf("sizeof(akun1): %d\n",sizeof(akun1));printf("sizeof(akun1.id): %d\n",sizeof(akun1.id));printf("sizeof(akun1.nama): %d\n\n\n",sizeof(akun1.nama));

// deklarasi variabel bertipe union UAkununion UAkun akun2;// inisialissi data anggota akun2akun2.id = 22;strcpy(akun2.nama,”Gonzales”);

// cetak data anggota akun2printf("akun2.id: %d\n", akun2.id);printf("akun2.nama: %s\n\n", akun2.nama);

// cetak alamat akun2 dan alamat anggota akun2printf("&akun2: %d\n", &akun2);printf("&akun2.id: %d\n", &akun2.id);printf("&akun2.nama:%d\n\n", &akun2.nama);

// cetak ukuran akun2 dan ukuran data anggota akun2printf("sizeof(akun2.id): %d\n",sizeof(akun2.id));printf("sizeof(akun2.nama): %d\n",sizeof(akun2.nama));printf("sizeof(akun2): %d\n\n",sizeof(akun2));

system("PAUSE");return 0;

}Gambar 5.1

53

Secara khusus, perhatikanlah beberapa hal berikut. Amati baris ke-27sampai ke-30 dan hasileksekusinya. Hal ini menunjukkan bahwa lokasi anggota struct berbeda-beda dan alamat daristruct tersebut sama dengan alamat dari anggota struct yang dideklarasikan pertama.Bandingkanlah hasil ini dengan hasil eksekusi baris ke-47 sampai ke-50.

Kemudian, amati baris ke-32 sampai ke-35 dan hasil eksekusinya. Hal ini menunjukkan bahwaukuran dari struct sama dengan atau lebih besar sedikit daripada jumlah ukuran data anggotanya.Bandingkan hasil ini dengan hasil eksekusi baris ke-52 sampai ke-55.

Perhatikan juga baris ke-19 sampai ke-25 dan hasil eksekusinya. Bandingkan dengan baris ke-39sampai ke-45. Ambillah kesimpulan dari perbedaan hasil ini.

5.9 Tugas

Tugas yang relevan dengan topik bab ini diberikan oleh dosen/asisten praktikum.

Tugas bab ini dapat dikombinasikan dengan tugas bab lain atas arahan dan ijin dosen/asistenpraktikum.

Tugas bab ini dikumpulkan kepada dosen/asisten sesuai format yang diminta.

54

6 BAB 6: Operasi File

Pokok bahasan:

Pengertian file

Saluran I/O standar: stdin dan stdout

Penanganan file: tingkat tinggi vs tingkat rendah

Posisi program pada file

Membuka file

Menutup file

Membaca file

Menulis file

Contoh kasus

55

6.1 Pendahuluan

Bab ini akan membahas konsep file dan penggunaannya dalam bahasa C/C++. Pertama,pengertian file akan diuraikan secara singkat. Penanganan file dibagi menjadi penanganan tingkattinggi dan tingkat rendah, dan ini akan dijelaskan selanjutnya. Beberapa fungsi pada pustakastandar C untuk mengoperasikan files juga aka dibahas setelah itu. Seperti pada bab-babsebelumnya, bab ini akan diakhiri dengan tugas tentang yang operasi file, yang dapatdikombinasikan dengan tugas dalam bab lainnya.

6.2 File

C/C++ memperlakukan informasi yang masuk ke atau keluar dari program sebagai ‘aliran’ data(steam of data/bytes/bits). Dikatakan aliran karena pada proses ini data disusun secara berurutanseperti sebuah aliran, untuk dipindahkan dari satu lokasi ke lokasi lainnya. Aliran bytes inilah yangdisebut juga sebagai file.

Dengan bantuan sistem operasi, sebuah program melihat files melalui sejumlah saluran atau‘portal’ (masuk dan keluar). Untuk dapat membaca atau menulis pada sebuah file, programtersebut harus membuka dulu salah satu saluran/portal yang sesuai. Dengan demikiansaluran/portal ini menyembunyikan hal-hal teknis yang terlalu detil yang bergantung pada sistemoperasi dari pemrogram. Untuk membaca data dari sebuah file, sebuah program cukupmembacanya dari portal file-nya. Dia tidak perlu berurusan dengan bagaimana data tersebutsampai kepadanya. Begitu juga sebuah program yang menulis informasi pada sebuah file cukupmenyampaikannya pada salah satu portal ini. Sisa pekerjaannya akan dilakukan oleh sistemoperasi. Kesimpulannya, untuk menggunakan sebuah file, sebuah program harus melakukanlangkah-langkah berikut:

1. Membuka file untuk membaca atau menulis (i.e. memesan sebuah portal untuk mencari filetersebut pada disk atau lokasi lainnya).

2. Membaca atau menulis pada file itu menggunakan fungsi-fungsi untuk menangani file yangdisediakan oleh pustaka standar.

3. Menutup file untuk membebaskan portal yang telah dipakai agar dapat digunakan olehprogram atau file lain.

Sebuah program membuka file dengan memanggil sebuah fungsi pada pustaka standar yangmengembalikan sebuah pointer yang menunjuk pada file. Program tersebut dapat menggunakanpointer ini untuk mengolah file tersebut dan untuk membedakannya dari file-file lainnya. Tipepointer to file ini dituliskan dalam bentuk FILE *, di mana FILE adalah sebuah struct khususyang didefinisikan pada <stdio.h>. FILE ini bukanlah file yang dimaksud sebenarnya, melainkan

56

sebuah struct yang dapat membantu kita untuk mengakses dan memanipulasi file yangsebenarnya. Pointer to FILE inilah yang dapat diibaratkan sebagai sebuah saluran/portal.

6.3 Saluran I/O Standar: stdin dan stdoutSelama ini kita sudah sering menggunakan masukan standar dan keluaran standar pada sebuahprogram. Masukan standar sering diasosiasikan dengan ‘keyboard’ dan keluaran standar denganmonitor. Untuk membaca data yang dimasukkan melalui keyboard, sebuah program cukupmemanfaatkan saluran/portal masukan standar, yaitu stdin. Fungsi scanf yang sering kitapakai itu sebenarnya membaca input dari user yang telah masuk ke dalam buffer (pada memori)yang bisa dibayangkan sebagai bagian dari stdin. Sebaliknya, untuk menulis ke layar monitor,sebuah program menggunakan saluran/portal keluaran standar stdout. Fungsi printf yangjuga sering kita gunakan itu hanya mengalirkan data yang kita hantarkan sebagai parameterfungsi tersebut ke stdout.

stdin dan stdout bertipe pointer to FILE (FILE *). Berbeda dengan saluran/portal lainnyayang harus dibuka dulu sebelum digunakan dan ditutup setelah dipakai, stdin dan stdout selaluterbuka secara otomatis ketika program yang bersangkutan dijanlankan.

6.4 Penanganan File: Tingkat Tinggi vs Tingkat Rendah

C menyediakan dua tingkat penanganan file: penanganan file tingkat tinggi dan tingkat rendah.File tingkat tinggi diperlakukan sebagai file teks. Data yang masuk ke file ini adalah data tekssebagaimana yang nampak pada layar monitor, karakter per karakter. File yang ditulis denganfungsi penanganan file tingkat tinggi akan menghasilkan file teks yang dapat diedit denganprogram pengedit teks.

File tingkat tinggi juga dibaca sebagai file teks, sebagaimana input dari keyboard yang dibaca olehprogram. Dengan demikian, fungsi penanganan file tingkat tinggi bekerja dengan konsep yangsama dengan fungsi I/O standar.

Penanganan file tingkat rendah, sebaliknya, mengelola data dalam format yang lebih rendah (lebihdekat dengan mesin atau piranti keras) tanpa mengonversinya terlebih ke dalam format teks.Karena itu fungsi-fungsi untuk menangani file level rendah ini kurang ‘programmer-friendly’, tetapidapat bekerja lebih cepat dan efisien.

Dalam modul ini kita akan memfokuskan bahasan pada penanganan file level tinggi. Kebanyakanfungsi penanganan file tingkat tinggi mudah dikenali dari namanya yang dimulai dengan huruf ‘f’,seperti:

fopen()fclose()

57

fprintf()fscanf()fgets()fputs()

6.5 Posisi Program pada File

Saat data dibaca dari sebuah file, sistem operasi mencatat posisi terkini program pada filetersebut. Program tersebut cukup memanggil fungsi standar tertentu untuk ‘membaca bagian fileberikutnya’ dan sistem operasi akan menjalankan perintah ini dengan membaca bagian fileberikutnya dan memajukan posisi program pada file. Begitu seterusnya sampai posisi pada filemencapai akhir dari file. Setiap karakter yang dibaca akan menyebabkan posisi program pada filemaju satu langkah.

Walaupun sistem operasi secara otomatis akan menangani banyak hal tentang posisi pada file,sebuah program juga dapat mengontrol perubahan posisi pada file tersebut melalui beberapafungsi, seperti ungetc() misalnya, jika dibutuhkan. Tetapi pada kebanyakan kasus, hal ini tidakdiperlukan dan lebih baik dihindari. Pergerakan posisi yang kompleks pada file dapatmenyebabkan pergereakan kompleks dari mekanisme disk drive, yang pada akhirnya bisamengakibatkan kerusakan pada disk dan munculnya kesalahan.

6.6 Membuka File

Seperti telah dijelaskan pada sub bab 6.2 di atas, langkah pertama untuk menangani file adalahmembuka file tersebut. Pada C fungsi untuk membuka file adalah fopen, dengan deklarasiberikut:

FILE *fopen(const char *filename, const char *mode);Fungsi ini membuka file ditunjuk oleh filename. Paremeter mode dapat bernilai salah satu daristring berikut:

r Mode baca file teks (r=read)

w Mode tulis file teks (w=write, memotong ukuran/panjang file menjadi 0, ataumembuat file baru)

a Mode sambung file teks untuk menulis (a = append, membuka atau membuatfile dan mengeset pointer file pada akhir file, end-of-file)

rb Mode baca file biner (rb=read binary)

58

wb Mode tulis file biner (wb=write binary, memotong ukuran/panjang file menjadi0, atau membuat file baru)

ab Mode sambung file biner untuk menulis (ab=append binary, membuka ataumembuat file dan mengeset pointer file pada akhir file, end-of-file)

r+ atau +r Mode baca dan tulis file teks

w+ atau +w Mode baca dan tulis file teks (memotong ukuran/panjang file menjadi 0, ataumembuat file baru)

a+ atau +a Mode baca dan tulis file teks (membuka atau membuat file dan mengesetpointer file pada akhir file, end-of-file)

r+b atau rb+atau +rb

Mode baca dan tulis file biner

w+b atau wb+atau +wb

Mode baca dan tulis file biner (memotong ukuran/panjang file menjadi 0, ataumembuat file baru)

a+b atau ab+atau +ab

Mode baca dan tulis file biner (membuka atau membuat file dan mengesetpointer file pada akhir file, end-of-file)

Jika file yang dimaksud tidak ada dan dibuka dengan mode baca (r), maka operasi buka file akangagal.

Jika file dibuka dengan mode sambung (append, a), maka seluruh operasi tulis akan dimulai dariakhir dari file tersebut tanpa memedulikan posisi file saat ini.

Jika file dibuka dengan mode update (+), maka keluaran (tulis) tidak dapat langsung diikutidengan masukan (baca) tanpa diintervensi oleh fseek, fsetpos, rewind, atau fflush.

Jika operasi membuka file sukses, sebuah pointer to *FILE akan dikembalikan . Jika operasi inigagal, maka null pointer akan dikembalikan.

6.7 Menutup File

Untuk menutup file kita dapat menggunakan fungsi fclose dari pustaka standar C, dengandeklarasi berikut:

int fclose(FILE *stream);

59

Fungsi ini menutup file yang ditunjuk oleh stream sekaligus mem-flush buffer yang ada. Prosesflush ini akan menyebabkan data yang tersisa pada buffer, jika ada, akan tertulis pada file.

Jika sukses menutup file, fungsi ini mengembalikan nilai 0. Sedangkan jika gagal, fungsi ini akanmengembalikan EOF.

6.8 Menulis File

Ada beberapa fungsi dari pustaka standar C yang dapat digunakan untuk menulis file, diantaranyaadalah:

fprintf fputc fputs

6.8.1 Fungsi fprintfDeklarasi:

int fprintf(FILE *stream, const char *format, ...);

Fungsi ini menuliskan keluaran yang terformat dalam bentuk string pada parameter format kedalam stream.

Jika sukses, fungsi ini akam mengembalikan jumlah karakter yang tertulis pada file. Jika adakesalahan, -1 dikembalikan.

fprintf() ini memiliki kesamaan dengan printf().Parameter yang digunakan hanya berbedapada satu hal, yaitu pada fprint terdapat tambahan satu parameter: sebuah pointer to file.Sebenarnya fprintf() berhubungan dengan printf() dengan cara yang sederhana. Duapernyataan berikut adalah identik.

printf ("Hello world %d", 1);fprintf (stdout,"Hello world %d", 1);

6.8.2 Fungsi fputcDeklarasi:

int fputc(int character, FILE *stream);Fungsi ini menulis satu karakter (unsigned char) yang dispesifikasikan oleh parametercharacter ke file yang ditunjuk oleh stream dan menggerakkan maju indikator posisi file padastream tersebut.

60

Jika sukses, fungsi ini mengembalikan karakter yang ditulis. Jika ada kesalahan, indikatorkesalahan untuk stream diset dan EOF dikembalikan.

6.8.3 Fungsi fputsDeklarasi:

int fputs(const char *str, FILE *stream);Fungsi ini menulis sebuah string pada stream sampai pada (tetapi tidak termasuk) karakter null.

Jika sukses, fungsi ini mengembalikan nilai non negatif. Jika ada kesalahan, EOF dikembalikan.

6.9 Membaca File

Untuk membaca file beberapa fungsi di bawah ini dapat digunakan:

fscanf fgetc fgets

6.9.1 Fungsi fscanfDeklarasi:

int fscanf(FILE *stream, const char *format, ...);Fungsi ini membaca input field dari sebuah stream sesuai dengan format format yang berisiconversion specifier. Conversion specifier ini menentukan bagaimana input akan disimpan dalamvariabel yang sesuai. Setiap variabel yang menjadi parameter setelah format haruslah bertipepointer.

Pembacaan input field berhenti saat karakter yang ditemukan gagal untuk dikonversi denganconversion specifier atau tidak ada lagi input field yang dibaca.

Jika sukses, fungsi ini akam mengembalikan jumlah input field yang berhasil dikonversikan dandisimpan dari stream. Jika ada kesalahan, EOF dikembalikan.

fscanf() ini analogis dengan scanf() sebagaimana frpintf() dengan printf().

6.9.2 Fungsi fgetcDeklarasi:

61

int fgetc(FILE *stream);Fungsi ini membaca dan mendapatkan karakter berikutnya (unsigned char) dari stream danmemajukan indikator posisi dalam stream .

Jika sukses, fungsi ini mengembalikan karakter yand didapat. Jika end-of-file dicapai, EOFdikembalikan dan indikator end-of-file diset. Jika kesalahan terjadi, maka indikator kesalahanuntuk stream tersebut diset dan EOF dikembalikan.

6.9.3 Fungsi fgetsDeklarasi:

char *fgets(char *str, int n, FILE *stream);Fungsi ini membaca satu baris dari stream dan menyimpannya ke dalam string str. Fungsi iniberhenti saat (n-1) karakter dibaca, karakter pada baris baru dibaca, atau end-of-file dicapai.Karakter pada baris baru disalin ke string str. Sebuah karakter null ditambahkan pada akhir stringtersebut.

Jika sukses, fungsi ini mengembalikan string. Jika ada kesalahan, sebuah null pointerdikembalikan. Jika end-of-file muncul sebelum ada karakter yang dibaca, string tidak berubah.

6.9.4 Fungsi feofDeklarasi:int feof(FILE *stream);Fungsi ini mengecek indikator end-of-file pada stream. Jika end-of-file dicapai, fungsi ini akanmengembalikan nilai bukan 0. Jika end-of-file belum dicapai, fungsi ini mengembalikan 0.

6.10 Contoh Aplikasi

Perhatikan contoh di bawah ini:

123456789

#include <stdio.h>#include <stdlib.h>

int main(){FILE *fp;

int i = 12;float x = 2.356;char ch = 's';

62

1011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556

char str[20] = "Selamat Datang!\n";

// Membuka file untuk menulisfp = fopen("latihan.txt", "w");if (fp != NULL){

printf("Sukses membuka file\n");

// Menulis file dengan fprintffprintf (fp, "%d %f %c %s", i, x, ch, str);

//Menutup fileif(fclose(fp)==0){

printf("Sukses menutup file\n");}else{

printf("Tidak sukses menutup file\n");}

}else{

printf("Tidak sukses membuka file\n");}

int j,n;float y;char c;char s[20];// Membuka file untuk membacafp = fopen("latihan.txt", "r");if (fp != NULL){

printf("Sukses membuka file\n");

// Membaca file dengan fscanfn = fscanf (fp, "%d %f %c %s", &j, &y, &c, s);printf("Jumlah masukan yang sukses dibaca: %d\n", n);printf ("j = %d, y = %f, c = %c, s = %s\n", j, y, c, s);

//Menutup fileif(fclose(fp)==0){

printf("Sukses menutup file\n");}else{

printf("Tidak sukses menutup file\n");}

}else{

printf("Tidak sukses membuka file\n");}

63

57585960616263646566676869707172737475767778798081

// Membuka file untuk membacafp = fopen("latihan.txt", "r");if (fp != NULL){

printf("Sukses membuka file\n");

// Membaca file dengan getcwhile (!feof(fp)) {

c = getc(fp);printf("%c",c);

}//Menutup file

if(fclose(fp)==0){printf("Sukses menutup file\n");

}else{

printf("Tidak sukses menutup file\n");}

}else{

printf("Tidak sukses membuka file\n");}

system("pause");return 0;

}Gambar 6.1

Analisis dan kerjakan kode di atas. Amati penggunaan fungsi-fungsi untuk menangani file.Lakukanlah eksperiemen mandiri untuk lebih memahami operasi file. Cobalah menggunakanfungsi-fungsi operasi file lain (yang tidak terdapat pada kode di atas) untuk membaca dan menulisfile.

6.11 Tugas

Tugas yang relevan dengan topik bab ini diberikan oleh dosen/asisten praktikum.

Tugas bab ini dapat dikombinasikan dengan tugas bab lain atas arahan dan ijin dosen/asistenpraktikum.

Tugas bab ini dikumpulkan kepada dosen/asisten sesuai format yang diminta.

64

7 Daftar Pustaka

Arnold, K., Gosling, J., and Holmes, J. The Java Programming Language, 4th Edition. AddisonWesley Professional, 2005.

Burgess, M. C Programming Tutorial (K&R version 4), 1999. Diakses 18 Oktober 2011, dari situsMark Burgess, Faculty of Engineering, Oslo University College:http://www.iu.hio.no/~mark/CTutorial/CTutorial.html

C Language Tutorial. Diakses 18 Oktober 2011, dari Computational Physics, Department ofPhysics, Drexel University: http://www.physics.drexel.edu/courses/Comp_Phys/General/C_basics/

Dodrill, G. 1997. C Language Tutorial. Diakses 18 Oktober 2011, dari Institute of Robotics, Facultyof Electrical Engineering and Computer Science, University of Maribor: http://www.ro.feri.uni-mb.si/predmeti/mik_si/C_prir/CLIST.HTM

Herianto, T. Tuntunan Praktis Pemrograman C++. PT Elex Media Komputindo Kelompok Gramedia,Jakarta, 1995.

Laboratorium Komputer. Modul Praktikum Dasar Pemrograman Komputer. Program Studi TeknikInformatika, Fakultas Teknik, Universitas Brawijaya, Malang, 2011.

Pranata, A. Pemrograman Borland C++ 4.x. Jilid 1. Penerbit Andi, Yogyakarta, 1996.

Soulie, J. C++ Language Tutorial. Diakses 18 Oktober 2011 dari cplusplus.com:http://www.cplusplus.com/doc/tutorial/