• Tidak ada hasil yang ditemukan

Pointer dan Reference

Dalam dokumen LSP Telematika. Cover (Halaman 30-41)

BAB II Dasar Pemrograman C++

2.6 Pointer dan Reference

Salah satu kelebihan dari bahasa C/C++ adalah karena bahasa ini mendukung sepenuhnya untuk pemanipulasian memori dengan mendukung pointer. Namun di balik itu, pointer juga merupakan salah satu fitur C++ yang berbahaya karena dapat mengakibatkan sistem operasi pada komputer kita menjadi crash (rusak). Penggunaan pointer dengan cara yang salah juga dapat menyebabkan bug yang sangat sulit untuk ditemukan pada program kita.

Variabel Pointer

Secara definisi, pointer dapat dikatakan sebagai suatu variabel yang menyimpan alamat memori. Pada bab-bab sebelumnya kita telah membahas

penggunaan variabel, tapi variabel-variabel tersebut hanya berisi nilai, bukan alamat.

Jika kita mempunyai sebuah variabel dengan tipe data tertentu, maka untuk mendapatkan alamat dari variabel tersebut adalah dengan menggunakan opertor &(ampersand). Alamat inilah yang kemudian akan disimpan ke dalam variabel yang bertipe pointer. Sedangkan untuk mendeklarasikan variabel sebagai pointer, kita hanya menambahkan tanda asterisk(*) di depan nama variabel. Berikut ini bentuk umum dari pendeklarasian variabel yang bertipe pointer.

tipe_data *nama_pointer;

Sebagai catatan bahwa penulisan di atas dapat diganti dengan tipe_data* nama_pointer atau tipe_data * nama_pointer.

Tipe data di atas berguna untuk menyatakan bahwa pointer yang kita deklarasikan tersebut akan ditempati oleh data dengan tipe tertentu. Sebagai contoh, kita akan mendeklarasikan pointer P yang akan ditempati oleh tipe data long, maka bentuk pendeklarasiannya adalah sebagai berikut:

long *P; //mendeklarasikan pointer P yang akan merujuk ke tipe long jika kita mempunyai sebuah variabel yang bertipe long (misalnya x), maka kita dapat memerintahkan pointer P di atas untuk menunjuk ke alamat yang ditempati oleh variabel x. Adapun sintaks untuk melakukan hal tersebut adalah seperti yang terlihat di bawah ini.

Apabila kita analisis potongan sintaks di atas, sebenarnya konsepnya sangat sederhana. Kita tahu bahwa P adalah pointer (berisi alamat) dan &x juga berisi alamat, maka kita dapat menyimpan alamat dari variabel x tersebut ke dalam pointer P. Kita tidak diizinkan untuk memasukkan sebuah nilai (bukan

long x; //mendeklarasikan variabel x dengan tipe long long *P;

alamat) ke dalam pointer P. Misalnya dengan menuliskan sintak seperti berikut:

P = x; //SALAH, karena x berupa nilai (bukan berupa alamat)

Jika kita memang ingin mengisikan nilai ke dalam alamat yang disimpan oleh Pointer P, maka seharusnya kita menggunakan tanda astersik (*) di depan nama pointer tersebut, yaitu dengan mengubah sintaks di atas menjadi:

*P = x; //BENAR, karena *P adalah nilai yang berada pada pointer P Sebagai catatan bahwa *P ini disebut dengan dereference pointer. Untuk dapat lebih memahami konsep pointer. Berikut ini gambar yang mengilustrasikan kasus di atas.

Pada gambar di atas alamat 1 dari memori di tempati oleh variabel x yang bertipe long. Adapun nilai dari variabel x tersebut adalah 10. Di atas kita mempunyai pointer P yang menunjuk ke alamat x, maka untuk mendapatkan nilai x kita dapat menggunakan dereference pointer, yaitu dengan *P. Dengan demikian dapat disimpulkan bahwa jika:

P =&x // keduanya meyimpan alamat Maka:

*P = x; //keduanya menyimpan nilai

Untuk membuktikan hal di atas, di sini kita akan mengimplementasikannya ke dalam sebuah program sederhana. Adapun sintaks program tersebut adalah sebagai berikut:

Alamat x (&x) 10

Alamat 2 20

Alamat 3 30

Alamat 4 40

Memori Komputer Nilai Pointer P

Contoh hasil yang akan diberikan dari program di atas adalah sebagai berikut:

Jika kita amati hasil program di atas, pada saat kita mengisikan variabel x dengan nilai 10, *P juga akan bernilai 10. Sedangkan pada saat kita memasukkan nilai ke dalam *P dengan nilai 200, variabel x juga akan berubah nilainya menjadi 200. Hal ini menunjukkan bahwa *P akan selalu sama dengan x, dan ini semua disebabkan karena *P dan variabel x tersebut menempati alamat yang sama.

Memasukkan Nilai pada Pointer

Nilai yang dimaksud disini tentu berupa alamat, bukan berupa nilai data. Walaupun tampak mudah tapi kita juga harus berhati-hati dalam melakukan

#include<iostream.h>

int main(){ long *P; long x;

P = &x;

x = 10; //mengisikan nilai 10 ke dalam variabel x

cout<<”Nilai x :”<<x<<endl; cout<<”Nilai *P :”<<*P<<endl; cout<<”Nilai P :”<<P<<endl; cout<<”Nilai &x :”<<&x<<endl;

*P = 200; //mengisikan nilai 200 ke dalam *P

cout<<”Nilai x :”<<x<<endl; cout<<”Nilai *P :”<<*P<<endl; cout<<”Nilai P :”<<P<<endl; cout<<”Nilai &x :”<<&x<<endl;

return 0; } Nilai x : 10 Nilai *P : 10 Nilai P : 0065FDFC Nilai &x : 0065FDFC Nilai x : 200 Nilai *P : 200 Nilai P : 0065FDFC Nilai &x : 0065FDFC

hal ini. Perlu diperhatikan bahwa tipe data dari pointer harus sama dengan tipe data dari variabel yang akan menempatinya. Hal ini merupakan hal yang biasa terabaikan oleh para programmer pemula. Misalnya kita mendeklarasikan pointer P ke tipe double dan kita juga memiliki variabel x yang bertipe int. Pada kasus ini kita tidak diizinkan untuk menyimpan alamat dan variabel x ke pointer P karena tipenya berbeda. Berikut ini sintaks programnya.

Pointer Tanpa Tipe

Pada bagian sebelumnya kita telah mengetahui bahwa pointer harus diisikan dengan alamat dari variabel yang bertipe sama dengan tipe pointer tersebut. Sebenarnya ada cara khusus yang untuk membuat pointer yang kita deklarasikan tersebut dapat menunjuk ke semua tipe data, yaitu dengan mendeklarasikan pointer tersebut sebagai pointer tanpa tipe. Pointer semacam ini sering dinamakan dengan void pointer. Adapun bentuk umum untuk mendeklarasikan pointer tanpa tipe ini adalah sebagai berikut:

void *nama_pointer;

Berikut ini contoh program yang dapat membuktikan bahwa pointer tanpa tipe (void pointer) dapat menyimpan alamat dari variabel-variabel yang bertipe apapun.

#include<iostream.h>

int main(){

void *P; /*mendeklarasikan pointer P sebagai pointer tanpa tipe*/

//mendeklarasikan variabel x, y, dan z dengan tipe

berbeda int x; long y; double z; double *P;

int x; //mendeklarasikan variabel yang bertipe int

P = &x; /*SALAH, karena P hanya dapat menyimpan alamat dari variabel-variabel yang bertipe double saja*/

//memerintahkan P untuk menunjuk ke alamat dari variablel x

P = &x;

x = 10; //mengisikan nilai 10 ke dalam variabel x

cout<<”Nilai x :”<<x; cout<<”Nilai P :”<<P; cout<<”Nilai &x :”<<&x; cout;

//memerintahkan P untuk menunjuk ke alamat dari variabel y

P = &y;

y = 2000; //mengisikan nilai 200 ke dalam y

cout<<”Nilai y :”<<y; cout<<”Nilai P :”<<P; cout<<”Nilai &y :”<<&y;

cout;

//memerintahkan P untuk menunjuk ke alamat dari variabel z

P = &z;

Z = 21.0378; // mengisikan nilai 21.0378 ke dalam y

cout<<”Nilai z :”<<z; cout<<”Nilai P :”<<P; cout<<”Nilai &z :”<<&z; cout;

return 0; }

Hasil yang akan diberikan dari program di atas adalah sebagai berikut:

Seperti kita lihat di atas bahwa P dapat menunjuk ke tipe data yang berbeda-beda. Sebagai bukti dair hal ini adalah nilai P yang berbeda, yaitu sesuai dengan alamat dari variabel yang ditunjuk.

Nilai x : 10 Nilai P : 0065FDFC Nilai &x : 0065FDFC Nilai y : 2000 Nilai P : 0065FDF8 Nilai &y : 0065FDF8 Nilai z : 21.0378 Nilai P : 0065FDF0 Nilai &z : 0065FDF0

Melakukan Inisialisasi pada Pointer

Setiap kita mendeklarasikan sebuah pointer, maka pointer tersebut akan menunjuk lokasi acak di memori. Oleh karena itu kita harus mengeset pointer yang kita deklarasikan tersebut dalam keadaan NULL, atau tidak menunjuk lokasi manapun. Untuk membuktikan hal ini, jalankan program di bawah ini;

Hasil yang didapat adalah sebagai berikut:

Alamat yang ditunjuk oleh pointer P: 00000000

Sebelumnya jika baris P = NULL; dihilangkan maka hasil yang diperoleh adalah:

Alamat yang ditunjuk oleh pointer P: 006821A4

Pointer ke Pointer (Multiple Indirection)

Dalam C/C++, kita dapat mempunyai pointer yang menunjuk ke pointer lain yang telah menunjuk ke alamat tertenu. Situasi ini sering disebut dengan multiple indirection atau pointer ke pointer. Konsep dari pointer ke pointer ini sederhana, kita tahu bahwa pointer normalnya berisi alamat dari sebuah objek (variabel) yang menyimpan nilai berupa data. Sekarang kita mempunyai pointer lagi yang akan menunjuk ke pointer tadi. Sebagai gambaran, perhatikan gambar ilustrasi di bawah ini.

#include<iostream.h>

int main(){

int *P; /* mendeklarasikan pointer P yang akan menunjuk tipe data int */

P = NULL; //menset pointer P dengan nilai NULL

cout<<”Alamat yang ditunjuk oleh pointer P:” <<P; return 0;

Untuk mendeklarasikan sebuah pointer yang akan menunjuk ke pointer lain adalah dengan menggunakan tanda asterisk sebanyak dua kali (**). Sebagai contoh, jika kita mendeklarasikan pointer seperti pada potongan sintaks di bawah ini:

int **P;

Maka P bukan pointer yang menunjuk ke tipe data int, melainkan pointer yang menunjuk pointer ke tipe data int. Untuk dapat lebih memahaminya, perhatikan program di bawah ini;

Alamat Nilai

Alamat Alamat Nilai

Pointer Variabel

Singel Indirection

Pointer Pointer Variabel

Mutliple Indirection

#include<iostream.h>

int main(){

int x = 25; //mendeklarasikan variabel x dengan nilai 25

int *P1; //mendeklarasikan pointer P1 yang menunjuk ke tipe int

int **P2; // mendeklarasikan pointer P2 yang menunjuk ke pointer P1

P1 = &x; P2 = &P1; //menampilkan nilai cout<<”Nilai x :”<<x<<endl; cout<<”Nilai *P1 :”<<*P1<<endl; cout<<”Nilai *P2 :”<<*P2<<endl; cout<<”Nilai **P2:”<<**P2<<endl; //menampilkan alamat

cout<<”Nilai &x :”<<&x<<endl; cout<<”Nilai P1 :”<<P1<<endl; cout<<”Nilai P2 :”<<P2<<endl;

return 0; }

Hasil yang akan diperoleh dari program di atas adalah sebagai berikut; Nilai x : 25

Nilai *P1 : 25

Nilai *P2 : 0065FE00 Nilai **P2 : 25

Nilai &x : 0065FE00 Nilai P1 : 0065FE00 Nilai P2 : 0065FDFC

Seperti yang kita lihat bahwa nilai x dapat diakses dengan menggunakan *P1 atau **P2 sedangkan alamat dari variabel x dapat diakses dengan menggunakan &x, P, ataupun *P2 (catatan: *P2 merupakan nilai yang menempati alamat yang ditunjuk oleh pointer P2). Hal ini membuktikan bahwa pointer P2 tidak menunjuk ke tipe data int, melainkan menunjuk ke pointer P1. Dan yang terakhir, P2 sendiri menyimpan alamat dari pointer P1. Untuk contoh di atas, P2 menyimpan alamat 0065FDFC.

Reference

Reference digunakan untuk membuat alias atau nama lain dari sebuah variabel. Sebagai contoh jika terdapat seseorang yang bernama Roy Marten, maka kita dapat membuat alias atau julukan dari nama tersebut, misalnya dengan alias RM. Oleh karena Roy Marten dan RM sebenarnya adalah satu orang, maka apa yang dilakukan terhadap Roy Marten, berarti itu juga terjadi pada RM.

Setelah mendapat gambaran tersebut, sekarang kita kembali ke pokok permasalahan kita tentang reference. Untuk membuat reference adalah dengan menggunakan tanda & di belakang tipe data yang akan diacu. Berikut ini bentuk umum dari pembuatan reference.

tipe_data& nama_alias = nama_variabel;

Untuk dapat memahami lebih jauh mengenai reference ini, perhatikan contoh program di bawah ini.

#include<iostream.h> int main(){

int x; //mendeklarasikan variabel x

//membuat alias dari variabel x dengan nama AliasX

int& AliasX = x;

//mengisikan nilai ke dalam variabel x

x = 12;

//menampilkan nilai yang disimpan dalam variabel x dan AliasX

cout<<”Nilai x :”<<x; cout<<”Nilai AliasX :”<<AliasX; cout<<’\n’;

//mengisikan nilai ke dalam AliasX

AliasX = 35;

//menampilkan kembali nilai yang disimpan dalam variabel x dan AliasX

cout<<”Nilai x :”<<x; cout<<”Nilai AliasX :”<<AliasX;

return 0; }

Hasil yang diperoleh dari program di atas adalah sebagai berikut;

Apabila kita analisis hasil dari program di atas, tampak bahwa pada saat kita memasukkan nilai 12 ke dalam variabel x, AliasX juga akan bernilai 12. Begitu juga sebaliknya, pada saat kita memasukkan nilai 35 ke dalam AliasX, variabel X juga akan bernilai 35.

Alamat dari Reference

Nama alias dan variabel menempati alamat yang sama di memori, jadi keduanya bukanlah dua buah variabel yang berbeda, melainkan satu variabel yang mempunyai dua nama.

Nilai X : 12 Nilai AliasX : 12

Nilai X : 35 Nilai AliasX : 35

Soal Latihan

1. Jika kita membutuhkan variabel yang dapat dikenali oleh semua lingkungan dalam program kita, maka mendefinisikan variabel tersebut sebagai :

a. Variabel statis b. Variabel global c. Variabel lokal d. Variabel register

2. Berikut ini yang termasuk dalam user defined types kecuali a. array

b.struktur c. enumerasi d.char

3. Untuk mendapatkan alamat dari sebuah variabel, dapat digunakan operator : a. $ b. & c. * d. ""

Soal Praktek

3. Buatlah program C++ untuk menampilkan alamat dari 3 variabel yang berbeda tipe datanya.

4. Buatlah sebuah struktur yang berisi nama, alamat dan nomor telepon. Kemudian isi dan tampilkan isi struktur tersebut.

Dalam dokumen LSP Telematika. Cover (Halaman 30-41)