Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem pascal-typ ukazovatel a zoznamy

mam zdrojak v pascale, takmer vlastnorucne prepisany.
ide v nom o typ ukazovatel a vytvaranie zoznamov....
Problem ale je, ze velkost pamate pred spustenim a po spusteni sa nerovna(co by sa zevraj malo).
Nakolko tomuto zatial dost dobre nerozumiem(respektive vobec), bol by niekto taky dobry a povedal mi, kde mam chybu? dik.

zdrojak najdete tu:

http://stredoslovak.szm.sk/ZOZNAM.PAS

alebo:

http://stredoslovak.szm.sk/ZOZNAM.rar

Na zaciatku tvorby tohto programu som to skusal kadejako editovat a vsimol som si, ze ked som tam nepouzil prikaz premenna:=nil, tak potom sa velkost pamete pred a po rovnala. lenze prikaz nil tam pouzivam a neviem, ci sa to vobec da spravit bez neho.
dik za odpovede.

Jsou zobrazeny jen nové odpovědi. Zobrazit všechny
Předmět Autor Datum
Žiaľ tam je chýb viac. Ty nesmieš akolovať pamäť pre smerníky, ktorým priradíš hodnotu nejakého smer…
msx. 14.04.2006 22:26
msx.
...tak to si ma moc nepotesil :-( Vo stvrtok z tohto pisem pisomku a o tyzden v pondelok treba odovz…
Pavol 14.04.2006 22:44
Pavol
Ty tam proste robíš s jedným poľom údajov. Takže new() použiješ len raz. Ostatné smerníky nastavuješ…
msx. 14.04.2006 22:52
msx.
V osnovách přetrvává styl programování v assembleru, který se používal tak před 20 až 30 lety (nepří…
Rce 15.04.2006 00:37
Rce
Dovolim si zasadne nesuhlasit s tvrdenim "Dnes skutečně není pro používání směrníků (ukazovátek, poi…
MM.. 16.04.2006 03:33
MM..
a ja si dovolim s nazorom MM.. plne suhlasit. smernik je velmi silna vec v rukach znaleho cleveka a…
IgorK 16.04.2006 03:38
IgorK
Aj ja súhlasím, ale robiť databázu s variabilnou dĺžkou cez smerníky je v dnešnej dobe blbosť. Stačí…
msx. 16.04.2006 05:27
msx.
Ja neviem co sa tam snazil robit, ani ake mal zadanie (nestudoval som poriadne otazku), ale nesnazi… nový
MM.. 16.04.2006 14:08
MM..
Lenže na čo to robiť takto, keď v jazyku Object Pascal sa to dá urobiť rýchlejšie? Tkéto programy sú… nový
msx. 16.04.2006 14:41
msx.
V skole nejde o to urobit nieco rychlejsie, ale o to aby studenti pochopili ake a naco su jednotlive… nový
MM.. 16.04.2006 20:54
MM..
A 100 000 prvku ve spojovem seznamu ma byt jako efektivni reseni? To snad ne. nový
michich 17.04.2006 14:33
michich
Ja som netvrdil ze si to musis alokovat po jednom, ani ze mal pouzit spojkovy zoznam, tvrdim ze prog… nový
MM.. 17.04.2006 17:08
MM..
Dobre, tak to jsem te asi jen spatne pochopil. Tezko navrhovat konkretni datovou strukturu, kdyz nev… nový
michich 17.04.2006 17:25
michich
Najprv si sadni nad prednasky/skripta alebo si daj do google "linked list" a snaz sa to pochopit. Az… nový
MM.. 16.04.2006 14:36
MM..
uz to mam takmer hotove: http://stredoslovak.szm.sk/ZOZNAM.PAS este by ma zaujimalo-automaticky ta… nový
Pavol 17.04.2006 12:04
Pavol
memavail() Ty potrebuješ zistiť voľnú pamäť, nie najväčší blok. Najväčší blok je vtedy potrebný, ak… nový
msx. 17.04.2006 13:05
msx.
Hezký. Čtení náhodně generovaných jmen mě pobavilo :-D Na první pohled se to zdá v pořádku (ale komu… nový
Rulda 17.04.2006 15:20
Rulda
- když už jsme u toho rozsahu, tak se mi vůbec zdá, že kódem nešetříš. Proč např. u zmiňovaného výpi… nový
Rulda 17.04.2006 15:27
Rulda
A ještě k té paměti. Msx. se bude zlobit, ale já mám jiný názor. Jedna položka v seznamu (v tomto př… nový
Rulda 17.04.2006 15:34
Rulda
Hnevať sa nebudem vlastne máš pravdu, totiž, ak bude voľné miesto na alokovanie dostatočnej pamäte,… poslední
msx. 17.04.2006 22:56
msx.
...premennu kon pouzivam pri pridavani polozky na koniec. Prirobim tam teda este procedury. I:5,':',… nový
Pavol 17.04.2006 15:45
Pavol
jj. S tím kon máš pravdu. Pokud chceš zarovnávat doleva, jde to udělat pomocí Lenght(vrací počet zn… nový
Rulda 17.04.2006 16:09
Rulda

Žiaľ tam je chýb viac. Ty nesmieš akolovať pamäť pre smerníky, ktorým priradíš hodnotu nejakého smerníka. Takisto ju nesmieš ani dealokovať. Ty to robíš tak, ako keby kúpiš auto (alokuješ pamäť) a potom svoje necháš na ulici a požičiaš si susedove (priradíš hodnotu iného smerníka). Keď raz kúpiš auto (vytvoríš smerník) a používaš len to jedno (iný smerník so záznamami nepoužívaš) nepotrebuješ iné auto, čiže nemá zmysel kupovať ďalšie (načo alokovať miesto pre ďalšie smerníky?). Ide o to, že ty len obsah smerníka uložíš do druhého (to ako keby si požičal auto niekomu ty), čiže on to auto už kupovať nemusí (nemusíš alokovať miesto pre smerník).

Tipujem, že si mi nerozumel o čom píšem. Ostatní programátori dúfam áno. Ty si musíš smerníky poriadne ešte naštudovať, lebo máš v tom poriadny zmätok.

Ty tam proste robíš s jedným poľom údajov. Takže new() použiješ len raz. Ostatné smerníky nastavuješ podľa tohto prvého, takže všetky zbytočné new() a dispose() musia preč. Pri hľadaní tam to dispose() nemá čo hľadať. Tým si iba dealokuješ to, čo si si alokoval. A vždy keď vytvoríš nový prvok poľa, tak použiješ new(). Potom samozrejme, keď končí program, tak musíš použiť dispose() pre každý prvok poľa.

Edit: Už asi 2 alebo 3 týždne chápem tomu, čo raz dávno povedal Jan Fiala a to, že v školách sa používajú zastaralé metódy. V Delphi nikdy nikto nepotrebuje vedieť ako sa robí so smerníkmi pri vytváraní databáze. Vtedy som sa hádal, že smerníky treba pochopiť, ak chce niekto vedieť programovať, ale teraz viem, že toto je zbytočné (myslím takúto úlohu, ako má dotyčný). Pascalu v DOSe už odzvonilo. Dokonca som uvažoval aj o vytvorení vlákna na túto tému.

V osnovách přetrvává styl programování v assembleru, který se používal tak před 20 až 30 lety (nepřímá adresa s bází v registru). Dnes skutečně není pro používání směrníků (ukazovátek, pointerů) rozumný důvod. Kdyby je raději učili používat objekty. :-/

Dovolim si zasadne nesuhlasit s tvrdenim "Dnes skutečně není pro používání směrníků (ukazovátek, pointerů) rozumný důvod".
Pouzitie smernika je v mnohych pripadoch efektivnejsie ako ine moznosti ktore dany programovaci jazyk ma.
P.S. "pouzivat objekty" je v podstate pouzivanie smernikov, len je to pekne "zabalene" (objekt je v podstate len jedna kopa smernikov plus kod a data samozrejme ;))

Ja neviem co sa tam snazil robit, ani ake mal zadanie (nestudoval som poriadne otazku), ale nesnazi sa on napr. robit spojkovy zoznam, alebo obojsmerny spojkovy zoznam? To je jedna zo zakladnych datovych struktur a pouzitie smernikov je tam NUTNE. Je normalne ze sa v skole snazia studentom vysvetlit datove struktury, aby aspon chapali co program bude robit ked sa pouzije napr. objekt typu "List" (nejaky je snad v kazdej kniznici) a aby vedeli ako to pouzit efektivne (resp. ako efektivne ukladat data v praxi). Spojkovy zoznam ma svoje vyhody a v urcitych pripadoch (ak chces implementovat odstranenie prvku zo zoznamu) je jeho pouzitie "nutne" (ostatne sposoby by boli extremne neefektivne, rozumej milionkrat pomalsie :).
Kedze to ludia nechapu, tak potom musim s hrozou zazivat "programy" ktore napr. ked chcu pracovat so zoznamom 100 000 suborov (zoznam suborov na vsetkych CDckach) tak kliknem na nejaky button ze odstranit nieco z toho a ten program pracuje pol minuty (zazil som uz taky "skvely program"! :-D). Ta ista operacia je ale urobitelna v zlomku sekundy, ak by "programator" vedel aspon co to je spojkovy zoznam.

Databaza je nieco ine, omnoho komplikovanejsie, nie vzdy je nutna databaza. (podobne ako si nejdem kupit kamion ked chcem previezt zapalkovu krabicku).

Lenže na čo to robiť takto, keď v jazyku Object Pascal sa to dá urobiť rýchlejšie? Tkéto programy sú náchylné na drobnú chybičku s rizikom zrútenia systému. Alebo aj ty by si v objektovo orientovanom jazyku použil takúto možnosť, keď mám možnosť použiť objekty stvorené práve na takú činnosť?

V skole nejde o to urobit nieco rychlejsie, ale o to aby studenti pochopili ake a naco su jednotlive datove struktury, ako prakticke zadanie pre studenta sa k tejto teme nuka prave naprogramovat spojkovy zoznam (t.j. taky objekt aky by si ty v objektpascale pouzil, tiez ho niekto musel naprogramovat).
Skola ktora by studentovi povedala: "ak chces vytvorit zoznam tak pouzi CList.Create()" by bola zla skola, ptz akonahle by student sadol k napr. devcpp tak by bol v prd***. Ak vie co to je list a na co to je tak si to vie najst za 10sekund v helpe daneho prostredia/kniznice ktoru pouziva a nema potom problem programovat v akomkolvek prostredi (od pascalu az po Javu alebo C#).

Dobre, tak to jsem te asi jen spatne pochopil.
Tezko navrhovat konkretni datovou strukturu, kdyz nevim, jake jsou na ni kladene pozadavky. Ale napriklad bych pouvazoval, jestli neni vhodne pouzit nektery z mnoha typu stromu, nebo treba hash tabulku. Dlouhe spojove seznamy jsou neefektivni i kvuli tomu, jak jsou nepratelske vuci cache.

uz to mam takmer hotove:

http://stredoslovak.szm.sk/ZOZNAM.PAS

este by ma zaujimalo-automaticky tam generujem(najprv do suboru a potom to nacitam), a ked si tam niekto da velky pocet, ako to mam skontrolovat, ci sa to vojde do pamate?
myslim...-neviem ci mam pouzit funkciu maxavail(vrati velkost najvacsieho volneho bloku) alebo memavail(vrati velkost vsetkych volnych blokov), respektive, mam tam vobec pouzit zistovanie, ci je dost volneho miesta v pamati?

Hezký. Čtení náhodně generovaných jmen mě pobavilo :-D
Na první pohled se to zdá v pořádku (ale komu by se chtělo přemýšlet v neděli odpoledne, že). Nějaké kosmetické změny bych ti ale doporučil (i když na výslednou funkci nebudou mít vliv)

- proměnná kon je IMHO zbytečná. Alespoň jsem si nevšiml, že bys ji někde potřeboval. Jen ti komplikuje život, protože ji při editaci seznamu musíš aktualizovat.
- v hlavním programu je příliš mnoho kódu. Je zvykem rozsáhlejší části kódu dávat do samostatných procedur (podle významu). Např. pouze část pro výpis seznamu má 5 stran (obrazovek). Ta by se určitě lépe vyjímala v samostatné proceduře.

... to be continue ...

- když už jsme u toho rozsahu, tak se mi vůbec zdá, že kódem nešetříš. Proč např. u zmiňovaného výpisu vypisuješ zvlášť první stranu a ty další? Nestačilo by udělat takhle?

pom:=zac; {v I je pocet polozek seznamu}
for I := 1 to I do
begin
  writeln(I:5,':', pom^.meno:11,' ',pom^.priez:13,' ',pom^.rocnik,'. rocnik'); {vypis polozky}
  if I mod 24 = 0 then {24-pocet polozek na stranku, lze menit}
  begin
    write('Enter=dalsia strana/Esc=navrat do menu');
    repeat key:=readkey; until (key=#27) or (key=#13);
    if key = #27 then
    begin
      key := #0; break;  {prerus smycku}
    end;
    clrscr;
  end;
  pom:=pom^.dalsi;
end;
writeln('Koniec prezerania, pokracuj stlacenim klavesy');
readln;

A ještě k té paměti. Msx. se bude zlobit, ale já mám jiný názor. Jedna položka v seznamu (v tomto případě) má 516 Byte (2×string + pointer). Pokud bude veškerá zbývající paměť (řekněme 50kB) roztroušena v blocích < 516 Bytes, tak alokace další položky selže, přestože celková dostupná paměť (součet všech bloků) bude víc než dostatečná. Proto bych se přikláněl k MaxAvail.

...premennu kon pouzivam pri pridavani polozky na koniec.
Prirobim tam teda este procedury.
I:5,':', pom^.meno:11,-toto nepouzivam, lebo sa mi to zarovna do prava a to nevyzera tak dobre ako ked je to zarovnane do lava(=preto gotoxy).
A k tomu co tu pises, nam vraveli, ze v skolskych programoch nemame pouzivat "nasilne prerusenia"-ci uz break, halt alebo goto.
A pridal som tam aj memavail(skusal som aj maxavail)-v oboch boli velkosti pridanych poloziek rovnake-dovolilo pridat max 3971 prvkov-je to OK?

jj. S tím kon máš pravdu.

Pokud chceš zarovnávat doleva, jde to udělat pomocí Lenght(vrací počet znaků řetězce) např. takto:

writeln(I: 3, ':'+ pom^.meno,' ':11 - Length(pom^.meno), pom^.priez, pom^.rocnik:13 - Length(pom^.priez),'. rocnik'); 

Break není násilné přerušení. Pouze předčasně ukončí cyklus (For/repeat/while) a program pokračuje následujícím příkazem za cyklem. Nepatří do stejné skupiny jako příkazy Goto či Halt.

MemAvail a MaxAvail vracejí shodné hodnoty, pokud nedojde k fragmentaci paměti (t.j. dokud je veškerá dostupná pamět v souvislém bloku). To je sice pravidlem po spuštění programu, ale po delší práci (alokování/uvolňování různě velkých položek) se paměť může fragmentovat. Potom obě funkce vracejí různé hodnoty. (MaxAvail <= MemAvail)
3971 položek - to závisí na dostupné konvenční paměti. Bude se tedy lišit při spuštění na různých počítačích, a bude se zmenšovat, jak tvůj program poroste. Pokud je to málo, budeš muset požít nějaký úspornější formát (String zabere v paměti 256 Bytes nezávisle na tom, kolik "užitečných" znaků obsahuje)

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