it-swarm-eu.dev

Co je pěkné vysvětlení ukazatelů?

Měl jste ve svých vlastních studiích (samostatně nebo ve třídě) okamžik „ah ha“, když jste konečně skutečně porozuměli ukazatelům? Máte vysvětlení, které používáte pro začátečníky, které se jeví jako zvláště efektivní?

Například, když začátečníci poprvé narazí na ukazatele v C, mohou jednoduše přidat &s a *s, dokud se nezkompiluje (jako já sám). Možná to byl obrázek, nebo opravdu dobře motivovaný příklad, který udělal ukazatele „kliknutím“ pro vás nebo vašeho studenta. Co to bylo, a co jsi zkusil, než se zdálo, že to nefunguje? Byly nějaké předpoklady pro témata (např. Struktury nebo pole)?

Jinými slovy, co bylo nezbytné k pochopení významu &s a *, kdy jste je mohli používat s důvěrou? Naučit se syntaxi a terminologii nebo případům použití nestačí, v určitém okamžiku musí být myšlenka internalizována.


Aktualizace: Dosud se mi líbí odpovědi; prosím, nechte je přicházet. Je zde spousta skvělých perspektiv, ale myslím, že mnoho z nich jsou dobrá vysvětlení/slogany pro sebe poté, co jsme tento koncept internalizovali. Hledám podrobný kontext a okolnosti, když na tebe svítilo.

Například:

Syntakticky jsem porozuměl pouze ukazatelům v C. Slyšel jsem, jak dva moji přátelé vysvětlují odkazy jinému příteli, který se ptal, proč byl ukazatel struct předán ukazatelem. První přítel hovořil o tom, jak je třeba na něj odkazovat a upravovat ho, ale šlo jen o krátkou poznámku od druhého přítele, kde mě to zasáhlo: „Je to také efektivnější.“ Posledním koncepčním posunem, který jsem potřeboval, bylo absolvování 4 bajtů místo 16 bajtů.

72
Macneil

Schéma paměti jako mřížky

Obvykle to, co dělám, je paměť jako „mřížka“, takže mohu vytvářet adresy, zvýrazňovat různé paměťové prostory a zapisovat do hodnot buněk (nebo ještě dále jejich binární reprezentace) a propojovat ukazatele v paměti s hodnotami, které Ukaž na. (A pak ještě zmíním, že se jedná o zjednodušení).

Obvykle je to pro většinu studentů „ohhhh“.

Symbol žonglování

Když pak přijde na to, aby přestali zapomenout na to, jak používat & a *, je to velmi jednoduché: prezentujte to stejným způsobem jako matematické nebo fyzikální výpočty. Pokud dělíte vzdálenost v km časem v hodině, dostanete rychlost v km/h. Co musí být venku. Jednoduchý.

printf na Záchranu

Uděláme jen několik základních příkladů, které vizuálně představují to, co jste jim vysvětlili, jim ulehčí to, o čem si myslí, že rozumějí, nebo jim dá příležitost říci „ah, tohle nedostanu“.

Buďte rozsáhlí

Ukazatele u jednoduchých typů zakryjte a ujistěte se, že rozumí rozdílu mezi adresováním a velikostí datového typu, poté strukturami, potom poli a více úrovněmi.

Pak začněte aritmetiku ukazatele.


Dodatek: Rekurze

Rekurzi obvykle vysvětlím podobně pomocí vizuální reprezentace. Nechte je vytisknout abecedu pomocí předem připravené funkce, která píše jeden znak, a požádejte je, aby ji vytiskly v opačném pořadí pouhým změněním dvou řádků.

Obvykle existuje „co ...?“ moment, a když přidáte pouze další parametr do svého printf pro tisk číselných hodnot a odsazení kroků, stane se úlevou.


Alternativy: Play-Doh Model a Water Cups

Vlastně jsem měl na univerzitě několik spolupracovníků, kteří ukázali studentům video vysvětlující odkazy a přístupy do paměti pomocí pasty play-doh. Bylo to neuvěřitelně chytré a dobře odvedené, i když jsem tuto techniku ​​nikdy sám nepoužil, s výjimkou velmi mladých studentů, kteří se zajímali o pochopení programování (obvykle však ty, které bych příliš nevedl k jazyku pomocí ukazatelů příliš brzy). V zásadě používáme malé koule play-doh, které se můžete připojit k dalším větším míčkům play-doh reprezentujícím paměťové prostory, a které můžete kombinovat, abyste je buď propojili (jako v propojené datové struktuře), nebo sloučit dohromady (jako v sousedícím) paměťový prostor). Použití různých barev pro paměťové prostory, na které je poukázáno, a ukazatele také pomáhají. Stále si ale myslím, že věc Memory-as-a-Grid funguje lépe, protože můžete jasně ukázat, že směřování je skutečně věcí „adresování“, jako na „mapě/mřížce“. Zatímco režim Play-doh je stále zmatuje, když si myslí, že se věci v paměti „vzájemně dotýkají“.

Věc Water Cup byla použita přímo kolegou, ale nevím, jestli s tím přišla. Byl to zajímavý přístup, ale všiml jsem si, že mnoho studentů bylo vysvětlení vysvětleno. Něco podobného technika DevSolo's Coffee Cup . Ale myslím si, že je to vlastně zavádějící, protože si studenti nechávají zaměňovat kontejnery, datové struktury, ukazatele a pole. Mohl by to být zajímavý přístup vysvětlit pole na začátku, jak předpokládám, ale nechtěl bych se toho držet příliš dlouho.

25
haylem

Někdo mnohem moudřejší, než jsem kdy řekl:

Jeptiška Wu Jincang se zeptala Šestého Patriach Huinenga: „Studovala jsem Mahaparinirvanovu sutru po mnoho let, přesto existuje mnoho oblastí, kterým úplně nerozumím.

Patriach odpověděl: „Jsem negramotný. Přečtěte si mi prosím postavy a možná budu schopen vysvětlit význam.“

Řekla jeptiška: „Nemůžete ani poznat postavy. Jak jste tedy schopni porozumět významu?“

„Pravda nemá nic společného se slovy. Pravdu lze přirovnat k jasnému měsíci na obloze. Slova lze v tomto případě přirovnat k prstu. Prst může ukazovat na umístění měsíce. Prst však není Měsíc. K pohledu na Měsíc je nutné hledět za prst, že? “

80
Frank Shearar

Zjistil jsem, že diagramy jsou velmi užitečné. Příklad:

pointer diagram


Tento druh diagramu mi pomohl zjistit, že ukazatele byly jejich vlastní proměnné, ale obsahovaly hodnotu, která byla umístění jiného objektu, tj. Pole nebo řetězce. Když jsem to udělal tužkou, mohl jsem ho použít ke sledování programu na papíře nebo na tabuli/tabuli.

46
Michael K

Když jsem se poprvé „dozvěděl“ o ukazatelích, byl jsem do toho trochu vtlačen. Moje univerzita učinila rozhodnutí dlouho předtím, než jsem se zapsala do centra osnov kolem Java, takže když můj profesor datových struktur přednesl jednu přednášku na C a požádal nás, abychom implementovali XOR-List s ukazateli, cítil jsem se, jako bych se dostal k něčemu cesta nad mou hlavou.

Definici jsem pochopil:

Ukazatel je proměnná, která obsahuje adresu proměnné

Ale stále jsem nerozuměl velké části konceptu. Když se ohlédnu zpět, myslím, že se soustředil na tři věci:

  1. Co přesně je umístění v paměti? (V té době jsem nebral třídu Computer Organisation)

  2. Nepříjemná syntax (Takže ... proč je přesně definována jako "int * ip", ale následně odkazuji na proměnnou jako "ip"?)

  3. Jak přesně je výhodné ukládat adresu proměnné, než ji pouze používat?

Teprve když jsem si koupil knihu K&R a dokončil každý problém, který jsem opravdu pochopil pro ukazatele. Kromě toho, že jsem dlouho absolvoval třídu Computer Organisation (myslím, že by měl být vyžadován před učením C), část z toho měla co do činění s tím, že jsem si uvědomil, že ukazatele lze použít pro funkce, pole, struktury ... dělat užitečné věci a ne pouze jako úložiště pro adresy obyčejných proměnných.

Ale můj „aha“ okamžik byl způsob, jakým K&R vysvětlil nepříjemnou syntaxi definování jednoduchého ukazatele. Poznamenal jsem si poznámky v celé knize (ve které jsem přeformuloval body uvedené v knize do vlastních slov, abych dále porozuměl), a toto se týká té:

Ukazatel je proměnná, která obsahuje adresu proměnné. Ukazatel je definován a dereferencován (poskytuje hodnotu uloženou v paměťovém místě, na které ukazuje) u operátora '*'; výraz je mnemotechnický.

Ex.: 
   int a;      /* Variable 'a' is an integer */

   int *ip;   /* Variable ip is a pointer and dereferencing it gives an integer.
                 In other words, the expression *ip is an int, so ip is a pointer
                 to an int */

Vždycky jsem měl pocit, že nemohu plně pochopit pokročilejší koncepty ukazatelů, dokud nebudu mít v hlavě něco tak elementárního zakořeněného. Po tom úkolu mě to donekonečna trápilo (což jsem mimochodem příliš nevedl;)) proč "* ip" neexistoval hned poté, co jsem (myslel jsem) definoval "* ip". Zvládnutí je nezbytné pro pokročilejší koncepty zahrnující ukazatele, jako jsou ukazatele funkcí a složitější definice, jako je tato:

char (*(x())[])()

Celkově vzato si myslím, že koncept ukazatelů vyžaduje:

  1. Základní porozumění tomu, jak je v počítači rozložena paměť (a jaká je paměť).

  2. Znalost toho, jak mocné ukazatele mohou být (využití ve skutečném světě, nejen další abstraktní pojem, který se učí kvůli učení).

  3. Deciphering hieroglyphics hovorově známý jak “definice ukazatele”

Celkově vzato si myslím, že při učení o ukazatelích by měly existovat alespoň 3 "aha" okamžiky. Pořád jsem student, takže jsem si myslel, že oceníte pohled někoho, kdo je stále (relativně) čerstvý z toho, že se tento koncept učí.

32
Kevin

Ukazatel je trochu jako zástupce aplikací na ploše. Odstraňte zástupce a cíl stále existuje. Spusťte zástupce a cíl začíná.

Fungování tohoto problému vždy vysvětlím jednoduchým vytvořením souboru txt na ploše a dvěma zkratkami k souboru. Po zkopírování a odstranění zkratek můžete vidět, jak lidé chápou myšlenku „referencí“.

Jakmile skupina porozumí základním zkratkám, můžete začít vysvětlovat ukazatele, jak chcete. Pravděpodobně to pochopí docela snadno.

19
Barfieldmv

Před 8-10 lety jsem na komunitní škole vyučoval úvodní kurz „C“. To bylo vždy zábavné téma prozkoumat. Zdálo se, že to funguje nejlépe, a to bylo po několika diskusích s kolegou, že jste použili šálek kávy a ruku.

Analogii šálku kávy (nebo jejich řady pro pole) jsem použil jako proměnnou (může něco držet). Pak jsem použil ruku, která by také mohla něco držet, nebo natažením ukazováčku na „směřování“ na šálek kávy.

Blízká ruka byla nulová, prst ukazující na mou hlavu (jako výsměchová zbraň) byl visící ukazatel.

Poté s několika demonstracemi a výlety po debuggeru klikla s většinou.

14
DevSolo

Opravdu se docela obávám, když uslyším otázku „jak jste pochopili ukazatele“. Vždy jsem si myslel, že koncept je neuvěřitelně jednoduchý a logický vývoj jazyků, který programátorům poskytuje velkou sílu.

Věc, která mě trápí, je, že mi nikdy nebylo těžké porozumět pojmu ukazatele. Takže když jste tady "kdy jste to konečně dostali" znovu a znovu, začnete přemýšlet:

Opravdu to dostanu? Možná jsem to nikdy neudělal?

Možná důvod, proč se tento koncept jeví jako choulostivý, je ten, že stále říkáme každému, kdo se s nimi ještě musí setkat, že ukazatele jsou tak obtížné, a tady je stovka způsobů, jak se můžete učit?

Prostě tu myšlenku hodím, samozřejmě osobně mám rád dobrý diagram a Steve Gibson vždy dělá fantastickou práci, když něco vysvětluje !

10
Marcus Whybrow

Nikdy jsem neměl problém s ukazateli v C, ale to může být proto, že jsem se musel nejprve naučit assembleru. Ve skutečnosti to byla úleva, že už nemusím spravovat adresy. Takže možná odpověď (za předpokladu, že to je něco, co učíte), je dát studentům emulovaný jazyk shromáždění, se kterým mohou pracovat. bude to zjistí v procesu psaní něčeho sofistikovanějšího než "Ahoj, svět."

7
Larry Coleman

Ukazatel je proměnná, jejíž hodnota je adresou paměti jiné proměnné.

7
kirk.burleson

Jak jsem se opravdu dozvěděl o ukazatelích? Psaním jednoduchého kompilátoru prváci rok vysoké školy.

Jak vysvětlit ukazatele laikem? Líbí se mi (datovaná?) Analogie knihovního katalogu uloženého na indexových kartách. Každá karta ("ukazatel") obsahuje informace o tom, kde je umístěna nějaká kniha ("data"), ale ve skutečnosti neobsahuje samotnou knihu. Pokud kartu změníte („aritmetika ukazatele“), změní se pouze to, na kterou knihu odkazuje a která nemá žádný dopad na knihu samotnou - buďte opatrní, abyste adresu nezklepali nebo byste mohli ukázat na neexistující knihu nebo dokonce špatná knihovna. Pokud však sledujete „adresu“ na kartě a přejdete do správné části knihovny („dereference the pointer“), můžete zobrazit/upravit knihu samotnou.

6
Yevgeniy Brikman

Upraveno na podporu revidovaného požadavku na otázku

Moje cesta k pochopení „post-pointeru“ (pokud si správně vzpomínám) šel takto. Měl jsem několik jednoduchých zkušeností s programováním shromáždění od doby, kdy jsem byl ještě blázen kolem BBC Micro , takže jsem měl pojem paměti jako hromadu krabic (viz níže níže). To bylo posíleno použitím polí. Šel jsem však do světa C a musel jsem se vypořádat s řetězci, což znamenalo ukazatele. V BASICu to bylo triviální, v assembleru jsem s nimi nikdy nemusel pracovat, a teď v klasickém C jsou to všechno ukazatele a věci. Ah, ale můžu se vrátit k polím pomocí řetězců (ukončených nulovou hodnotou), jako je tento:

char s[] = "Hello, world!";
printf("%s",s);

Všechno v pořádku, to je jen řada znaků (8 bitů na postavu v mém malém světě) s nulovým znakem na konci, který ukazuje, kde končí. Printf prostě vezme toto pole a přejde přes něj jeho tisk. Ale co když chci předat tento řetězec do funkce?

void print_str(char* p) {
  printf("%s",p);
}

Co je v manuálu, ale o čem to všechno je? Hmm, znak * znamená „ukazatel na znak“. Dobře ... ztratil mě. Pak mě napadlo, že znak * je p ekvivalentní s s [0]. Dobře, můžu to použít, ale pořád jsem ještě neuzavřel, jaké jsou ukazatele. Jak mám nastavit některá data s jednou z těchto věcí? Znovu k manuálu ...

char* p = "Hello World!";

Když píšu výše, říkám si: „deklarovat ukazatel na znak a nastavit jej na stejnou úroveň znaků“. Nějak tento ukazatel odstraní potřebu pole. Myslím, že to je kompilátor, který pro mě dělá nějaké věci pro změnu. Jak tedy mohu změnit pole pomocí tohoto ukazatele? Vím, že bych mohl použít verzi pole

 s[2] = 'L'; 

ale co je ekvivalent v "ukazatel mluvit"? Znovu k této příručce ...

*(p+2) = 'L';

Předpokládám, že * jednoduše znamená "obsah adresy v paměti" a (p+2) je s[2]. Což znamenalo, že ukazatel p byl ... jen ... adresa ... bong!

Že je zvuk osvícení. Najednou jsem se ušklíbl ukazatele (bylo to dávno, my staré časovače jsme se „nevzdali“ až později). Byla to jen indukce.


Originál:

Dobře, moje hodnota 2c:

Představte si paměť je banda krabic. Každé pole má na boku číslo (adresa). Každé pole obsahuje číslo (obsah). S těmito boxy můžete pracovat dvěma způsoby: proměnnými (chci obsah rámečku N), ukazateli (chci obsah rámečku cokoli, co je v rámečku N). Ukazatele jsou pouhá indirection.

A pro velkou odpověď, která pokrývá vše, co budete kdy potřebovat vědět - přečtěte si toto .

5
Gary Rowe

Budu předpokládat, že někdo, kdo se naučí ukazatele, ví, jaké jsou normální proměnné a jak fungují v C. Nyní se pokusme definovat ukazatele s některými jeho atributy-

  • Jsou to také proměnné, ale různé povahy. Předpokládejme, že v proměnném prostoru jsou dvě vrstvy. Normální proměnné různých typů se nacházejí v horní vrstvě a ukazatele ve spodní vrstvě. Stejně jako toto číslo -

    alt text

  • Jak název napovídá „Ukazatel“, ukazatele mohou na něco směřovat. Jako náš prst může ukazovat na nějaký objekt. Na jaké věci poukazují? To jsou normální proměnné. Zkrátka „Ukazatele ukazují na normální proměnné“.

  • Stejně jako normální proměnné jsou ukazatele stejného počtu typů jako int, char nebo float. Ukazatel konkrétního typu může ukazovat pouze na stejný typ proměnných.
  • Ukazatel může ukazovat na jednu proměnnou a později stejný ukazatel může ukazovat na jinou proměnnou. Jen typ by měl být stejný. Takže přidružení ukazatele k některé proměnné není trvalé a lze jej změnit.
  • Jak je tedy deklarován ukazatel? Skoro jako normální proměnné. Název musíte předcházet hvězdičkou (*). Jako-

    int *pointer;
    
  • Jak je potom ukazatel spojen s proměnnou? Za použití & operátor před proměnnou jako je tento příkaz-

    pointer = &variable;
    
  • Jak je ukazatel používán ukazováním na proměnnou? To se také provádí tak, že se před jméno uvede hvězdička (*). Potom ji lze použít místo proměnné, na kterou nyní směřuje-

    *pointer = var1 + var2;
    

    namísto

    variable = var1 + var2;
    
  • Nyní si zahrajte s ukazateli s nějakým kódem. Stačí si na tuto charakteristiku ukazatelů zvyknout. Až do tohoto bodu mluvíme o tom, co ukazatele dělají. Jakmile s tím budete v pořádku, pak začněte studovat, jak ukazatele ukazují na nějakou proměnnou a jak reagují, pokud se na ně použijí normální aritmetické operace. Pak jděte na vztah mezi ukazateli a poli a ukazateli na ukazatele.

To je vše, co bych navrhl ohledně učení ukazatelů.

5
Gulshan

Získejte nějaké malé bloky dřeva.

přidejte kovové háčky na jeden konec a kovové oči na druhý.

nyní můžete vytvořit propojený seznam ve věcech, se kterými můžete hrát.

Zkuste vysvětlit s touto fyzickou rekvizitou. Často jsem si přál, abych to měl při výuce ukazatelů studentům prvního ročníku.

Malý kovový háček je ukazatel, blok dřeva, na který poukazovala.

DEFY komukoli, aby si to po hraní s bloky.

4
Tim Williscroft

Usnadnil jsem si život, když jsem odstranil všechny chmýří a začal chovat ukazatel jako k jakékoli jiné proměnné, spíše než k nějaké magické entitě (už dávno v platové třídě 11) .. prostě vím 3 věci:

  1. Ukazatel je proměnná, která ukládá adresu jiné proměnné (nebo pouze jakékoli adresy).
  2. * se používá k získání hodnoty v umístění paměti, které je uloženo v proměnné ukazatele.
  3. & operátor uvádí adresu umístění paměti.

Zbytek je syntaktický cukr a zdravý rozum. Stačí napsat několik jednoduchých C programů (jako je implementace propojené knihovny seznamů) pomocí ukazatelů, abyste si to pověsili.

4
Sridhar Iyer

Vysvětlení, že jsem se opravdu vysmíval, bylo:

Zvažte městskou síť s různými domy postavenými na pozemcích. V ruce držíte kus papíru. Na papír, který jste napsali:


Davidův dům,

112 Takže a tak ulice.


Papír (proměnná ukazatele) obsahuje adresu, která kazuje na Davidův dům. Pokud chcete říct příteli, aby se podíval na Davidův chladný dům, je mnohem snazší použít jako odkaz na dům hromadu papíru, než poslat skutečnou dvoupatrovou budovu poštou.

Stejně jako u skutečných ukazatelů se můžete dostat do potíží, když sledujete adresu na svém kusu papíru. David se mohl přestěhovat a když se tam dostanete, najdete v zemi velkou díru. V tomto případě by bylo lepší vymazat adresu na papíře, když se David přestěhoval nebo alespoň změnil na novou. Dalo by se také zjistit, že jdete na adresu a zadejte, co si myslíte, že je obývací pokoj vašeho přítele Davida, ale tentokrát skončíte v kompletním cizím bazénu. Někdo jiný použil prostor na adrese, kterou jste měli, pro něco úplně jiného.

2
Per Wiklander
  1. Ukazatel lze považovat za zobecnění indexu do pole.
    • Uvědomte si, že velké pole lze nasekat na řadu menších, nepřekrývajících se polí s proměnnou velikostí. Nyní jsou tato menší pole obvykle považována za pole. Větší je pak celý paměťový prostor počítače. Proces sekání menších polí se nazývá přidělování paměti.
  2. Soubor struktur, které jsou spolu spojeny některými ukazateli, lze považovat za směrovaný graf .
    • Každý vrchol je proměnná, která může obsahovat nějakou hodnotu.
    • Některé proměnné jsou ukazatele a každý ukazatel může mít přesně jednu odchozí hranu na něco jiného.
    • Proměnné, které nejsou ukazatelem, nebudou mít žádný odchozí okraj. Mohli mít libovolný počet příchozích Edge.
2
rwong

Pokud chcete vysvětlit ukazatele, musíte nejprve vysvětlit paměť. Obvykle to dělám pomocí milimetrového/čtvercového papíru s řádky a sloupci. Pokud "student" rozumí paměti, může porozumět tomu, co je adresa. Pokud máte adresu, máte ukazatele.

Můžete hrát s touto abstrakcí. Např. zapište adresu (číslo) jednoho čtverce do druhého čtverce. Nyní nakreslete šipku od čtverce ukazatele k cílovému čtverci. Nyní přepište ukazatel (např. Ho zvyšte) a upravte šipku. Napište adresu do jiného pole a nechte studenta nakreslit šipku ...

Další krok: Pojmenujte určitá pole (jako ukazatel). Nyní můžete vysvětlit dereferencování. A je to.

2
EricSchaefer

Nedokážu si docela dobře vzpomenout na okolnosti kolem mých ukazatelů-aha-moment, ale zpětně jsem si vybavil paměť kolem mého chápání pole ve stylu c. (tj. arr[3] je stejné jako *(arr+3))

Z nějakého důvodu považuji za nesmírně užitečné prohlížet ukazatele jako pole, kdykoli se to stane v situaci ukazatele.

2
Zaz

V zásadě @Gary Rowe představil správný model. Paměť jako sada polí s adresami (čísly). Každé pole obsahuje hodnotu (číslo).

Myšlenkou ukazatele je interpretovat hodnotu v jednom poli jako adresu jiného pole. Tato hodnota se používá k odkazovat na konkrétní pole, proto se nazývá odkaz. dereferencing je tedy proces otevírání pole, na které se odkazuje.

pokud v je proměnná (pole), pak příkaz

  • v znamená hodnotu v, tj. dej mi, co je v krabici
  • *v znamená dereference hodnotu v, tj. dej mi, co je v poli označeno hodnotou v
  • &v znamená odkaz v, tzn. dejte mi adresu do pole

Myslím, že to neslouží účelu zavedení ukazatelů jako něčeho úplně jiného. Když jsem byl malý, bylo to pro mě těžké pochopit. Vždycky to vypadalo jako temná magie, kterou jsem nikdy nepochopil, která vyžadovala spoustu zvláštních postav. Poprvé jsem tomu rozuměl, když jsem psal malou hru s dvojím nasměrováním v jazyce, který nemá ukazatelovou aritmetiku. To mě osvícilo.

Ukazatele jsou otázkou interpretace. Myslím, že vysvětlením, že to dělá věci mnohem jednodušší. Aritmetika ukazatele je velmi jednoduchá a intuitivní operace, pokud je zobrazen jednoduchý příklad s pamětí 10 proměnných.

2
back2dos

Možná jsem to jen já, ale s analogiemi dobře pracuji. Řekněme tedy, že máte přítele (funkci/třídu) "Foo", který chce mít někoho jiného (jinou funkci/třídu), "Bar", z nějakého důvodu vás kontaktovat. "Foo" by vás mohl vzít za barem, ale to není pohodlné, pohybovat všemi těmi bytostmi (instancemi) kolem. „Foo“ však mohl odeslat „Bar“ vaše telefonní číslo (ukazatel). Tímto způsobem, bez ohledu na to, kde jste, „Foo“ ví, jak vás kontaktovat, aniž by vás musel hledat.

A řekněme, že „Bar“ má známého „Baza“, který se s vámi chce také spojit. Jste však chránící své telefonní číslo a nechcete, aby všichni měli, „Baz“ může volat „Bar“ (telefon jako ukazatel), který vám pak může hovor předat (další ukazatel). A tak dále a dále řetěz přátel "Baz" a přátel přátel.

2
Hugo

Ukazatele dávají způsob větší smysl, pokud jste studovali jazyk assembleru nebo počítačovou architekturu. Myslím, že kdybych učil třídu C, začal bych pár týdny architektury, abych vysvětlil paměťový model a druhy instrukcí, které procesor skutečně provádí.

2
Barry Brown

Můj "aha!" moment přišel v tomto tutoriálu:

Výuka o ukazatelích a polích v C

Přesněji řečeno, přišlo v této kapitole: Kapitola 3: Ukazatele a řetězce

Abych byl ještě přesnější, přišlo s touto větou:

Parametr předávaný puts () je ukazatel, což je hodnota ukazatele (protože všechny parametry v C jsou předávány hodnotou) a hodnota ukazatele je adresa, na kterou odkazuje, nebo jednoduše adresa .

Když jsem to četl, mraky se rozpadly a andělé vyhodili fanfáry na trubku.

Jak vidíte, každý tutoriál nebo kniha C, kterou jsem četl dříve, než tvrdil, že C může projít hodnotou nebo odkazem, je to nebezpečná lež. Pravda je, že C vždy prochází hodnotou, ale někdy se předává hodnota jako adresa. V rámci této metody je kopie vytvořena z této adresy, stejně jako by byla vytvořena kopie předaného int. Kopie není není vyrobena z hodnota, na kterou ukazatel ukazuje. Použitím ukazatele v rámci metody můžete získat přístup k původní hodnotě a změnit ji.

Nikdy jsem se nestal programátorem C, ale stal jsem se programátorem .NET a odkazy na objekty a objekty fungují stejným způsobem; odkaz na objekt je předán hodnotou (a tedy zkopírován), ale samotný objekt není zkopírován. Pracoval jsem kolem mnoha programátorů, kteří tomu nerozumí, protože se nikdy nenaučili ukazatele.

2
Kyralessa

Ukazatel je rychlá poznámka, která vám řekne, kde je něco užitečného. Obsahuje umístění věci a řekne vám, jak velká je ta věc (stejně jako v C). Takže dvojitý ukazatel je jako lepkavá nota, která říká: „V lednici je šest balení“. Musíte vlastně jít dostat šest balení zjistit, jestli je to Coke nebo Budweiser.

1
philosodad

http://cslibrary.stanford.edu/

Tato stránka obsahuje skvělé návody pro učení ukazatelů a správu paměti.

Navrhuji, abyste si prošli základy ukazatelů, ukazatele a paměť poskytovanou na webu. Můžete se také podívat na problémy spojené se seznamy uvedené na odkazu a dále posílit koncepty ukazatelů.

1
deovrat singh

Vzhledem k kódu:

int v=42; // deklarace a inicializace jednoduché proměnné

int *p = &v; // vytvoření bodu p proměnné v

O výše uvedeném kódu lze říci následující:

int * p // "int ukazatel p" ... takto deklarujete ukazatel na proměnnou typu int

*p // "označeno p" ... to jsou data, na která p odkazuje, stejně jako v.

&v // "adresa proměnné v" ... to představuje doslovnou hodnotu pro p

1
zener

Klíčem k vysvětlení ukazatelů je zajistit, aby lidé, kterým vysvětlujete, již rozuměli pojmu paměti. I když by to bylo hezké, kdyby to opravdu pochopili, nízká úroveň, věřit, že paměť existuje jako obrovské pole, a pochopení, že přístup k jakékoli poloze v poli je podle jejího indexového umístění, je dostačující.

Další krok, s konceptem předávání umístění indexu spíše než kopírování celé paměti, má smysl pro většinu lidí. A to stačí, aby většina lidí pochopila, proč jsou ukazatele užitečné.

posledním krokem k pochopení ukazatelů je vysvětlit, jak můžete jako parametr předat umístění indexu paměti pro způsob uložení umístění indexu, kde jsou uložena všechna data. Zjistil jsem, že to může být pro některé lidi krok příliš daleko.

Jakmile někdo uchopí tyto základní kroky, je přímo před nimi, aby pochopili, že můžete řetězy ukazovat na neurčito, pokud sledujete, kolikrát je třeba se podívat na adresy, abyste našli skutečný datový objekt.

Jakmile někdo uchopí ukazatele, další věcí, kterou musí rychle pochopit, je rozdíl mezi haldy paměti a paměti zásobníku, a proč jsou ukazatele zásobníku paměti nebezpečné, když jsou předány mimo tuto metodu.

1
Michael Shaw

Trik je vysvětlit, že umístění věci a samotné věci nejsou stejné, stejně jako obrázek dýmky není dýmka . Když věc přesunete, změní se její umístění. Místo zůstává a dá se tam umístit ještě jedna věc.

1
sal

Za předpokladu, že už chápete pole alespoň na povrchní úrovni, moje nejlepší vysvětlení ukazatelů by bylo toto:

Představte si veškerou paměť v počítači (nebo adresní prostor v procesu, chcete-li být přesnější) jako jedno velké pole bajtů. Ukazatel je pouze index do tohoto pole. Ukazatele jsou tedy jen zvláštním druhem celého čísla.

Poznání o všech trikech, které by kodéry C a shromáždění mohli udělat tím, že by se ukazatele považovaly za celá čísla, a jak se rozlišuje čistě konvencí na úrovni jazyka shromáždění, mi pomohlo toto porozumění upevnit.

0
dsimcha

Když jsem byl na univerzitě, měl můj profesor nějaké opravdu čisté snímky PowerPoint, zobrazující bod jako samostatnou proměnnou na své vlastní s šipkou na umístění v paměti (reprezentované jako pole) a když jsme dělali Propojené seznamy, udělal by to krok -by-krok, ukazující, když se změní šipka, když je ukazatel dereferencován atd ..., nebyl způsob, jak by to člověk nemohl pochopit během pár minut. Samotný koncept je opravdu snadný, ale jeho správná implementace nebo aplikace v praktických programech vyžaduje více praxe.

0
chiurox

Než to udělám, vysvětlím, že v programování „vše využívá paměť“ a (statické) přiřazení proměnných v paměti. Vysvětlím také, co je adresa paměti, a vztah mezi paměťovým prostorem, adresou paměti a proměnnými.

Nakonec vysvětlím, že existují celočíselný datový typ a proměnné, řetězcový datový typ a proměnné ... atd., Dokud nevysvětlím, že existuje speciální datový typ, který ukládá adresy do paměti, který má prázdnou hodnotu jako 0 o "", s názvem null.

A konečně dynamicky alokované proměnné díky použití ukazatelů.

0
umlcat

Vzpomínám si na knihu „C puzzle“ nebo podobnou knihu, kterou jsem četl čistě, protože to byla jedna z mála knih o programování/počítači dostupná v knihovně, moje chápání C bylo základní. Hodil na tebe výraz C a požádal o jeho vysvětlení, čím dál složitější.

0
peterchen