Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: Kedy sa tie pointre pouzivaju?

Aktivity
Avatar
expoox
Tvůrce
Avatar
expoox:15.1.2013 22:48

Ahoj, mohol by si prosim ta este vysvetlit kedy sa tie pointre pouzivaju ? teda v akych situaciach ? uz asi z 3 zdrojoch studujem pointre a nikde to nieje povedane kedy sa pouzivaju
dakujem

 
Odpovědět
15.1.2013 22:48
Avatar
Odpovídá na expoox
Drahomír Hanák:15.1.2013 23:00

Abys pochopil, kde se používají, musíš nejdřív vědět, co to pointer je. Když to víš, nemělo by být těžký představit si, kde a na co se používají.

Pointer je ukazatel někam do paměti. Např. na zásobníku se alokuje paměť pro hlavní funkci (main). Zde se vytvoří proměnné a volají se další funkce. Ty další funkce mají taky nějakou svou paměť. Potřeboval bys třeba seřadit pole, které si vytvořil ve funkci main. Pole se uložilo v zásobníku, ale kdybys ho měl předávat nějaké jiné funkci (např. serad_pole), bylo by nejspíš dost neefektivní, kopírovat celé pole do paměti funkce a pak zase zpět do main. Udělá se to jinak. V main funkci serad_pole předáš pouze odkaz na to, kde je pole umístěno v paměti. Daná funkce pak může pracovat přímo s originálním polem v main.

Dalším příkladem je třeba samotné pole. I to je pointer. pole[1] je v podstatě ekvivalent *(pole+1), jelikož položky pole jsou v paměti uloženy za sebou, takže tímto zápisem se posuneš v paměti o daný datový typ na další index pole. Pak se taky používají pro práci s dynamickou pamětí, kde se v podstatě jen odkazuješ na haldu a ke všem proměnným tam přistupuješ pomocí pointeru.

Editováno 15.1.2013 23:04
 
Nahoru Odpovědět
15.1.2013 23:00
Avatar
Зайчик
Člen
Avatar
Odpovídá na expoox
Зайчик:16.1.2013 9:42

Úplně nejjednodušší použití je třeba když si vytvoříš ve funkci main proměnnou a chceš jí používat i v další funkci aniž by proměnná byla globálního typu. Vytvoříš si na proměnnou pointer, který budes používat v další funkci například... ale myslím že Drahoš to řekl dost pochopitelně. :)

Nahoru Odpovědět
16.1.2013 9:42
Коммунизм для нашего будущего!
Avatar
Kit
Tvůrce
Avatar
Odpovídá na Зайчик
Kit:16.1.2013 9:57

Ještě zajímavější je, když z main zavoláš nějakou funkci, která alokuje v paměti pole a naplní hodnotami. Pointer pak vrátí jako výsledek funkce. Tento pointer pak předáš jako parametr další funkci, která s tím polem má dál pracovat.

Nahoru Odpovědět
16.1.2013 9:57
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Luboš Běhounek Satik:16.1.2013 11:22

Každým program používá takzvaný zásobník, což je část paměti, která je neustále hezky srovnaná, takže je to rychlejší, než zbytek paměti, ale je malá a hlavně co na zásobníku v nějaký funkci vytvoříš, to se zase musí ze zásobníku odstranit, když tu funkci opouštíš.

Když alokuješ nějakou paměť dynamicky, tak ji můžeš mít alokovanou dokud ji neuvolníš, ale nikdy předem nevíš adresu, která zrovna bude volná, proto vždy jen při alokaci dostaneš ukazatel na místo, které alokátor našel a bylo volné.

Typicky se na zásobník ukládají parametry funkcí, takže když třeba zavoláš funkci SeradPole

int length = 100;
int * poleCisel;
poleCisel=(int *) malloc(length*sizeof(int)); // alokováno dynamicky - na haldě (heap)
SeradPole(poleCisel, length);

(která je definovaná takhle)

int SeradPole(int * poleCisel, int length)
{
...
}

tak se na zásobník uloží kopie adresy poleCisel a kopie obsahu proměnné length a provede se zavolání funkce SeradPole, která s nima něco provede a nakonec si je pak zase ze zásobníku odebere (resp. jen posune ukazatel na vrchol zásobníku).

Proto když v běžný funkci změníš nějakou běžnou proměnnou, co ti přišla jako parametr, tak se to změní jen uvnitř té funkce - na zásobníku.
Jen pokud ti přišel ukazatel, tak můžeš měnit data na místě, kam ukazatel ukazuje (jako tady ve funkci SeradPole - muzes menit data na msite, kam poleCisel ukazuje a srovnat pole), ta změna je pak trvalá, protože nešaháš na lokální kopii na zásobníku, ale přímo na data na haldě.

Nahoru Odpovědět
16.1.2013 11:22
https://www.facebook.com/peasantsandcastles/
Avatar
Lukáš Hruda
Tvůrce
Avatar
Odpovídá na Kit
Lukáš Hruda:16.1.2013 15:51

V C se návratová hodnota takových funkcí často používá ke zjištění a případný indentifikaci chyby, takže to nemusí vždycky jít. V C se všeobecně výstupy funkce řeší pointerama v parametrech, návratová hodnota se pro výstup používá když je to jenom jedna hodnota a zároveň není potřeba aby funkce dávala informaci o chybě. Alespoň většina Céčkových knihoven co sem kdy používal se tohohle drží. Já v C moc nedělam, ale když jo, tak většinou zvolim to co mi zrovna připadá nejpraktičtejší.

 
Nahoru Odpovědět
16.1.2013 15:51
Avatar
Kit
Tvůrce
Avatar
Odpovídá na Lukáš Hruda
Kit:16.1.2013 16:15

V C nejsou výjimky, tak to ani jinak nejde. Předávání výsledků funkce v parametrech odkazem mi vždycky bylo proti srsti. Moderní jazyky už těmito neduhy netrpí.

Nahoru Odpovědět
16.1.2013 16:15
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Lukáš Hruda
Tvůrce
Avatar
Odpovídá na Kit
Lukáš Hruda:16.1.2013 16:27

Tohle záleží hodně na jazyku. Já třeba v C++ to řešim tak že pokud výstupní data ve funkci vznikají, pak je funkce vrací, pokud ale funkce mění data který už existujou, předávam data referencí (popř. pointerem) a měnim je přímo, funkce pak třeba ani nic nevrací. Informaci o chybě se snažim vždycky předávat návratovou hodnotou, nebo vyřešit chybu uvnitř funkce, většinou jde oboje, pokud ne, tak výjimkou ale všeobecně se výjimkám snažim vyhejbat.

Editováno 16.1.2013 16:29
 
Nahoru Odpovědět
16.1.2013 16:27
Avatar
Kit
Tvůrce
Avatar
Odpovídá na Lukáš Hruda
Kit:16.1.2013 16:37

Výjimky považuji za sekundární (chybový) informační kanál a proto je používám vždy, když je to možné. Ze začátku jsem se jim také vyhýbal, ale pak jsem zjistil, že je to vynikající nástroj. Hlavně se ale přes výjimky nesmí řešit standardní situace, jako např. ukončení cyklu apod.

Měnit existující data je vždy nebezpečné. Pro tento účel byly vyvinuty objekty a rozhodně by se neměly obcházet.

Předávání chyby návratovou hodnotou blokuje důležitý informační kanál funkce a v podstatě znemožňuje správné použití dependency injection. A bez dependency injection se nedá správně dělat test-driven development.

Editováno 16.1.2013 16:38
Nahoru Odpovědět
16.1.2013 16:37
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Lukáš Hruda
Tvůrce
Avatar
Odpovídá na Kit
Lukáš Hruda:16.1.2013 16:43

Měnit existující data je ale znatelně efektivnější než je 2x kopírovat (jednou do parametru, jednou do návratový hodnoty). Objekty v C++ nejsou v základu referenční, takže stejně nakonec musíš použít referenci explicitně, nebo udělat pointer.

 
Nahoru Odpovědět
16.1.2013 16:43
Avatar
Kit
Tvůrce
Avatar
Odpovídá na Lukáš Hruda
Kit:16.1.2013 16:50

Však také C++ není plně objektový jazyk. V těch plně objektových se jako výsledek funkce předává právě jen pointer na výsledný objekt. To si vynutilo vytvoření výjimek jako sekundárního (chybového) kanálu funkce.

Každý normální program má jeden standardní vstup, jeden standardní výstup a jeden standardní chybový výstup. Výstupní kanály programů jsou tedy dva, tak proč by tuto možnost neměla mít každá funkce v tom programu?

Nahoru Odpovědět
16.1.2013 16:50
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
expoox
Tvůrce
Avatar
expoox:16.1.2013 18:04

Dakujem za odpovede, cize ak som to spravne pochopil tak je vyhodnejsie pouzivat pointeri pre to lebo pointeri su pamatovo vyhodnejsie kedze to nieje klasicka premenna (je to odkaz na premennu) a netreba pre nu alokovat pamat, chapam to spravne ? Ak som niekde napisal blbost tak ma kludne opravte.

 
Nahoru Odpovědět
16.1.2013 18:04
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na expoox
David Hartinger:16.1.2013 18:09

Pointer je dobrý jen k tomu, že ti umožňuje vytvářet datové struktury za běhu programu. Např. klasické pole si ve zdrojáku nastavíš na nějakou velikost a po spuštění ji už nezměníš. Když potřebuješ měnit velikost nějaké kolekce za běhu programu (což potřebuješ velmi často), musíš použít pointery. Jednoduše řečeno přes pointery si uděláš třeba natahovací pole.

Pointery určitě nejsou výhodnější a v mnoha případech se vyplatí kopírovat obsah klasických proměnných než udělat chybu v pointeru. Jinak celá myšlenka lidsky řízených pointerů (stejně jako jazyk C) je zastaralá a dávno ji převzaly stroje, takhle se už neprogramuje.

Nahoru Odpovědět
16.1.2013 18:09
You are the greatest project you will ever work on.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 13 zpráv z 13.