Pascal programozás alap és haladó szinten!

Mindenkinek akit kicsit is érdekel ,de tudni akar! AZ övék ez a honlap!

7.jpg

Mutatók

11.1 Típusos mutató

Deklarálása: azonosító: ^alaptípus                         Pl. Var p1, p2: ^real;

A mutató egy memóriacímet (4 bájtos: szegmens, ofszet) tartalmaz, egy alaptípusú változóra mutat. A mutatóhoz futás közben rendelhetünk memóriacímet és így tárterületet (dinamikus adattárolás).
A New eljárás a heap memóriában foglalterületet a mutatott változó számára, a Dispose eljárás pedig felszabadítja a lefoglalt területet. Így lehetõvé válik, hogy egy nagy helyfoglalású adatstruktúra számára csak akkor kössünk le memóriát, amikor használjuk a változót. Nézzünk erre egy példát:

    type TTomb = array[1..1000]of real;
    var t: TTomb;  {A rendszer már a program idításakor lefoglal 6000 bájtot az adatszegmensben}
        pt: ^TTomb;{A rendszer a program idításakor csak 4 bájtot foglal le a mutató számára}
    begin
      ...
      New(pt);     {A heap-ben létrejön a mutatott változó}
      ...          {Használhatom a pt által mutatott változót (pt^)}
      Dispose(pt)  {A terület felszabadul a heap-ben}
    end.

A mutatót ráirányíthatjuk egy az alaptípusával megegyezõ típusú változóra a @ operátorral vagy az Addr függvénnyel. Pl. pt := @t; vagy pt := Addr(t).
A Ptr függvénnyel a mutatónak egy tetszõleges memóriacímet adhatunk értékül.
A negyedik lehetõség arra, hogy egy mutatóhoz egy memóriacímet rendeljünk: értékadó utasítás egy vele azonos alaptípusú mutatóval.

Hivatkozás a mutatott változóra: mutató-azonosító^                      (pl.: pt^[12] := 1)

Mutató típusú konstans: Nil.
A Nil nem mutat sehová. (Pl. láncolt lista végének a jelzésére használhatjuk).

Mûveletek: Címe: @             Egyenlõség vizsgálat: =, <>

További szabványos eljárások, függvények:
Eljárások: Mark, Release                       Függvények: MaxAvail, MemAvail, Ofs, Seg

Láncolt listák: A különbözõ típusú láncolt listák nagyon fontos adatszerkezetek a számítástechnikában. Az egyes adatelemek (rekordok) közötti csatolást mutatókkal valósíthatjuk meg, így a rekordnak van egy mutató típusú mezõje, melynek alaptípusa maga a rekord. Az alábbi példában figyeljük meg, hogy a mutató típus deklarálásánál olyan azonosítót használunk, amely a programunkban csak késõbb szerepel. (A Pascal ebben az egy esetben engedi ezt meg.)

    type Mutato = ^Adatelem;
         Adatelem = record
           Adat: real;
           Kovetkezo: Mutato;
         end;
    var Elso, Uj, Aktualis: Mutato;

 

Példák: 1. Fûzzük fel láncolt listára a billentyûzetrõl beolvasott számokat. Írassuk ki a listát!
Megoldás: Láncolt lista - példaprogramok

1.

program Lista1;
uses Crt;
type TMutato = ^TAdatElem;
     TAdatElem = record
       Adat: integer;
       Kovetkezo: TMutato;
     end;
var  Elso, Aktualis, Uj: TMutato;
     a: integer;
begin
  ClrScr;
  ReadLn(a);
  Elso := nil;
  while a <> 0 do
    begin
      New(Uj);                      {Az Uj mutatóhoz memóriaterület rendelése}
      Uj^.Adat := a;
      Uj^.Kovetkezo := nil;
      if Elso = nil then
        Elso:=uj                    {Elsõ rekord, az Elso mutat az Uj-ra}
      else
        Aktualis^.Kovetkezo := Uj;  {Az Aktualis-hoz csatoljuk az Uj-at}
      Aktualis := Uj;               {Az Aktualis léptetése}
      ReadLn(a)
  end;
  {A lista megjelenítése}
  WriteLn;
  Aktualis := Elso;
  while Aktualis <> nil do
    begin
      WriteLn(Aktualis^.Adat);
      Aktualis := Aktualis^.Kovetkezo
    end;
  ReadKey
end.

2. Fûzzük fel rendezett láncolt listára a billentyûzetrõl beolvasott számokat. Írassuk ki a listát!
Megoldás

2.

program Lista2;
uses Crt;
type TMutato = ^TAdatElem;
     TAdatElem = record
       Adat: integer;
       Kovetkezo: TMutato;
     end;
var  Elso, Aktualis, Uj, Elozo: TMutato;
     Szam: integer;
begin
  ClrScr;
  Elso := nil;
  ReadLn(Szam);
  while Szam <> 0 do
    begin
      New(Uj);
      Uj^.Adat := Szam;
      Uj^.Kovetkezo := nil;
      {Az Uj rekord helyének a megkeresése a rendezett listában}
      Aktualis := Elso;
      while (Aktualis <> nil) and (Aktualis^.Adat < Uj^.Adat) do
        begin
          Elozo := Aktualis;
          Aktualis := Aktualis^.Kovetkezo;
        end;
      {Az Uj rekord beillesztése a listába}
      if Aktualis = Elso then   {Az Elso elem lesz}
        Elso := Uj
      else                      {Az Elozo mögé, az Aktualis elé}
        Elozo^.Kovetkezo := Uj;
      Uj^.Kovetkezo := Aktualis; 
      ReadLn(Szam)
    end;
  {A lista megjelenítése}
  WriteLn;
  Aktualis := Elso;
  while Aktualis<>nil do
    begin
      WriteLn(Aktualis^.Adat);
      Aktualis := Aktualis^.Kovetkezo;
    end;
  readkey
end.

 

11.2 Típusnélküli mutató - Pointer

Deklarálása: POINTER

Egy négy bájtos memóriacímet tartalmaz. A mutatott változónak nincs típusa. A típusnélküli mûveleteknél használjuk (pl. adatmozgatás).
A GetMem eljárással foglalhatunk le egy megadott méretû területet a heap-ben a mutatónk számára. Ha a memóriaterületre már nincs szükségünk a FreeMem eljárással azt felszabadíthatjuk.
A mutatót ráirányíthatjuk akármilyen címre vagy változóra a @ operátorral vagy az Addr függvénnyel. Pl. p := @tomb1; vagy p := Addr(tomb1).
A Ptr függvénnyel a mutatónak egy tetszõleges memóriacímet adhatunk értékül.
Egy mutató értékadó utasítással egy másik mutató címét is felveheti.
A mutatott változóhoz rendelhetünk típust: típus(mutató-azonosító^).

Hivatkozás a mutatott változóra: mutató-azonosító^

Mutató típusú konstans: Nil.

Mûveletek:
Címe: @
Egyenlõség vizsgálat: =, <>

További szabványos függvények: MaxAvail, MemAvail, Ofs, Seg

Példa: 1. Mentsünk el egy garfikát egy típus nélküli állományba, majd olvassuk vissza!

Megoldás: Típusnélküli mutató - példaprogram

program KepMent;
uses Crt, Graph;
var f: file;          {A típusnélküli állomány, amelybe mentjük a képet}
    kep: pointer;     {A kép memóriába való elmentéséhez szükséges mutató}
    d, m: integer;
    meret: word;
    grd, grm, a, b, c, px, py, py1, i: integer;
    x, y: real;
begin
  {Grafika kirajzolása (két függvény ábrázolása)}
  d := detect;
  InitGraph(d, m, 'c:\bp\bgi');
  a := 1;
  b := -2;
  c := -3;
  for i := 0 to 640 do PutPixel(i,240,14);
  for i := 0 to 64 do begin PutPixel(10*i,241,14); PutPixel(10*i,239,14) end;
  for i := 0 to 480 do PutPixel(320,i,14);
  for i := 0 to 48 do begin PutPixel(319,10*i,14); PutPixel(321,10*i,14) end;
  for i := -320 to 320 do
    begin
      x := i/10;
      y := 5*Sin(x/4);
      px := Round(10*x + 320);
      py := Round(-10*y + 240);
      py1 := Round(-10*x + 240);
      if (py < 480) and (py > 0) then PutPixel(px,py,15);
      if (py1 < 480) and (py1 > 0) then PutPixel(px,py1,15)
    end;
 
  Assign(f, 'kepment.dat');
  Rewrite(f);
  {A képet négy részletben tudjuk elmenteni}
  meret := ImageSize(0, 0, 319, 239); {A negyedkép mérete}
  GetMem(kep, meret);                 {Helyfoglalás a típusnélküli mutatónak a heap-ben}
  GetImage(0, 0, 319, 239, kep^);     {Negyedkép elmentése a mutatott területre}
  BlockWrite(f, kep^, meret div 128); {A memóriaterület elmentése a fájlba}
  GetImage(320, 0, 639, 239, kep^);
  BlockWrite(f, kep^, meret div 128);
  GetImage(0, 240, 319, 479, kep^);
  BlockWrite(f, kep^, meret div 128);
  GetImage(320, 240, 639, 479, kep^);
  BlockWrite(f, kep^, meret div 128);
  FreeMem(kep, meret);                {A memóriaterület felszabadítása}
 
  {A kép visszaolvasása}
  ReadKey;
  ClearDevice;
  ReadKey;
  Reset(f);
  GetMem(kep, meret);                 {Helyfoglalás a típusnélküli mutatónak a heap-ben}
  BlockRead(f, kep^, meret div 128);  {Adatmozgatás a fájlból a lefoglalt memóriaterületre}
  PutImage(0, 0, kep^, copyput);      {A negyedkép kirajzolása}
  BlockRead(f, kep^, meret div 128);
  PutImage(320, 0, kep^, copyput);
  BlockRead(f, kep^, meret div 128);
  PutImage(0, 240, kep^, copyput);
  BlockRead(f, kep^, meret div 128);
  PutImage(320, 240, kep^, copyput);
  FreeMem(kep, meret);                {A memóriaterület felszabadítása}
 
  ReadKey;
end.

5.jpg


Weblap látogatottság számláló:

Mai: 7
Tegnapi: 7
Heti: 18
Havi: 83
Össz.: 153 434

Látogatottság növelés
Oldal: Mutatók
Pascal programozás alap és haladó szinten! - © 2008 - 2024 - kerigseoszt.hupont.hu

A HuPont.hu-nál a honlap készítés egyszerű. Azzal, hogy regisztrál elkezdődik a készítés!

ÁSZF | Adatvédelmi Nyilatkozat

X

A honlap készítés ára 78 500 helyett MOST 0 (nulla) Ft! Tovább »