» »

Pomoč pri Turbo Pascalu. Nujno!

Pomoč pri Turbo Pascalu. Nujno!

Dr X ::

Pozdravljeni!

A bi mi znal mogoče kdo pomagat. Kaj je kle narobe.

var p:pointer;
s:integer;

begin
s:=0;
getmem(p,2);
p^:=723; ------ KAKO SE TO SPLOH PRAV NAPIŠE

writeln('vrednost statiźne je',s,' = 732');

end.

Že v naprej se vam zahvaljujem za odgovor.
Nič ni nemogoče.

Gundolf ::

a ne bi moral za p napisat nekaj podobnega var p:pointer to integer; Drugo se mi pa zdi v redu. Je pa res da ze dolgo nisem niti pogledal pascala.

Gundolf ::

Se popravljam, menda bo var p:^integer; bolje. In pa mislim da obstaja tudi funkcija new, ki jo potem lahko klices: new(p);

Senitel ::

Kaj v bistvu hočeš naredit? Sedaj imaš načeloma spremenljivko tipa integer in netipiziran kazalec. Nastaviš s na nič, si rezerviraš 2 bajta pomnilnika (ki ju nikoli ne sprostiš) in zapišeš na to novo lokacijo 723 in pričakuješ, da se bo vrednost s spremenila? No go...

Dr X ::

Razlaga:


Poznamo dva tipa kazalcev tipizirane in netipiziranje. Moj programček tako in tako nič ne dela, gre namreč samo za učenje, tako, da se po nepotrebnem sprašujete o njegovi uporabnosti.

Moj problem je pa ta: kako na lokacijo na katero kaže natipizirani kazalec shraniti neko vrednost, ta ukaz namreč ne dela: p^:=723 (deluje samo pri tipiziranem kazalcu);

Zanima pa me še kaj moraš napisati (p^:=????), da kazalcu določiš nek tpčno določen naslov.


Že v naprej se vam zahvaljujem za težko pričakova odgovor.
Nič ni nemogoče.

Gundolf ::

Aja to bi ti rad :) Poskusi p:=@s;

Deno ::

Pri kazalcih se uporabljata večinoma dva znaka, ^ in @.
Znak ^ si lahko predstavljaš kot "kaže na", @ pa kot "naslov od".

Kazalec p, ki kaže na vrednost tipa integer bi naredili takole:
p:^integer;
Namesto ^ si zamisli stavek "kaže na"; p:"kaže na" integer.

Kreirajmo še enko navadno spremenljivko tipa integer:
a:integer;
a:=10;

Writeln(a) bi nam izpisal 10.

Če hočemo, da kazalec p kaže na naslov od spremenljivke a, bi napisali:
p:=@a;
Beri: p dobi vrednost "naslov od" a. S tem smo kazalcu p dodelili naslov od a (kazalci delajo samo z naslovi in kot takim ne moremo prirediti nekih drugih vrednosti). Zdaj lahko kazalec p uporabimo za dostop do a:
p^:=30;
Beri: "Kamor kaže p, naj se zapiše vrednost 30". p v našem primeru kaže na naslov od a.
Tokrat bi nam writeln(a) izpisal 30, saj smo a preko kazalca priredili novo vrednost.

Celotna koda za ta program je taka:

var p:^integer;
a:integer;

Begin
a:=10;
writeln(a); {Izpise se nam 10}

p:=@a;
p^:=33;
writeln(a); {Izpise nam 33, saj je kazalec spremenil vrednost a}
End.


Upam, da ti je malo bolj razumljivo. Če ti še karkoli ni jasno, pa še enkrat vprašaj.

EDIT:
Še odgovor na tvoje vprašanje o prirejanju določenih naslovov. Ker kazalec lahko drži samo naslov, je prireditev preprosta. p:=naslov, ie. p:=50. Kazalec p bi kazal na naslov 50. Vendar ti uporabo tega zelo odsvetujem, saj boš najverjetneje pisal čez neke druge podatke na tem naslovu, kar ni najbolj priporočljivo. Naslovi se ves čas spreminjajo (ob prvem izvajanju programa ima lahko spremenljivka a naslov 50, ob drugem izvajanju bo pa čisto drugačen). Program se ti bo vsakič obnašal drugače. Zato namesto naslova uporabljaj spremenljivko (p:=@a).

Zgodovina sprememb…

  • spremenil: Deno ()

Dr X ::

Tnx, Deno. Zdej stvar malo bolj razumem. Samo še vedno pa me muči sledeče.

var p:pointer;
begin
getmem(p,2);
p^:=????;
end.

S tem programom sem rezerviral 2 byta v pomnilniku in p kaže na naslov tega rezerviranega prostora. Samo zanima pa me kako bi en integer shranil na naslov na katerega zdaj kaže pointer. S tem ukazmom namreč ne gre:

p^:=732;

Oprostite če preveč "morim". :D
Nič ni nemogoče.

Gundolf ::

Ja ce hoces nujno uporabljati pointer in ne ^integer potem je to seveda malo tezje. integer(p^):=666; ce se ne motim. No ce prav pomislim to ne bi smelo delati. Vsaj C ne bi dovolil ekvivalentnega stavka. No poanta je, da lahko assignas integer samo izrazom tipa integer. Ce imas kaj drugega moras to pac nekako pretvoriti v integer. Ce zgornje slucajno ne deluje poskusi ^integer(p)^. Ce ti tega ne bo sprejel definiraj type pinteger : ^integer; in nato pinteger(p)^. Pac, znajdi se malo.

Zanima pa me še kaj moraš napisati (p^:=????), da kazalcu določiš nek tpčno določen naslov.

A po zadnjem postu sodec ti ne zelis dolociti naslova kazalcu (to si storil ze z getmem(p,2) ampak dolociti vrednost 'spremenljivki' na katero ti kaze ta tvoj pointer. Ne tega dvojega mesati.

Dr X ::

Hvala. To sm želel zvedet. :D
Nič ni nemogoče.

Dr X ::

Še neki :D . Zakaj ta ukaz ki ste mi ga povedal ne dela p:=50, če bi tako rad postavil kazalec na naslov 50 mi napiše TYPE MISMATCH.
Nič ni nemogoče.

Gundolf ::

Zto ker je 50 integer in ne naslov. V turbo pascalu se da naslov tvoriti z operatorjem @ ali pa s funkcijo addr(seg, ofs). seg je segmentni del naslova, ofs pa offset na podanem segmentu. Naslov je namrec 32biten, seg in ofs pa sta 16bitna integerja. To spet govorim na pamet a mislim da bi moralo biti nekako takole: p:=addr(0, 50) pri cemer pa tega NIKAKOR noces delati.

No ce se enkrat pomislm morda se funkcija imenuje tudi ptr. Eno od tega dvojega. Poglej v help. Pascal ima kakor se spomnim cisto soliden help o svojih funkcijah.

Dr X ::

Hvala folk k mi dajete brezplačne inštrukcije, bom mel RSO (Računalniški sistemi in omrežja - 4.letnik, Vegova) še pet. :D

Če vs ne mot pa mam spet eno vprašanje. Kako bi v teoriji, ker program bom že sam napisal, preveril s paskalom (brez funkcij kot npr. memavail) koliko dinamičnega pomnilnika (heap) mam še na voljo in to tako da se mi program normalno konča. Razmišljal sem da bi rezerviral pomnilnik v zanki z getmem (p,1) ter to štel, sam tako se mi program ne konča normalno.
Nič ni nemogoče.

Zheegec ::

Dr X -> Kastelic, kaj?
"božja zapoved pravi; <Spoštuj očeta in mater>,
ne govori pa o spoštovanju sodstva."
Janez Janša, 29.04.2014

Dr X ::

Ja, :D A znaš rešt vajo.
Nič ni nemogoče.

Senitel ::

Kolikor se jaz spomnim pascala in pascal sem zadnjič delal pri Kastelicu >:D imaš eno funkcijo, ki vrne koliko je še prostora na heapu. Samo se je moj "Žepni priročnik Turbo Pascala" nekam izgubil.

Dr X ::

Spet rabm slo-tech inštrukcije.

Še zmer sm pri zadnji nalogi. Več vem samo to da lahko kolk dinamičnega pomnilnika maš še na voljo ugotoviš tako da odšteješ Stack pointer in Heap pointer, sam mi ne rata. Zanima me če sta heap in stack v istem segmentu pomnilnika, program mi namreč napiše da nista. Pa še tole mi neki smrdi:

a:=seg(heapptr);
b:=ofs(heapptr);

getmem(p,4);

a:=seg(heapptr); ---- TUKI in
b:=ofs(heapptr); ---- TUKI sta vrednosti enaki kot zgori pred getmem(p,4), sam a se nebi mogu heap pointer premaknt za kkšen offseta al pa segment.
Nič ni nemogoče.

Gundolf ::

Ne vem kaj je heapptr ampak poskusi pogledati se seg(p) in ofs(p). Mogoce ti bosta kaj pametnega povedala ;)

Kot sem ze rekel, znajdi se.

Drugace pa heap in stack nista v istem segmentu. Vsak segment je 16 biten, se pravi da vesbuje 64 kB. Ce bi bilo oboje v istem segmentu bi lahko uporabil le teh 64 kB, tako pa imas v turbo pascalu na voljo skoraj cel MB! Ok salo na stran, ce se to res da storiti, potem moras imeti na voljo kako spremenljivko ala maxSeg ali kaj podobnega. Kot sem ze rekel, se za heapptr ne vem kaj tocno je tako da ... Morda pa je maxSeg kar 65535 oziroma nekaj manjsi. Poskusi v tvojem programu spremeniti getmem(1) na getmem(32768) in vsakic izpisi seg in ofs. Mogoce ti bo tudi to dalo kaksno idejo.


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

[Java] array v voidu

Oddelek: Programiranje
101629 (1328) Spura
»

C# je mozna referenca do int izven funkcije (direkt v classu torej)

Oddelek: Programiranje
81295 (1109) TopCat
»

Odkrita ranljivost v Flashu omogoča pridobitev sistemskih privilegijev

Oddelek: Novice / Varnost
355114 (3014) fiction
»

[Turbo pascal] Max Min tezave

Oddelek: Programiranje
8943 (816) luli
»

[Turbo Pascal] Pomoč...

Oddelek: Programiranje
131097 (999) Grey

Več podobnih tem