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
U pointru nemozes pouzit predsa adresovanie sposobom [x,y], ako ma prekladac podla toho urobit vypocet adresy prvku? (napr. adresa je x*VELKOST_RIADKU+y), ked nepozna kolko je VELKOST_RIADKU?
Najprv mysliet potom robit.
nj to mi už došlo, byl to jen takovej pokus, s typem "pointer" nemám moc zkušeností, spíš by mě zajímalo jestli někoho nenapadá jak na to..
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
inac nerobia sa v delphi dynamicke polia nahodou takto?
var
A: array of Integer;
begin
SetLength(A, 1); // tu sa naalokuje miesto pre pole
A[0] := 1;
end;
P.S. alebo RTL.asp
ten druhy priklad (v strede obrazovky) "Declaring and using dynamic arrays"
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
P.S. najprv pouzit google az potom robit
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)
Ja len doplnim: najprv si poriadne premysliet, az potom robit...
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.
Koukam dobrej napad, tohle se muze kdykoliv hodit. Asi bych pouzil radeji assembler.