Cari Blog Ini

Diberdayakan oleh Blogger.

search

Flow -  Progress

Selasa, 26 Februari 2019

POINTER PADA PEMROGRAMAN C++

by seftianhanafi.blogspot.com  |  in ALPRO 2 (2D) at  Februari 26, 2019

 

 A.     Pengertian Pointer

Pointer adalah penunjuk suatu variabel. Karena menunjuk suatu variabel, maka pointer wajib memiliki alamat dari variabel yang ditunjuknya. Kadangkala dalam program yang besar, penghematan memori wajib untuk dilakukan. Dengan mekanisme copy dan paste nilai variabel satu kedalam variabel lain, akan sangat memboroskan memori. Dengan mekanisme pointer, suatu variabel dalam suatu fungsi dapat diakses oleh fungsi yang lain.
Hal yang sebenarnya terjadi adalah pointer itu menyimpan alamat memori yang dia tunjuk. Pada pointer kita dimungkinkan untuk menunjuk suatu memori, mengubah nilai dan menyalin nilai memori tersebut secara tidak langsung (perantara melalui variabel pointer). Sebelum kita mempelajari pointer, ada dua hal yang perlu anda ketahui. Dalam pointer terdapat dua macam operator yang akan kita gunakan, yaitu Address-of (&) dan Dereference operator (*).
  • Deklarasi dari Pointer
tipe_data *nama_pointer
  • Operator pointer
&nama_pointer = menunjukkan alamat nama_pointer
*nama_pointer = menunjukkan alamat nama_pointer

B. Membuat Pointer

            pada umumnya pointer sebenarnya adalah variabel, peraturan yang dimiliki variabel juga berlaku pada pointer, jadi tidak jauh beda dengan variabel. pointer hanya mendapatkan beberapa perbedaan yaitu penambahan dua operator yang akan membuat variabel menjadi variabel pointer.
Untuk membuat sebuah variabel pointer kita hanya menambahkan dereference operator sebelum identitas. Operator dereference tidak harus melekat pada identitas, operator tersebut juga bisa di letakan setelah tipe data atau di antara tipe data dan identitas. dari berbagai cara penulisan tersebut memiliki makna yang sama yaitu satu operator dereference hanya akan berlaku pada saru variabel.
Pointer tidak hanya berlaku pada variabel, kita juga dapat melakukanya pada function, objek dan lain-lain. Dan cara implementasi pointer selain pada variabel, caranya masih sama seperti kita melakukanya pada variable.
Bentuk Penulisan
tipeData *identitas;
//atau
tipeData *identitas = &var;
Contoh Penulisan
int *pInt;
double *pDouble = &myVar;

C. Operator Pointer

              Bahasa C menyediakan dua buah operator untuk operasi pointer yaitu operator ‘*’ dan operator ‘&’.  Operator alamat ‘&’ digunakan untuk mendapatkan alamat memori dari operandnya.
Operator ‘*’ digunakan untuk mendapatkan nilai dari operandnya.
Contoh :
#include <stdio.h> main() { char*Alamat_X,X,Y,Z;
X=’J’;
Alamat_X = &X;      Y = X;
Z = *Alamat_X;
printf(“Nilai variabel X  adalah %c\n”, X);      printf(“Nilai variabel Y  adalah %c\n”, Y);      printf(“Nilai variabel Z  adalah %c\n”, Z);
printf(“Nilai variabel X  adalah berada di alamat %p\n”, Alamat_X);  
}

Jika program ini dijalankan, akan didapatkan hasil :

Nilai variabel X adalah J Nilai variabel Y adalah J
Nilai variabel Z adalah J
Nilai variabel X berada di alamat FFDB

D. Pointer dan Array

            Hubungan antara pointer dan array sangatlah erat. Perhatikan contoh berikut :
1
2
char str[80], *p1;
p1 = str;
Disini, p1 telah diset ke alamat dari elemen pertama array str. Untuk mengakses elemen ke lima dari array kita bisa menuliskan
1
2
3
str[4];
/* atau */
 *(p1+4)
Kedua pernyataan diatas akan mengembalikan nilai dari elemen ke lima. Ingat, array dimulai dengan 0. Untuk mengakses elemen ke lima, kita harus menggunakan 4 untuk mengindekskan str. Kita juga menambahkan 4 ke pointer p1 untuk mengakses elemen ke lima karena p1 sebelumnya menunjuk ke elemen pertama array str. (Ingat bahwa sebuah nama array tanpa indeks mengembalikan alamat pertama dari array itu, yang merupakan alamat dari elemen pertama.)
C/C++ menyediakan dua cara untuk mengakses array: aritmatika pointer dan mengindeks array (array-indexing). Meskipun array-indexing kelihatan lebih mudah, aritmatika pointer lebih cepat. Karena kecepatan adalah sebuah perbandingan dalam pemrograman C/C++, programmer biasanya menggunakan pointer untuk mengakses array.
Berikut ini adalah dua versi fungsi putstr(), yang pertama menggunakan cara array-indexing dan yang kedua dengan pointer. Fungsi putstr() ini menuliskan string yang diinputkan sebagai argumen ke konsol.
1
2
3
4
5
6
7
8
9
10
11
12
/* Dengan mengindekskan array s. */
void putstr(char *s)
{
    register int t;
    for (t = 0; s[t]; ++t) putchar(s[t]);
}

/* Mengakses s dengan pointer. */
void putstr(char *s)
{
    while (*s) putchar(*s++);
}

Array Pointer
Pointer juga bisa diarraykan layaknya tipe data lain. Misalnya deklarasi untuk array pointer ke int dengan 10 elemen adalah
1
int *x[10];
Untuk memberikan alamat sebuah variabel (misalnya variabel var) ke elemen ketiga dari array pointer, tulis
1
x[2] = var;
untuk menemukan nilai var, tulis
1
2
3
4
5
6
void display_array(int *q[])
{
int t;
for(t=0; t<10; t++)
printf("%d", *q[t]);
}
Ingat, q bukan sebuah pointer ke integer, tapi q adalah pointer ke sebuah array pointer ke integer (Perhatikan gambar dibawah.) Parameter q tidak akan bisa menerima argumen selain sebuah pointer ke integer, karena itulah q dideklarasikan sebagai array pointer.
Pic17 - Pointer
Array pointer sering digunakan untuk menyimpan pointer ke string. Kita bisa membuat fungsi yang menghasilkan pesan error berdasarkan kode angka, seperti berikut:
1
2
3
4
5
6
7
8
9
10
void syntax_error(int num)
{
static char *err[] = {
"Cannot Open File\n",
"Read Error\n",
"Write Error\n",
"Media Failure\n"
};
printf("%s", err[num]);
}
Array error menyimpan pointer ke setiap string. Seperti yang kita lihat, printf() didalam syntax_error() dipanggil dengan pointer karakter yang menunjuk ke salah satu dari berbagai
pesan error yang diindekskan berdasarkan pada angka yang dilewatkan ke fungsi. Misalnya, jika num diberi nilai 2, pesan Write Error akan ditampilkan.

E. Pointer Sebagai Parameter Fungsi

            Suatu fungsi dalam C mempunyai bentuk:
tipe_keluaran nama_fungsi ( tipe_parameter_1
parameter_fungsi_1,
tipe_parameter_2
parameter_fungsi_2,
.....
tipe_parameter_n
parameter_fungsi_n )

contoh fungsi main yang biasa dipakai:

int main(int argc, char argv[][])
{
return 0;
}

Pada fungsi main diatas, keluaran fungsi berupa integer (int), nama fungsi main, parameter1 bertipe integer, parameter 2 bertipe char. Instruksi return akan mengembalikan keluaran fungsi ini, keluaran fungsi ini adalah 0.
parameter2 fungsi main diatas adalah array dua dimensi, maka seperti yang telah kita pelajari diatas, maka fungsi main diatas dapat ditulis ulang dengan pointer seperti berikut:
int main(int argc, char **argv)
{
return 0;
}

suatu fungsi pertukaran nilai X dan nilai Y dituliskan sebagai berikut:

#include

int hasilY;

int tukar(int X,int Y)
{
int Z;
Z = X;
X = Y;
Y = Z;
hasilY = Y;
return X;
}

int main()
{
int X,Y,Z
X=10;
Y=20;

printf("sebelum ditukar:\n");
printf("X = %d\n",X);
printf("Y = %d\n",Y);

Z = tukar(X,Y);

printf("setelah ditukar:\n");
printf("X = %d\n",Z);
printf("Y = %d\n",hasilY);
}
Program diatas melibatkan variabel global hasilY, sebagai parameter penyimpan nilai Y setelah ditukar. Sedangkan nilai X setelah ditukar digunakan sebagai keluar fungsi tukar.
Program seperti ini mempunyai kekurangan karena menggunakan variabel global, selain memboroskan memori, ada kemungkinan kesamaan dalam penamaan antara variabel satu dengan variabel yang lain. Maka program diatas diubah menjadi:
#include

void tukar(int *X,int *Y)
{
int Z;

Z = *X;
*X = *Y;
*Y = Z;
}

int main()
{
int A,B;
A=10;
B=20;

printf("sebelum ditukar:\n");
printf("A = %d\n",A);
printf("B = %d\n",B);

tukar(&A,&B);

printf("setelah ditukar:\n");
printf("A = %d\n", A);
printf("B = %d\n", B);
}
Bagaimana cara kerja fungsi tukar diatas?
1. Parameter fungsi diinisialisasi sebagai pointer *X dan *Y.
2. Saat pemanggilan fungsi tukar:
tukar(&A, &B);
Maka terjadi penunjukan alamat A dan B oleh pointer *X dan *Y.

3. Karena penunjukan oleh pointer ini, maka perubahan nilai A dan B sesuai dengan perubahan pada pointer *X dan *Y, demikian pula perubahan nilai pointer *X dan *Y maka nilai A dan B juga berubah.

F. FUNGSI dengan KELUARAN berupa POINTER

Pernah menemui fungsi seperti ini?
int *fungsi(int x, int y);
fungsi tersebut adalah fungsi dengan keluaran pointer bertipe integer, salah satu contoh nyatanya adalah fungsi malloc yang pernah kita gunakan.
void *malloc(size_t sizeAlocation);
Lalu, apa guna fungsi seperti ini?
contoh program dengan fungsi mengembalikan pointer:
#include
#include
char *KAPITAL(char *Y)
{
char z;
char *X;
while(*Y)
{
i = i + sizeof(char);
Y = Y + sizeof(char);
}
Y = Y - i*sizeof(char);
X = (char *)malloc(i + sizeof(char));
while(*Y)
{
z = *Y;
if(z>'a' && z<'z')
*X = z;
Y = Y + sizeof(char);
X = X + sizeof(char);
}
*X = *Y;
return X = X - i*sizeof(char);
}
int main()
{
char *p="huruf kecil";
char *h;
h = KAPITAL(p);
printf("%s\n",h);
free(h);
return 0;
}

Cara kerja program diatas adalah sesuai dengan comment diatas, saya jelaskan ulang:
pada fungsi main()
h = KAPITAL(p);
sebenarnya adalah identik dengan kita menunjuk ke alamat return variabel (keluaran fungsi) dari fungsi KAPITAL. Sesuai dengan analisa kita didepan (topik pointer dan array) alamat ini adalah alamat index pertama dari keluaran fungsi itu sendiri dalam fungsi KAPITAL adalah N[0].
Apabila kita cermati dalam fungsi KAPITAL diatas, kita harus mengembalikan posisi pointer ke posisi awal pointer[0] setelah kita melakukan increment.
Y = Y - i*sizeof(char);
Untuk apa? Karena kita membutuhkan alamat awal (index 0) dari pointer asal agar dapat kita gunakan untuk mengaksesnya sebagai satu kumpulan string, hal ini identik dengan "pemberi jejak" agar kita tidak tersesat.
maksudnya? Pada while berikut ini:
while(*Y)
{
i = i + sizeof(char);
Y = Y + sizeof(char);
}
Apabila kita printf(Y) maka hasilnya tidak akan sama dengan isi Y yang kita maksud, karena alamat (pointer) dari Y itu sendiri telah bergeser akibat increment. coba print alamat awal Y dan bandingkan dengan alamat sesudah increment:
//sebelum dan sesudah while coba tuliskan code berikut:
printf("Y = %p",&Y[0]);
Ingat lagi: karena *Y adalah pointer maka Y adalah alamat pada index ke 0 atau &Y[0]
Kenapa kita harus mengalokasikan memori dulu dalam fungsi KAPITAL dan kenapa h harus di free di fungsi main?
Kita, kompiler dan komputer tidak pernah mengetahui berapa jumlah array yang dibutuhkan untuk mem-buffer parameter masukan yang telah diolah, oleh karena itu besar kemungkinan terjadi segmentation fault karena kita/program dapat sembarangan menimpakan data ke alamat yang tidak teralokasikan!
Kita perlu membebaskan memori yang telah dialokasikan dengan free, dan tentu saja free ini harus ditempatkan setelah penggunaan memori telah selesai (tidak digunakan lagi). Karena pada contoh diatas memori yang disimpan akan ditampilkan dengan printf, maka setelah printf-lah kita dapat mem-free-nya.
Kenapa harus di free?             Untuk menghindari memory leak, yaitu kondisi dimana memori yang telah kita pakai (alokasikan) dan sudah tidak berguna namun tidak dapat digunakan (alokasikan) lagi, hal ini tentu menyebabkan pemborosan memori.
Untuk lebih jelas coba dan modifikasi program diatas! Bagaimana hasilnya?
Pada fungsi KAPITAL, setelah pengalokasian memori:
X = (char *)malloc(i + sizeof(char));
tambahkan:
printf("alamat X = %p\n", X);
Pada fungsi main, ganti dengan:
int main()
{
char *p="huruf kecil";
char *h;
int i;
for(i=0;i<10;i++)
{
h = KAPITAL(p);
printf("%s\n",h);
free(h);
}
return 0;
}
bandingkan dengan tanpa free:
int main()
{
char *p="huruf kecil";
char *h;
int i;
for(i=0;i<10;i++)
{
h = KAPITAL(p);
printf("%s\n",h);
}
return 0;
}
Dengan main() yang pertama, alamat X akan selalu tetap, sedangkan pada main kedua alamat X akan selalu berubah (bertambah) sebesar jumlah memori yang dialokasikan (dalam contoh adalah 11 byte), sehingga dengan 10 perulangan kita telah memboroskan memori sebesar:
(10 * 11 byte) - 11 byte = 99 byte

https://haganesite.wordpress.com/2016/07/30/pointer-dan-array/
http://ayo-ngelmu.blogspot.com/2009/02/pointer-dan-fungsi.html

0 komentar:

Tugas Besar Pemrograman Visual

Proudly Powered by Blogger.