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.
|
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
|
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.

Array pointer sering digunakan untuk menyimpan pointer ke
string. Kita bisa membuat fungsi yang menghasilkan pesan error berdasarkan kode
angka, seperti berikut:
|
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:
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://www.belajarcpp.com/tutorial/cpp/pointer/
/https://www.sinauarduino.com/artikel/pointer-pada-pemrograman-cpp/
/https://www.sinauarduino.com/artikel/pointer-pada-pemrograman-cpp/
https://haganesite.wordpress.com/2016/07/30/pointer-dan-array/
http://ayo-ngelmu.blogspot.com/2009/02/pointer-dan-fungsi.html
0 komentar: