Na FreeHostingu Endora běží desítky tisíc webů. Přidejte se ještě dnes!

Vytvořit web zdarma

Na FreeHostingu Endora běží desítky tisíc webů. Přidejte se ještě dnes!

Vytvořit web zdarma

int21h

Pseudopole v pascalu

Co je pole, je jasn. Pascal ale zn i tzv. pseudopole. Z klasickho Turbo pascalu urit znte pseudopole Port a PortW. Zde je na mst otzka, co je to vlastn za. Nen to blok pamti, ale jaksi virtualizovan pstup ke skrytm procedurm. To me bt uiten i v mnoha jinch ppadech, ale bohuel, Turbo pascal neumouje tvoit si vlastn pseudopole. To je rys, pro kter bv pascal vysmvan programtory jinch jazyk, tedy, e programtor neme vytvoit analogie nkterch zabudovanch konstrukc. A z toho odvozuj, e pascal nen plnohodnotn programovac jazyk. To je samozejm nesmysl a navc pro Freepascal neplat ani prvn st nmitky. Ve Freepascalu toti je mon tvoit vlastn pseudopole a um to ob generace: 1.x.x i 2.x.x.>

Pseudopromnn

Ne se pustme do pseudopol, zaneme trochu jednodumi pseudopromnnmi. Pozad tto syntaxe je dosti sloit a v tomto lnku se nebudu poutt do rozshlho vkladu a omezm se jen na minimum. Teorii a systematick vklad syntaxe si mete pest z manulu k Freepascalu nebo z jakkoliv lep knihy o Delphi.
Pseudopromnn jsou odvozeny od jedn vlastnosti td z objektovho programovn. Ppomeme si, e TP i BP znaj tzv. objekty, co je seskupen procedur, funkc a promnnch, ve kterch procedury a funkce objektu spolen sdl promnn objektu. Freepascal (a Delphi) krom objekt znaj i tdy (class), kter koncept objekt v rznch aspektech rozuj. Jednm z rozen jsou tzv. properties, co se do etiny pekld jako vlastnosti.
Ukame si progrmek:
{$MODE OBJFPC}         {Nutno zapnout budto takto nebo pomoci nastaveni v menu}
type TTrida = class
     public
        Procedure PriradCislo(i:longint);
        Function ZjistiCislo:longint;
        property cislo:longint read ZjistiCislo write PriradCislo;

     protected
        vnitrnicislo:shortint;
     end;

Procedure TTrida.PriradCislo(i:longint);
begin
if i<(-128) then i:=-128;
if i>127 then i:=127;
vnitrnicislo:=i;
end;

Function TTrida.ZjistiCislo:longint;
begin
ZjistiCislo:=vnitrnicislo;
end;

var trida:TTrida;
begin
trida:=TTrida.Create;
trida.cislo:=4543;
writeln(trida.cislo);
readln;
end.
Ped sebou mme ne zcela triviln kd, kter piad promnn vnitrnicislo hodnotu. Mon se ptte, pro to dlat tak sloit, kdy by prost stailo ponechat vnitrnicislo v reimu public a provst piazen:
trida.vnitrnicislo:=HODNOTA
No jo, jene vimnte si, e vnitrnicislo je jenom shortint a lehko bychom mohli piadit hodnotu mimo rozsah, co by vedlo k neoekvanmu chovn programu. Oklika pes pseudopromnnou cislo umouje provst kontrolu rozsahu a podobnm vcem zamezit. A nejen to. Obsah obslunch funkc PriradCislo a ZjistiCislo me bt libovoln a zdaleka se nemus jen omezovat na kontroly rozsah. Jako dobr zpsob pouit m napad ukldn piazovanch hodnot do logovacho souboru, co by umoovalo snadnj analzu chyb.

Pseudopole

Pseudopole jsou dalm drobnm rozenm vymoenosti property, potamo pseudopromnnch. Bez dlouhch e si ukame kd, kter se podob standardn pascalovsk definici pseudopole Port
{$MODE OBJFPC}
{$CALLING OLDFPCCALL}
type TBrana = class
     public
        Procedure DoPortu(p:word;b:byte);
        Function ZPortu(p:word):byte;
        property B[p:word]:byte read ZPortu write Doportu;
     end;

Procedure TBrana.DoPortu(p:word;b:byte);assembler;
asm
mov dx,p
mov al,b
out dx,al
end;

Function TBrana.ZPortu(p:word):byte;assembler;
asm
mov dx,p
in al,dx
end;

var brana:TBrana;
    i:longint;
    a:byte;
begin
brana:=TBrana.Create; {ve skutecnosti neni nutne, nebot nepristupujeme k zadnym datum tridy}

writeln('Po zmacknuti Enteru program pocka 700 snimkovych behu, tedy 10 sekund');
readln;
writeln('Start!');
for i:=1 to 700 do
    begin
    while Brana.B[$3da] and 8 <> 0 do;
    while Brana.B[$3da] and 8 = 0 do;
    end;
writeln('Cas uplynul!');
readln;
end.
Docela se to u podob pascalovskmu pseudopoli Port, e? Ale jak odstranit ono ohyzn "Brana.B" a nahradit to prostm "Brana"? Jde to? Ano, jde.
Do deklarace property jde toti vsunout kouzeln modifiktor default, kter umon vynechat st ".B"
Take do tetice krtk progrmek, kter piprav pseudopole pesn tak, jak jsme zvykl. Opakovat pklad z porty by ale bylo nudn, take si ukeme, jak virtualizovat obrazovku do dvourozmrnho pseudopole, a pipomeneme si, jak ve Freepascalu provst pm zpis do videopamti.
{$MODE OBJFPC}
const SIRKAOBRAZOVKY:longint = 80;
      VYSKAOBRAZOVKY:longint = 25;

type
     TObr = class
     private
        Function RozsahOK(x,y:byte):boolean;
        Procedure ZapisZnak(x,y:byte;c:char);
        Function PrectiZnak(x,y:byte):char;
     public
        property ZZ[x,y:byte]:char read PrectiZnak write ZapisZnak;default;
        end;

Function TObr.RozsahOK(x,y:byte):boolean;
begin
RozsahOK:=(x>0) and (y>0) and (x<=SIRKAOBRAZOVKY) and (y<=VYSKAOBRAZOVKY);
end;

Procedure TObr.ZapisZnak(x,y:byte;c:char);
begin
if RozsahOK(x,y) then
   asm
   movzx ebx,y
   movzx eax,x
   dec ebx
   dec eax
   imul ebx,SIRKAOBRAZOVKY
   add ebx,eax
   shl ebx,1
   add ebx,0B8000h
   mov al,c
   mov fs:[ebx],al
   end;
end;

Function TObr.PrectiZnak(x,y:byte):char;
begin
if RozsahOK(x,y) then
   asm
   movzx ebx,y
   movzx eax,x
   dec ebx
   dec eax
   imul ebx,SIRKAOBRAZOVKY
   add ebx,eax
   shl ebx,1
   add ebx,0B8000h
   mov al,fs:[ebx]
   end;
end;

var Obr:TObr;
    x,y:byte;
    
begin
{Obr:=TObr.Create}   {neni treba, protoze neprisupuji k promennym tridy}
for y:=10 to 20 do
    for x:=20 to 60 do
        Obr[x,y]:='*';  {Mozno i Obr.ZZ[x,y]:='*'  (ale proc tak osklive?)}
readln;
end.
Properties maj pochopiteln mnohem ir pouit ne jen tvorba psedopol. Velice uiten jsou napklad v tvorb uvatelskch rozhran (GUI), kdy je jejich pomoc mon doshnout toho aby se pi zmn parametr grafickho prvku zmna okamit projevila na obrazovce. Napklad zavolnm...
Tlacitko.text:='zmeneny text';
...patin obalenm v properties doshneme toho, aby mnc procedura rovnou zavolala Tlacitko.Draw a zmna se tak ihned projevila na obrazovce.

A to je ve.
2009-07-12 | Laaca