Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem Prístup k jednej premennej z viacerými typmi deklarácie

Keď mám takúto definíciu premennej

var xy: array[0..7, 0..7] of Integer;

a chcem k nej pristupovať aj ako

var xy: array[0..63] of Integer;

tak mám na výber dve možnosti:
1.

var
  xy1: array[0..7, 0..7] of Integer;
  xy2: array[0..63] of Integer absolute xy1;

2.

var
  xy: record
    case Byte of
      1: a: array[0..7, 0..7] of Integer;
      2: b: array[0..63] of Integer;
    end;
  end;

Vie mi niekto vysvetliť, načo je dobrá druhá definícia a v čom je výhodnejšia? Prvá definícia je použiteľná v TP a myslím aj v Delphi. Overené nemám. A zaujímalo by ma hlavne toto:
1. Čo znamená Byte v case? Prečo tam nie je Word alebo niečo iné? Načo to tam vôbec je?
2. Čo znamenajú tie čísla vo vetvení case?

Viem o čo sa jedná, ale nechápem tomu vetveniu, prečo to nejde napísať nejako takto (môj výmysel):

var
  xy: record
    switch
      a: array[0..7, 0..7] of Integer;
      b: array[0..63] of Integer;
    end;
  end;
Předmět Autor Datum
Na frázi absolute zapomeň, neměla by se používat je-li vyhnutí. Ve standardním pascalu by to mělo v…
Rce 29.12.2006 00:21
Rce
1. Tak toto je potom čo? Z jedného šachového programu: type Sachovnice = record Case Byte of 0:(yx:…
msx. 29.12.2006 00:30
msx.
1: Jak jsem napsal výše: Delphi dovoluje zjednodušení (o proti standardnímu Pascalu - ten to nedovol…
Rce 29.12.2006 00:59
Rce
Napisem len nieco vseobecne: toto co robis je IMHO vseobecne nie moc dobra praktika, ptz si nemozes… poslední
MM.. 29.12.2006 02:29
MM..

Na frázi absolute zapomeň, neměla by se používat je-li vyhnutí.

Ve standardním pascalu by to mělo vypadat takto:

var
  xy: record
    CoToJe: byte;
    case CoToJe of
      1: a: array[0..7, 0..7] of Integer;
      2: b: array[0..63] of Integer;
    end;
  end;

Pak je jasné, proč jsou v CASE čísla větvení. Prostě jakou hodnotu obsahovalo CoToJe, taková větev deklarace se vybrala. Protože se ve skutečnosti jedná o redefinici téhož místa paměti, DELPHI dovoluje zjednodušení na uvedení jen typu a hodnot. Lze to třeba taky takto:

type TBarva (Cervena, Modra);
var
  xy: record
    case TBarva of
      Cervena: a: array[0..7, 0..7] of Integer;
      Modra: b: array[0..63] of Integer;
    end;
  end;

Že to nejde přes switch je dáno syntaxí jazyka.

Doporučuji, sežeň si někde knížku "Delphi v kostce" z O'Reilly (česky vydal Computer press), tam najdeš odpovědi na většinu tvých dotazů (to neznamená, že bych nechtěl odpovídat, jen bys to měl takříkajíc při ruce ;-)).

PS: V redefinicích doporučuju použít packed record, aby se tam někde nenacpaly výplňové bajty pro zaokrouhlení adres.

1. Tak toto je potom čo? Z jedného šachového programu:

type
   Sachovnice = record
   Case Byte of
      0:(yx:Array[{y}0..7,{x}0..15] of Byte);
      1:(yxs:Array[{y}0..7,{x}0..15] of ShortInt);
      2:(r:Array[0..127] of Byte);
   End;

Pri deklarácii sa tá deliaca premenná pre case nikde nedefinuje.

2. Pokiaľ viem, vraj v Turbo Pascale stratilo slovo packet význam. Stačí použiť direktívu na vypnutie Word align data $A- a je to. V Delphi je to obdobné.

1: Jak jsem napsal výše: Delphi dovoluje zjednodušení (o proti standardnímu Pascalu - ten to nedovoluje), že místo řídící proměnné záznamu stačí uvést jen její typ. Programátor pak musí sám rozhodnout (v programu), kdy a jak bude danou část paměti interpretovat. Například součástí unity SysUtils je následující definice:

  WordRec = packed record
    case Integer of
      0: (Lo, Hi: Byte);
      1: (Bytes: array [0..1] of Byte);
  end;

Typem WordRec můeme dle libosti interpretovat hodnotu typu word jako její horní bajt Hi a dolní bajt Lo nebo jako pole bajtů Bytes [0] a Bytes [1]. V SysUtils najdeš ještě další užitečné redefinice, například: LongRec a Int64Rec.

//Edit: V tebou uvedené deklaraci může programátor dle libosti, chutě a podle toho, jak se mu který algoritmus lépe dělá interpretovat šachovnici jako:
yx - dvourozměrné pole 8x16 s bajtovou hodnotou, indexováno yx [y, x] nebo:
yxs - dvourozměrné pole 8x16 s ShortInt hodnotou, indexováno yxs [y, x] a konečně nebo:
r - jednorozměrné pole 128 bajtů furt za sebou, indexováno r [x] ...
Jedná se ale furt o totéž místo paměti, takže výrazy: yx [1, 0], yxs [1, 0], r [16] označují furt jeden a tentýž bajt.
(Proč však má šachovnici 8x16 to nevím :)))

2. Packed mělo a má stále význam a to, že v záznamu nebudou generovány výplňkové bajty. Narozdíl od standartního Pascalu, kde packed určuje komprimovaný způsob uložení. Slovo packed v record je IMHO (Jez.) názornější, než direktiva $A-. Navíc direktiva $A- zatrhne výpňkové bajty na celou junitu, což rozhodně není žádoucí. Leda furt uvádět $A- a pak $A+.

Napisem len nieco vseobecne: toto co robis je IMHO vseobecne nie moc dobra praktika, ptz si nemozes byt isty ako bude reprezentovat dvojrozmerne pole nejaky (neznamy) prekladac (bude najprv prvy rozmer alebo druhy rozmer, bude tam alignment, apod). Ja viem ze standard je jasny a bude ti to fungovat na tom tvojom prekladaci, ale je to proste IMHO "spinave". Aj pouzivat absolutne cisla v programe je nevhodny zvyk, kvoli citatelnosti programu a kvoli lahkej zmene v buducnosti je vhodne pouzivat vopred definovane symboly(nazvy) namiesto cisel.
V C je na to o co sa snazis union, ale IMHO je bezpecnejsie zadefinovanie pola len raz ostatne pristupy robit napr. cez makro. Ja by som to urobil napr. takto (pouzijem syntax C):
#define SIRKA_SACHOVNICE 8
#define VYSKA_SACHOVNICE 8
int Sachovnica[SIRKA_SACHOVNICE * VYSKA_SACHOVNICE]; // toto je jedina definicia
#define SachovnicaXY(x,y) Sachovnica[x + y*SIRKA_SACHOVNICE]

A som si vzdy (na vsetkych prekladacoch a s akymkolvek nastavenim) isty ze co mam kde ulozene, a je to aj citatelnejsie a rozmer je lahko zmenitelny (asi ho nikto menit nebude ale ide mi vseobecne aj o ine cisla).
Pristup cez x,y cez to nasobenie moze byt menej efektivny (nie som si zhlavy isty ako preklada pristup na dvojrozmerne pole cez [x,y] na instrukcie CPU ci na to nie je efektivnejsia instrukcia ako nasobenie a scitanie)

Zpět do poradny Odpovědět na původní otázku Nahoru