MFF UK / Ústav teoretické fyziky / Tomáš Ledvinka
Přednášky
. . . . . . . . . . . . . . . . . . . . . . . . . .
Programování pro fyziky (1.r)
  Úvod
  Programy a algoritmy
  Píšeme program
  Píšeme program II
  Procedury a funkce
  Malujeme funkce
  Chyby. Typy I.
  Typy II. Pole a Záznamy
  Pole II.Řetězce.Soubory.
  Gnuplot.Interpolace...
  Matice. Velké O...
  Fronta,Zásobník. Postscript
  Bin. soubory, ...
  Ukazatele,Objekty, ...
    Ukazatele
    Přetypování
    Num. kvadratura
    Objekty
    Přehled probraných témat
Počítačová algebra
Klasická elektrodynamika (2.r)
Vybrané partie OTR

Cvičení
. . . . . . . . . . . . . . . . . . . . . . . . . .
Programování pro fyziky (1.r)
Teoretická mechanika (2.r)
Klasická elektrodynamika (2.r)


Věda
. . . . . . . . . . . . . . . . . . . . . . . . . .
Diskové zdroje v OTR
Hyperbolické systémy v OTR


Kontakt
. . . . . . . . . . . . . . . . . . . . . . . . . .
Email
Konzultační hodiny


Ostatní
. . . . . . . . . . . . . . . . . . . . . . . . .
Mallorca
Ze společnosti

Přetěžování funkcí a procedur (overloading)

I když dnes už nemusí být identifikátory dlouhé nanejvýš šest či osm znaků, stále je problém, když dvě procedury dělají totéž, ale ne docela. V následujícím programu jsou definovány čtyři funkce označené stejným identifikátorem Soucet, místo abychom použili čtyři různé idnetifikátory, řekněme SoucetIntPole, SoucetRealPole, SoucetRRPoli, SoucetRIPoli. Pravidlo pro tvorbu přetížených funkcí a procedur je snadné: žádné dvě nesmějí mít stejné typy povinných formálních parametrů (nepovinné jsou ty s deklarací Id : Typ = DefaultHodnota), rozhodně nestačí aby se dvě funkce lišily jen typem vrácené hodnoty. Překladač (i programátor, že) prostě musí mít jasno v tom, která procedura se tím či oním zápisem aktuálních parametrů vlastně zavolá.

program Soucty;

type tRealVec = array of real;

const Ai : array [1..3] of integer = (1,2,3);
      Ar : array [1..3] of real    = (1.0,2.0,3.0);

function Soucet(const A: array of integer):integer; overload;
var i,s : integer;
begin
  s:=0;
  for i := Low(A) to High(A) do s := s+A[i];
  Soucet := s;
end;

function Soucet(const A: array of real):real; overload;
var i : integer;
    s : real;
begin
  s:=0;
  for i := Low(A) to High(A) do s := s+A[i];
  Soucet := s;
end;

function Soucet(const A,B: array of real):tRealVec; overload;
var i : integer;
    s : tRealVec;
begin
    SetLength(s,High(A)+1);
    Assert(High(A)=High(B),'Soucet (r+r vektoru): Scitana pole museji by stejne dlouha!');
    for i:= Low(A) to High(A) do s[i] := A[i]+B[i];
    Soucet:=s;
end;

function Soucet(const A: array of real; const B: array of integer):tRealVec; overload;
var i : integer;
    s : tRealVec;
begin
    SetLength(s,High(A)+1);
    Assert(High(A)=High(B),'Soucet (r+i vektoru): Scitana pole museji by stejne dlouha!');
    for i:= Low(A) to High(A) do s[i] := A[i]+B[i];
    Soucet:=s;
end;

procedure WriteVecLn( const A: array of real; w: integer = 14; d : integer = 12);
var i,imax : integer;
begin
  Write('[');
  imax := High(A);
  for i:= Low(A) to imax do begin
    Write(A[i]:w:d,' ');
    if i<imax then Write(',');
  end;
  WriteLn(']');
end;

begin
  WriteLn(Soucet(Ai));
  WriteLn(Soucet(Ar));
  WriteVecLn(Soucet(Ar,Ai));
  Readln;
end.

Protože přetěžování funkcí spíše zvyšuje čitelnost programu (s obvyklými důsledky), i když nepochází od Wirtha, nemusíte se za použití této techniky stydět. To naopak neplatí o následujícím tématu.

Přetypování (type cast)

je operace, kdy z výrazu nebo proměnné jednoho typu vyrobíme výraz či proměnnou jiného typu, aniž se s bity a bajty něco děje.

program TypeCasts;

type tBarva = (Cerna, Modra, Zelena, Cervena, Bila);
     t8byte = array[0..7] of byte;
     pInt64 = ^int64;

var Barva : tBarva;
    i     : Integer;
    i64   : Int64;
    r     : Real;

begin
  {Přetypování ordinálního výrazu}
  Writeln( Boolean(0) );
  Writeln( Integer(Modra) ); {tohle by šlo i přes ord}
  Barva := tBarva( 4 );

  {Přetypování proměnné}
  byte(Barva) := 4;    {provede totéž, co předchozí příkaz}

  r := Pi; {int64(t8byte(Pi)) se samozřejmě nesmí, Pi neni proměnná }
  Writeln(int64(t8byte(r)));{Kvůli bezpečnosti je zakázáno
                            přímé přetypování real <-> celé číslo}


  {Přetypování ukazatele}
  Writeln( ( pInt64( @r ) )^ );

  Readln;
end.

Výše uvedený program ilustruje tři různé druhy přetypování:

  • Přetypování výrazu ordinálního typu, kdy z výrazu ord. typu tA učiníme výraz ord. typu tB. Protože ordinální typy jsou vlastně jen intervaly celých čísel, existuje přirozené zobrazení z tA do tB [ takové, kdy ord(a) = ord(b) ].
  • Přetypování proměnné, kdy řekneme kompilátoru, aby na oblast paměti, kde je uložena proměnná typu tA nahlížel jako by tam byla uložena proměnná typu tB. Podmínkou je, aby velikosti proměnných obou typů byly shodné [sizeof(tA) = sizeof(tB) ] a aby nešlo o převod mezi celými a reálnými čísly (z důvodu bezpečnosti, aby se někdo nedivil, že int64(PromennaTypuRealSHodnotouRovnouPi) = 4 614 256 656 552 045 848).
  • Přetypování ukazatelů, kdy výraz typu ukazatel na tA (tedy ^tA) předěláme na výraz typu ukazatel na tB, přičemž oba ukazují na oblast začínající na stejné adrese.

V každém případě je přetypování operací velmi post-Wirthovskou a někteří z vás jej nebudou nikdy potřebovat.

.