Tipe pointer

Tipe object merupakan tipe data yang mengubah teknik pemrograman secara besar-besaran. Dengan adanya tipe object, kita bisa memperlakukan program seperti obyek pada kehidupan nyata. Bahkan tipe obyek juga bisa memiliki keturunan seperti kita. Akan tetapi kelebihan dari tipe obyek ini akan lebih terasa kemudahannya hanya jika kita menggunakan tipe pointer untuk berhubungan dengan obyek-obyeknya. Oleh karena itu, kita tinggalkan dahulu tipe obyek untuk melihat kepada tipe pointer.

Variabel adalah sebuah lokasi memori di dalam komputer. Pada saat kompilasi, nama-nama variabel akan diganti dengan alamat memori tempat variabel tersebut menyimpan nilainya. Variabel dengan tipe pointer memiliki sedikit perbedaan dengan variabel yang lain. Variabel dengan tipe pointer tidak menyimpan data secara langsung, akan tetapi hanya menyimpan alamat lokasi memorinya.

Untuk membuat variable dengan tipe pointer, kita menambahkan tanda (^) sebelum tipe yang ditunjuk. Sebagai contoh, jika kita hendak membuat variabel yang menunjuk kepada data dengan tipe integer, maka penulisan tipenya menjadi ^integer. Penulisan ini bisa langsung digunakan pada deklarasi variabelnya, bisa juga dibuat menjadi tipe terlebih dahulu. Contoh:

type 
   PInteger = ^Integer;

var
   PData1:PInteger;
   PData2:^Integer;

Variabel PData1 maupun PData2 memiliki tipe yang sejenis.

Reference dan Dereference

Variabel dengan tipe pointer tidak bisa ditugasi dengan nilai selain alamat memori. Sebagai contoh, PData1 tidak bisa diisi dengan nilai 100 (yang merupakan angka dalam kawasan integer). Semua variabel hanya bisa ditugasi dengan alamat dari variabel yang memiliki tipe sesuai dengan tipe pointernya. Untuk mendapatkan alamat dari sebuah variabel, kita bisa menggunakan simbol at (@) sebelum nama variabel yang akan diambil alamatnya. Sebagai contoh, untuk mendapatkan alamat dari variabel i, maka penulisannya menjadi @i. Proses mengisi variabel pointer dengan alamat suatu variabel disebut dengan reference.

Di dalam operasi-operasi yang melibatkan variabel dengan tipe pointer, maka ekspresi yang dihasilkannya adalah alamat-alamat memori, bukan data yang berada pada alamat tersebut. Perhatikan contoh berikut:

var
   A,B:integer;
   PA,PB:^integer;
begin
   //mengisi variabel pointer ke variabel
   PA:=@A;
   PB:=@B;
   //mengisi variabel A dan B dengan bilangan
   A:=1;
   B:=2;
   PB:=PA;//aksi ini tidak menyebabkan B berisi 1
   //aksi ini hanya menyebabkan PB menunjuk ke A
end;

Jika yang Anda kehendaki dari program di atas adalah untuk membuat isi variabel B sama dengan isi variabel A, maka Anda harus melakukan proses yang disebut dereference terhadap variabel-variabel pointernya. Untuk melakukan dereference, tambahkan simbol (^) di belakang variabel pointer. Jadi jika Anda ingin membuat isi B sama dengan isi A melalui variabel pointer, maka cara yang harus Anda lakukan adalah:

   PB^:=A;//atau
   PB^:=PA^;

New dan Dispose

pointer yang baru dideklarasikan akan memiliki nilai yang disebut dengan nil, yaitu nilai yang menunjukkan bahwa pointer tersebut belum menunjuk kepada suatu variabel. Proses dereference terhadap pointer dengan nilai nil akan menyebabkan kesalahan program. Agar pointer memiliki nilai (yang bukan nil), cara pertama adalah dengan melakukan reference terhadap sebuah variabel seperti pada contoh di atas. Cara kedua adalah dengan meminta kepada sistem untuk menyediakan sebuah lokasi memori dengan perintah new.

Jika kita menggunakan cara yang kedua, maka pada saat kita sudah tidak menggunakan variabel tersebut, kita juga bertanggung jawab untuk memberitahukan kepada sistem bahwa bahwa lokasi memori yang kita pesan sudah tidak kita gunakan lagi, yaitu dengan perintah dispose. Jika kita tidak melakukan dispose, maka sistem akan menganggap bahwa memori yang kita pesan masih tetap digunakan. Dan jika kita sering melakukan perintah new dengan ukuran yang besar dan tidak melakukan dispose dengan benar, maka sistem bisa kehabisan memori.

Contoh penggunaan new dan dispose adalah sebagai berikut:

var
   PA,PB:^integer;
begin
   new(PA);
   new(PB);
   PA^:=1;
   PB^:=PA^;
   dispose(PA);
   dispose(PB);
end;

HariLahir dengan pointer

program HariLahir5;
{$APPTYPE CONSOLE}
type
  TNamaBulan=(Januari=1, Pebruari, Maret, April,
              Mei, Juni, Juli, Agustus, September,
              Oktober, Nopember, Desember);
  //membuat tipe pointer kepada TObjectTanggal
  PObjectTanggal=^TObjectTanggal;
  TObjectTanggal=object
    Tanggal:integer;
    Bulan:TNamaBulan;
    Tahun:integer;
    procedure AmbilTanggal;
    function JumlahHari:integer;
    function NamaHari:string;
  end;
const
  Hari:array[0..6]of string=
        ('Minggu','Senin','Selasa','Rabu',
        'Kamis','Jumat','Sabtu');
  HariPertama=5;
var
  //TglLahir sekarang bertipe pointer
  TglLahir:PObjectTanggal;
//---implementasi TObjectTanggal------------------
  procedure TObjectTanggal.AmbilTanggal;
  var tmp:integer;
  begin
    Write('Tanggal ?: ');
    Readln(Tanggal);
    Write('Bulan ?  : ');
    Readln(tmp);
    Bulan:=TNamaBulan(tmp);
    Write('Tahun ?  : ');
    Readln(Tahun);
  end;

  function IsKabisat(Y:integer):boolean;
  begin
    result:=((Y mod 4=0)and(Y mod 100<>0))
            or(Y mod 400=0);
  end;

  function TObjectTanggal.JumlahHari:integer;
    function HariDlmBulan(B:TNamaBulan):integer;
    begin
      case B of
      Januari,Maret,Mei,Juli,Agustus,
      Oktober,Desember:result:=31;
      April,Juni,September,Nopember:result:=30;
      Pebruari:if IsKabisat(Tahun)
                then result:=29 else result:=28;
      end;
    end;
  var i:TNamaBulan;
      ii:integer;
  begin
    result:=0; 
    //Hitung hari dalam tahun
    for ii:=0 to Tahun-1 do
      if IsKabisat(ii)then result:=result+366
         else result:=result+365; 
    //tambahkan dengan sisa hari
    for i:=Januari to Pred(Bulan)do
      result:=result+HariDlmBulan(i);
    result:=result+Tanggal;
  end;

  function TObjectTanggal.NamaHari:string;
  var i:integer;
  begin
    i:=(JumlahHari+HariPertama)mod 7;
    result:=Hari[i];
  end;
//---------------------------------------------
  procedure DisplayHari(Tgl:PObjectTanggal);
  begin
    Writeln('Anda lahir hari ',Tgl.NamaHari);
  end;

  procedure AmbilData;
  begin
    Writeln('**Semua data dalam angka**'#13#10);
    Writeln('Masukkan data tanggal lahir');
    TglLahir.AmbilTanggal;
  end;
begin
  //memesan memori kepada sistem
  new(TglLahir);
  AmbilData;
  DisplayHari(TglLahir);
  //mengembalikan memori yang sudah tidak terpakai
  dispose(TglLahir);
  Writeln('Tekan Enter');
  Readln;
end.

Ada hal yang istimewa dalam pendefinisian tipe data pointer, yaitu bahwa pendefinisian tipe pointer boleh mengacu kepada tipe yang didefinisikan di bawahnya. Perhatikan contoh pendefinisian tipe yang bukan pointer seperti berikut:

type
   TArrayI=array[0..4]of TArrayII;
   TArrayII=array[0..5]of integer;

Pendefinisian tipe seperti contoh di atas akan dianggap salah karena TArrayII belum terdefinisikan pada saat pendefinisian TArrayI. Akan tetapi perhatikan pada baris yang mendefinisikan PObjectTanggal seperti pada program HariLahir5 yang ternyata dianggap benar.

Ada perbedaan antara Turbo Pascal dan Delphi dalam mengacu kepada anggota obyek. Jika program HariLahir5 ditulis untuk Turbo Pascal, maka pada prosedur DisplayHari seharusnya dilakukan dereference terhadap Tgl yang bertipe pointer sehingga penulisannya seperti berikut:

    Writeln('Anda lahir hari ',Tgl^.NamaHari);

Pada Delphi, akses terhadap anggota dari sebuah obyek atau record melalui pointer secara otomatis akan menghasilkan dereference-nya. Walaupun demikian, Anda tetap bisa menambahkan simbol dereference seperti pada Turbo Pascal. Cara di dalam Delphi akan membuat penulisan program menjadi lebih mudah karena proses reference dan dereference merupakan proses yang seringkali membuat pemrogram pemula merasa bingung dalam menggunakan tipe pointer.

Pada program HariLahir4, TglLahir merupakan variabel dengan tipe TObjectTanggal, maka tidak diperlukan sebuah langkahpun untuk membuat obyek untuk TglLahir (secara otomatis TglLahir sudah merupakan obyek). Pada program HariLahir5, TglLahir merupakan variabel dengan tipe pointer terhadap TObjectTanggal, maka harus ada proses pembuatan obyek untuk TglLahir sebelum TglLahir bisa digunakan (harus dilakukan new). Pada kasus ini TglLahir bukan merupakan obyek tetapi hanya merupakan pointer kepada obyek yang pada saat dideklarasikan bernilai nil.

Apakah Anda menyukai post ini? Mengapa tidak memberikan komentar di bawah dan melanjutkan perbincangan, atau berlangganan my feed dan dapatkan artikel semacam ini yang dikirm secara otomatis feed reader Anda.
Harap diperhatikan bahwa komentar atau pertanyaan yang disampaikan haruslah sesuai dengan topik yang sedang dibahas. Komentar atau pertanyaan yang tidak sesuai dengan topik akan kami hapus :!:

Tinggalkan komentar

Sebelum membuat komentar, pastikan Anda telah membaca komentar-komentar sebelumnya. Jangan membuat pertanyaan yang telah ditanyakan. Perhatikan pula link-link dalam artikel. Lihatlah link tersebut sebelum membuat pertanyaan, karena mungkin penjelasan dari pertanyaan Anda telah di jawab dalam link tersebut.

Komentar yang tidak mengikuti aturan ini akan dihapus!

(wajib)

(wajib)


Time limit is exhausted. Please reload the CAPTCHA.