» »

Pomoč pri c++ razlaga

Pomoč pri c++ razlaga

Area_51 ::

Hi! Bi mi znal kdo razložit kazalce (pointers) in reference, ker sem bral iz knjige pa nič ne štekam, drugo mi gre, samo to nikakor ne razumem kaj naj delam s tem????8-O

LP

HVALA
Area 51

Seadoo ::

Uff... si si pa res izbral najtežjo stvar za učenje nekoga pri programiranju.

V spremenljivke spravljaš podatke, v kazalce pa le kažeš na spremenljivke. In pol lahko funkcije kličeš s kazalcem, da ne prenašaš celotne spremenljivke v funkcijo. Uporabni pa se tudi pri dinamičnem alociranju pomnilnika, itd.

Ko boš prišu do nekega problema, pri katerem boš rabu kazalce, se jih boš pač moral naučit. Do takrat pa se raje nauči vse drugo :)

Vesoljc ::

vsa fora je v tem, da namesto podajanja konkretnih objektov (recimo void Izpisi(int vrednost); ) podajamo le njihov naslov.

primer:
int a;
Izpisi(a);
v tem primeru bo funkcija Izpisi najprej alocirala nov pomnilnik (začasni) za podani parameter (tokrat int), ko funkcija konča se pomnilnik sprosti. za manjše (x < 4byte ?? ) objekte to ni niti tako hudo.

kaj se pa dogaja zdaj?
struct big
{
int data[100000];
};
void Izpisi(big my_big);

izpisi bo zopet alociral ogromno začasnega pomnilnika! (podajanje po vrednosti)

void Izpisi(big my_big)
{
for(int i=0;i < 100000;i++)
cout < < my_big.data[i];
}

še to:
void spremeni(int a)
{
a = 100;
}

int main()
{
int b = 0;
spremeni(b);
}
zgornja koda ne bo delovala točno zaradi tega, ker funkcija spremeni alocira novo, začasno spremenljivko tipa int in operira nad njo, ne pa nad podano spremenljivko.

tukaj vstopijo pointerji (ptr's) in reference(ref's). ptr in ref je biti zelo isto. razlika je le v tem, da z ptr obdelujemo z adreso objekta, z ref pa z objektom samim.

zato lahko rečemo:
void Izpisi(big* p_big);
tokrat bo Izpisi alociral le pomnilnik za en pointer (4 byte ponavadi). (podajanje po referenci)

void Izpisi(big* p_big)
{
for(int i=0;i < 100000;i++)
cout < < p_big->data[i];
}

int main()
{
big a;
izpisi(&a); // podamo naslov od a-ja, (njegov ptr)
}

ker je pointer le "pointer" in ne objekt, moramo najprej naresti dereferenco (operator ->), ki nam omogoči dostop do objekta.

z referencami se pa tudi temu izognemo (vsaj na videz ;) )

void izpisi(const big& r_big) // be const correct ;)
{
for(int i=0;i < 100000;i++)
cout < < r_big.data[i];
}

int main()
{
big a;
izpisi(a); // podamo kot referenco
}

tudi tukaj se alocira le referenca in ne celoten objekt in tako kot pri ptr-jih se tudi tukaj vse narejene spremembe nad podanim objektom "shranijo" (zato ker delamo z podanim objemtom in ne novim,začasnim).

še enkrat:

void spremeni1(int a)
{
a = 100;
}

void spremeni2(int* p_a)
{
(*p_a) = 200;
}

void spremeni3(const int& a)
{
a = 300;
}

int main()
{
int b = 0;
spremeni1(b); // b je še vedno nič
spremeni2(&b); // b = 200
spremeni3(b); // b = 300
}

kej pozabu? :)

dinamične spremenljivke? ker podajaš samo pointerje lahko dejanske spremenljivke alociraš kasneje med samim delovanjem (run-time), a to je druga zgodba...
Abnormal behavior of abnormal brain makes me normal...

Seadoo ::

U, nekomu se da razlagat... dej prosim še dinamično alociranje razloži, no >:D >:D

Vesoljc ::

jutr dopoldne, ko ne bom plačeval za net ;)
Abnormal behavior of abnormal brain makes me normal...

Person ::

 #include "stdio.h" #include "conio.h" int stevilo_znakov; void main() { //Dobiš število znakov printf("Vpisi, koliko znakov naj vsebuje niz:\n"); scanf("%d",&stevilo_znakov); //Pointer na spremenljivko char* podatki = NULL; podatki = new char[stevilo_znakov+1]; //+1 => zadnji znak mora biti '\0' - null terminated string" // Alocira toliko BYTES, kot jih potrebuješ. if(podatki == NULL) // Če zmanjka pomnilnika, je pointer null { printf("\aNi dovolj pomnilnika (potrebnih bi bilo %dKB)!\n\nPritisni enter za izhod.",stevilo_znakov/1024); getche(); return; } //Pač, spremeni vse znake v A for(int i = 0; i < stevilo_znakov; i++) { podatki[i] = 'A'; } podatki[i] = '<66d87f67c52f203ff5c5222c280db3c9>'; //Izpiše niz. Če boš testiral velike velikosti znakov, pol jih ne izpiše, ker bo predolgo trajalo :) printf("Testni niz:\n%s",podatki); printf("\nIzpis je koncan. [%dKB] podatkov v nizu.\n\nPritisni tipko za sprostitev pomnilnika.\n",stevilo_znakov/1024); getche(); //Sprostitev pomnilnika (če imaš array, potem je delete[]) delete podatki; printf("Pomnilnik je bil sproscen. [%dKB]\n\nPritisni tipko enter za izhod.",stevilo_znakov/1024); getche(); } 
A je OK razloženo?
Let's make something useful!

Zgodovina sprememb…

  • spremenil: Person ()

Area_51 ::

Hvala za vso razlago in primere, primere, ki ste jih navedli jih razumem, kar piše, in kako je kej uporaljeno, ampak še vedno mam eno vprašanje:

Zakaj sploh uporabljamo kazalce in reference, kaj z jnimi pridobimo, ko jih uporabimo???

LP

HVALA:))
Area 51

napsy ::

Na Jokerjevem mnenjalniku v izbi mojstri kode obstaja podobna tema, ki govori o kazalcih. Tam najdeš vse razloženo. Tema je nekoliko starejša.
"If you die, you die. But when you live you live. There is no time to waste."

BigWhale ::

> Zakaj sploh uporabljamo kazalce in reference

Preprosto zato, ker jih lahko! Kaj z njimi pridobis? Marsikaj. Lahko si jih podajas sem ter tja med funkcijami, s pomocjo referenc, ti funkcija lahko vrne vec kot le en sam parameter, pointers are cool... that's why Java sucks :P

Seadoo:

Dinamicno alociranje? Najlazje si ga razlozis tako nekako: man malloc; man calloc; man free

;)

PS: Bistvenega, realloc sem pa izpustil :P

Zgodovina sprememb…

  • spremenil: BigWhale ()

kopernik ::


that's why Java sucks :P


Če bi uporabljlal Javo, bi vedel, da je vsaka spremenljivka(razen primitivnih) referenca na objekt, zato si med funkcijami podajaš reference in ne objektov. Smart ass :)

DMouse ::

Pri primitivnih pa lahko uporabiš tudi besedi ref ali out, odvisno kako želiš zadevo uporabiti.

Popravek: zamešal z nekim drugim jezikom, java ne omogoča tega :\

Zgodovina sprememb…

  • spremenil: DMouse ()

kopernik ::

Java ne pozna keywordov ref oziroma out (SUNova Java, za Microsoftovo ne vem...)

Zgodovina sprememb…

  • spremenil: kopernik ()

BigWhale ::

> Smart ass :)

Gre se zato, da v Javi ne mores narest pointerja, ne kaj se fura med funkcijami... :)

kopernik ::

In zakaj bi hotel narediti pointer, če je vsaka spremenljivka itak referenca(torej pointer) na objekt ?
(če odmislim razne direktne manipulacije s spominom, ki v javi "niso potrebne" zaradi Garbage collectorja)

Zgodovina sprememb…

  • spremenil: kopernik ()

BigWhale ::

Brez veze, debatirava, ker vsak trdi svoje. :) Raje narediva kaj pametnejsega... :)

Person ::

@kopernik & BigWhale: Rahlo sta zašla s teme:\

Pač, pointerji in reference se uporabljajo:
* večja hitrost pri prenosu parametrov v funkcijo (ker pač ni potrebnega kopiranja)
* večja učinkovitost porabe pomnilnika (Zakaj bi vedno znakovni niz zasedel enako količino spomina, če pa jo v bistvu potrebuje 1%?)
* seznami objektov (Zelo uporabno za igre, pa tudi programe.)
* hitro brisanje, spreminjanje vrstnega reda v seznamih (Izbrišeš samo en objekt.)

Dodajte, če sem kaj pozabil.;)
Let's make something useful!

Zgodovina sprememb…

  • spremenil: Person ()

Person ::

En preprost dinamični seznam: (prikaz uporabnosti)

Izvorna koda:
Seznam.cpp
Seznam.h

Izvorna koda + exe:
PreprostiDinamicniSeznam.zip

Ne, trdim da je najboljši dinamični seznam na svetu, je pa narejen prez pomoči, domača pamet:)

Opomba:
Ker je razred majhen, ob novem vnosu ni zelo velike razlike v porabi pomnilnika.
Da pa lahko opazite razliko, pa odkomentirajte tole vrstico:
//char test[1000000];
Številko lahko spremijate, ob pritiravanju boste lepo uporabili večino sistemskega pomnilnika :D
Let's make something useful!

Zgodovina sprememb…

  • spremenil: Person ()

kopernik ::

Dj:
Tolk grozno pa tudi nisva zašla. Če te moti, ignoriraj. Jeeeeez ...

Person ::

OK.
Let's make something useful!

Person ::

Malo sem še dodelal... če komu mogoče koristi, drgač je itak za lastne potrebe delan.8-)

Izvorna koda + EXE (v1.1)
PreprostiDinamicniSeznam v1.1

Izvorna koda + EXE (v1.0)
PreprostiDinamicniSeznam v1.0

BTW:
Bi prejšnji post popravil, pa nekot ne gre.;(
Let's make something useful!


Vredno ogleda ...

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

[Java] array v voidu

Oddelek: Programiranje
102279 (1978) Spura
»

[C] struct in int[] (strani: 1 2 )

Oddelek: Programiranje
657324 (6397) MrBrdo
»

[C++] dinamično 2d polje

Oddelek: Programiranje
143257 (3094) bozjak
»

[C] Narascajoce sortiranje linearnega seznama

Oddelek: Programiranje
71856 (1745) Jebiveter
»

[c++] Nezaželjeno spreminjanje vrednosti

Oddelek: Programiranje
211739 (1547) ]Fusion[

Več podobnih tem