Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailemVyřešeno pointer v Delphi

Ahoj,
při programování v Delphi 7 jsem narazil na tento problém:
Potřebují v programu dvojrozměrné pole, jehož rozměry by se daly vybrat až za běhu programu. S tím ovšem, že pole zabere právě tolik místa, kolik je potřeba (jinak bych mohl rovnou alokovat místo pro maximální velikost a bylo by po problému). Vymyslel jsem to tak, že definuji několik typů (jeden pro pole 20x20, druhý 40x40 atd.), vytvořím ukazatele na tyto typy, podle potřeby jeden z nich alokuju a přiřadím ho jedné speciální proměnné, která bude typu pointer a skrz kterou budu k poli přistupovat. Ale to je asi špatný postup, už proto že když jsem tu speciální proměnnou definoval v sekci var jako pointer, hlásilo mi to při kompilaci chyby tam kde jsem tu proměnnou chtěl použít ("array type required"), asi proto že za tou proměnnou byly ty hranaté závorky (např. specialnipromenna[x,y] ).

Nenapadá tedy někoho, jak by se tento problém dal vyřešit? Nerad bych při každém přistupování k tomu poli používal nějaký case, který by použil proměnnou podle toho, jaké má to pole velikost. Díky

Petr Kryštof

Předmět Autor Datum
U pointru nemozes pouzit predsa adresovanie sposobom [x,y], ako ma prekladac podla toho urobit vypoc…
MM.. 01.08.2007 15:48
MM..
nj to mi už došlo, byl to jen takovej pokus, s typem "pointer" nemám moc zkušeností, spíš by mě zají…
maherik 01.08.2007 15:51
maherik
v C sa to da robit napr. tak ze pouzijes index [x*velkost_riadku+y], namiesto [x,y], kde velkost_ria…
MM.. 01.08.2007 15:58
MM..
inac nerobia sa v delphi dynamicke polia nahodou takto? var A: array of Integer; begin SetLength(A,…
MM.. 01.08.2007 16:08
MM..
jenže tohle je jednorozměrný; jo, díky, je to taky varianta, ale moc se mi nechce to předělávat, už…
maherik 01.08.2007 16:21
maherik
dvojrozmerne mas tu RTL.asp ten druhy priklad (v strede obrazovky) "Declaring and using dynamic arra…
MM.. 01.08.2007 16:41
MM..
P.S. najprv pouzit google az potom robit :-D Ja len doplnim: najprv si poriadne premysliet, az poto…
Intex 02.08.2007 13:24
Intex
super, díky, to bych mohl použít, vypadá to dobře mimochodem, když mám dvojrozměrné pole, tak mě na…
maherik 02.08.2007 14:30
maherik
v tom druhom pripade sa nic neprepocitava, ale urobi sa pole pointerov (array of array) a teda pre k…
MM.. 02.08.2007 14:38
MM..
Koukam dobrej napad, tohle se muze kdykoliv hodit. Asi bych pouzil radeji assembler.:i: poslední
virus 02.08.2007 17:16
virus

v C sa to da robit napr. tak ze pouzijes index [x*velkost_riadku+y], namiesto [x,y], kde velkost_riadku je samozrejme tiez premenna kedze je to cele alokovane dynamicky. P.S. pozor na to v takom vzorci je velkost_riadku vlastne maximalne y. T.j. [x*max_y + y]. Alebo sa to da otocit o 90°, pouzit max_x, a teda vypocet bude [x + y*max_x]. P.S. v C by to bolo max_y+1 resp. max_x+1 lebo indexy su od 0, delphi ma indexy tusim od 1 takze potom je to len max_x a max_y.
V delphi neviem ci sa da za pointerom vobec pouzit index v [] alebo ci je nutne pouzivat za pointerom specialny operator. vid google najdi si nejake delphi basics

jenže tohle je jednorozměrný; jo, díky, je to taky varianta, ale moc se mi nechce to předělávat, už jsem celkem daleko; možná teda že mi nic jinýho nezbyde

doufal jsem, že by to šlo nějakým přetypováním, u nějaké proměnné za běhu programu nastavit typ dvojrozměrného pole podle potřeby

dvojrozmerne mas tu
RTL.asp
ten druhy priklad (v strede obrazovky) "Declaring and using dynamic arrays"

zjednodusene

var
  multiArray : Array of Array of string;  // Multi-dimension array
  i,j : Integer;

begin
  SetLength(multiArray, 3);  // tu je prvy rozmer (pocet "riadkov" pola)

  // tu si nastavis druhy rozmer (da sa pre kazdy "riadok" pola nastavit iny rozmer ako tu vidno:
  SetLength(multiArray[0], 1);
  SetLength(multiArray[1], 2);
  SetLength(multiArray[2], 3);
  // alebo si mozes nastavit vsetky riadky na rovnaky rozmer v cykle

  // Set and show all elements of this array
  for i := 0 to High(multiArray) do
    for j := 0 to High(multiArray[i]) do
    begin
      multiArray[i,j] := IntToStr(i+j);
      ShowMessage('multiArray['+intToStr(i)+','+intToStr(j)+'] = '+
                  multiArray[i,j]);
    end;
end;

P.S. najprv pouzit google az potom robit :-D
p.S.2. inac dufam ze je jasne ze budes musiet robit zasahy aj do kodu programu, tam kde sa napr. v cykle plni cele pole hodnotami apod. budes musit zmodifikovat hranicne hodnoty cyklu (predtym to boli hodnoty staticke, t.j. nejake pevne cisla (velkost pola), tie sa musia zmenit na hodnoty dynamicke, podla velksori pola, t.j. musis to zmenit na nejake premenne)

super, díky, to bych mohl použít, vypadá to dobře

mimochodem, když mám dvojrozměrné pole, tak mě napadá, při běhu toho programu se to stejně samo musí přepočítávat ne? To pole je přeci úsek paměti, kde se tak jako tak musí ta pozice vypočítat vynásobením jedné souřadnice "délkou řádku" a přičtením druhé. Zajímalo by mě totiž, jestli bych ten program zpomalil, kdyby to pole bylo jen jednorozměrné a já si k tomu druhému rozměru pomohl tímhle dopočítáváním, které bych si dělal sám. Chtěl bych se zeptat, jestli ta myšlenka je správná, protože potom by bylo (co do rychlosti programu) jedno, jestli bych použil dvojrozměrné pole nebo jednorozměrné s tím dopočítáváním.

to ale spíš pro pochopení principu, jinak asi použiju to cos napsal posledně, vypadá to opravdu dobře

v tom druhom pripade sa nic neprepocitava, ale urobi sa pole pointerov (array of array) a teda pre kazdy riadok sa alokuje pamat osobitne a ulozi sa pointer na dany riadok do toho pola pointerov. Prvy rozmer teda vlastne vybere spravny pointer, a podla druheho rozmeru sa potom posuva v tom riadku.

Co je efektivnejsie tazko povedat zavisi od prekladaca ze ako ten druhy pripad prelozi a ake packalovske kontroly tam prevadzkuje. Ten prvy pripad je lepsi pri alokacii pola (alokuje sa len raz cely kus pamate), druhy pripad je lepsi pri pristupe k prvkom pola ak sa to efektivne naprogramoje (napr. pri sekvencom pristupe k riadku si precitam pointer na riadok len raz a posuvam ho po riadku) a ak to prekladac efektivne prelozi (C je v tomto lepsi nerobi ziadne kontroly). Najefektivnejsie je napisat ten pristup k polu v assembleri :-)

P.S. ak to pole nepouzivas v nejakej kritickej oblasti (napr. ak sa k tomu nepristupuje miliardu krat po sebve) tak je to plusminus jedno ze co pouzijes. To jedno nasobenie to moc nespomali.

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