it-swarm.it

Qual è una bella spiegazione per i puntatori?

Nei tuoi studi (da solo o per una lezione) hai avuto un momento "ah ah" in cui finalmente hai capito davvero i suggerimenti? Hai una spiegazione che usi per i programmatori principianti che sembra particolarmente efficace?

Ad esempio, quando i principianti incontrano per la prima volta dei puntatori in C, potrebbero semplicemente aggiungere & Se * Finché non viene compilato (come ho fatto io una volta). Forse è stata una foto, o un esempio davvero ben motivato, che ha fatto "puntare" i puntatori per te o il tuo studente. Cos'è stato e cosa hai provato prima che non sembrasse funzionare? Ci sono stati prerequisiti di argomenti (ad es. Strutture o array)?

In altre parole, cosa era necessario per capire il significato di & Se *, Quando potevi usarli con sicurezza? L'apprendimento della sintassi e della terminologia o dei casi d'uso non è sufficiente, a un certo punto l'idea deve essere interiorizzata.


Aggiornamento: Finora mi piacciono molto le risposte; per favore, continua a venire. Ci sono molte grandi prospettive qui, ma penso che molte siano buone spiegazioni/slogan per noi stessi dopo abbiamo interiorizzato il concetto. Sto cercando i contesti e le circostanze dettagliati quando ti è venuto in mente.

Ad esempio:

In C. ho capito sinteticamente solo i puntatori in C. Ho sentito due miei amici che spiegavano i puntatori a un altro amico, che mi chiedeva perché un struct fosse passato con un puntatore. Il primo amico ha parlato di come doveva essere referenziato e modificato, ma era solo un breve commento dell'altro amico in cui mi ha colpito: "È anche più efficiente". Passare 4 byte anziché 16 byte è stato lo spostamento concettuale finale di cui avevo bisogno.

72
Macneil

Diagramma della memoria come griglia

Di solito quello che faccio è rappresentare la memoria come una "griglia", in modo da poter creare indirizzi, evidenziare diversi spazi di memoria e scrivere nei valori delle celle (o anche ulteriormente, le loro rappresentazioni binarie) e collegare i puntatori in memoria ai valori che essi indicare. (E poi menziona ancora che è una semplificazione).

Di solito è un momento "ohhhh" per la maggior parte dei miei studenti.

Simbolo Giocoleria

Quindi quando si tratta di smettere di dimenticare come usare & e *, è molto semplice: presentarlo nello stesso modo in cui eseguono calcoli matematici o fisici. Se si divide una distanza in km per un'ora in ora, si ottiene una velocità in km/h. Cosa c'è dentro deve essere fuori. Semplice.

printf to the Rescue

Fare solo alcuni esempi di base che rappresentano visivamente ciò che hai spiegato con questi li consolerà in ciò che pensano di aver capito, o darà loro l'opportunità di dire "ah, non capisco questo".

Sii ampio

Copri i puntatori per tipi semplici e assicurati che comprendano la differenza tra indirizzamento e dimensione di un tipo di dati, quindi strutture, quindi array e livelli multipli.

Quindi avviare l'aritmetica del puntatore.


Addendum: ricorsione

Di solito spiego la ricorsione in modo simile, usando una rappresentazione visiva. Invitali a stampare l'alfabeto utilizzando una funzione predefinita che scrive un singolo carattere, quindi chiedi loro di stamparlo in ordine inverso cambiando solo due righe.

Di solito c'è un "what the ...?" momento e quando aggiungi solo un altro parametro al tuo printf per stampare valori numerici e rientrare i passaggi, diventa un sospiro di sollievo.


Alternative: il modello Play-Doh e le tazze d'acqua

In realtà ho avuto alcuni colleghi in un'università che hanno mostrato agli studenti un video che spiega i puntatori e gli accessi alla memoria usando play-doh paste. È stato incredibilmente intelligente e ben fatto, anche se non ho mai usato quella tecnica da solo, ad eccezione di studenti molto giovani interessati a comprendere la programmazione (ma di solito quelli che non li avrei condotti verso una lingua usando puntatori troppo presto). Fondamentalmente usando minuscole sfere di play-doh che è possibile collegare ad altre sfere più grandi di play-doh che rappresentano gli spazi di memoria e che è possibile combinare insieme per collegarle (come in una struttura dati collegata) o unire insieme (come in una contigua spazio di memoria). L'uso di colori diversi per gli spazi di memoria indicati e anche i puntatori aiutano. Ma penso ancora che la cosa Memory-as-a-Grid funzioni meglio, dal momento che puoi mostrare chiaramente che il puntamento è davvero una questione di "indirizzamento", come su una "mappa/griglia". Considerando che la modalità Play-doh li confonde ancora nel pensare che le cose si "tocchino" davvero nella memoria.

Anche la tazza d'acqua è stata usata direttamente da un collega, ma non so se sia venuta fuori. È stato un approccio interessante, ma ho notato che molti studenti sono rimasti perplessi dalla spiegazione. Qualcosa di simile a tecnica DevSolo's Coffee Cup . Ma penso che sia in realtà fuorviante mentre fai confondere gli studenti con contenitori, strutture dati, puntatori e array. Presumo che potrebbe essere un approccio interessante per spiegare gli array all'inizio, ma non mi atterrei molto a lungo.

25
haylem

Qualcuno molto più saggio di quanto dicessi una volta:

La suora Wu Jincang chiese al sesto Patriach Huineng: "Ho studiato il sutra Mahaparinirvana per molti anni, ma ci sono molte aree che non capisco del tutto. Per favore, illuminami."

Il patriach rispose: "Sono analfabeta. Per favore, leggimi i personaggi e forse potrò spiegarne il significato".

Disse la suora, "Non puoi nemmeno riconoscere i personaggi. Come riesci quindi a capirne il significato?"

"La verità non ha nulla a che fare con le parole. La verità può essere paragonata alla luna luminosa nel cielo. Le parole, in questo caso, possono essere paragonate a un dito. Il dito può indicare la posizione della luna. Tuttavia, il dito non è il luna. Per guardare la luna, è necessario guardare oltre il dito, giusto? "

80
Frank Shearar

Ho scoperto che i diagrammi sono stati molto utili. Esempio:

pointer diagram


Questo tipo di diagramma mi ha aiutato a vedere che i puntatori erano la propria variabile, ma conteneva un valore che era la posizione di un altro oggetto, ovvero array o stringa. Inoltre, una volta fatto a matita, potrei usarlo per tracciare il mio programma su carta o su una lavagna/lavagna.

46
Michael K

Quando ho "appreso" per la prima volta i puntatori, mi sono spinta in qualche modo. La mia università aveva preso la decisione molto tempo prima che mi iscrivessi per centrare il curriculum attorno a Java, quindi quando il mio professore di Strutture di dati tenne una lezione su C e ci chiese di implementare un elenco XOR con puntatori mi sentivo come se stessi entrando in qualcosa way sopra la mia testa.

Ho capito la definizione:

Un puntatore è una variabile che contiene un indirizzo di una variabile

Ma non ho ancora capito gran parte del concetto. Guardando indietro, penso che fosse incentrato su tre cose:

  1. Che cosa è esattamente una posizione di memoria? (All'epoca non frequentavo un corso di organizzazione informatica)

  2. La sintassi scomoda (So um ... perché esattamente è definita come "int * ip" ma poi mi riferisco alla variabile come "ip"?)

  3. In che modo è esattamente vantaggioso memorizzare l'indirizzo di una variabile piuttosto che utilizzarla?

Non è stato fino a quando ho acquistato il libro K&R e completato tutti i problemi che ho avuto davvero una comprensione per i puntatori. Oltre al fatto che avevo da tempo completato la lezione di Computer Organization (che penso dovrebbe essere richiesta prima di imparare C), parte di essa ha avuto a che fare con il fatto che ho capito che i puntatori possono essere usati per funzioni, array, strutture ... fare cose utili e non semplicemente come memoria per indirizzi di variabili ordinarie.

Ma il mio momento "aha" è stato di gran lunga il modo in cui K&R ha spiegato l'imbarazzante sintassi della definizione di un semplice puntatore. Ho preso appunti in tutto il libro (in cui riformulo i punti sollevati dal libro con le mie parole per migliorare la mia comprensione), e questo è quello relativo a quello:

Un puntatore è una variabile che contiene un indirizzo per una variabile. Un puntatore è sia definito sia dereferenziato (restituendo il valore memorizzato nella posizione di memoria a cui punta) con l'operatore '*'; l'espressione è mnemonica.

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 */

Avevo sempre pensato di non riuscire a cogliere appieno i concetti più avanzati di puntatori fino a quando non avevo qualcosa di così elementare radicato nella mia testa. Mi aveva infastidito all'infinito dopo quell'incarico (che non avevo fatto troppo bene, tra l'altro;)) perché "* ip" non esisteva subito dopo che (pensavo di aver definito) "* ip". La padronanza di questo è essenziale per concetti più avanzati che coinvolgono puntatori, come puntatori a funzioni e definizioni più complicate come questa:

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

Tutto sommato, penso che il concetto di puntatori richieda:

  1. Una comprensione di base di come la memoria è disposta in un computer (e che cos'è la memoria).

  2. Conoscenza di quanto possano essere potenti i puntatori (utilizzo nel mondo reale, non solo un altro concetto astratto che apprendono per motivi di apprendimento).

  3. Decifrare i geroglifici colloquialmente noti come "una definizione di un puntatore"

Quindi, tutto sommato, penso che dovrebbero esserci almeno 3 momenti "aha" quando si imparano i puntatori. Sono ancora uno studente, quindi ho pensato che avresti apprezzato il punto di vista di qualcuno che è ancora (relativamente) fresco di apprendimento del concetto.

32
Kevin

Il puntatore è un po 'come le scorciatoie dell'applicazione sul desktop. Elimina il collegamento e l'obiettivo esiste ancora. Avvia il collegamento e il target viene avviato.

Spiego sempre il funzionamento di questo semplicemente creando un file txt sul mio desktop e due scorciatoie per il file. Dopo aver copiato ed eliminato le scorciatoie, puoi vedere le persone capire l'idea dietro "riferimenti".

Una volta che il gruppo capisce le basi dietro le scorciatoie, puoi iniziare a spiegare i puntatori come preferisci. Probabilmente lo capiranno abbastanza facilmente.

19
Barfieldmv

8-10 anni fa, ho insegnato un corso introduttivo "C" in un college della comunità. Questo è sempre stato un argomento divertente da esplorare. Ciò che sembrava funzionare meglio, e questo dopo aver discusso un paio di volte con un collega, era usare una tazza di caffè e la mano.

Ho usato l'analogia di una tazza di caffè (o fila di esse per array) come una variabile (può contenere qualcosa). Ho quindi usato la mia mano, che potrebbe anche contenere qualcosa o, estendendo il mio indice per "indicare" una tazza di caffè.

Una mano stretta era nulla, un dito puntato sulla mia testa (come una finta pistola) era un puntatore penzolante.

Quindi, con alcune dimostrazioni e viaggi nel debugger, ha fatto clic con la maggior parte.

14
DevSolo

Mi preoccupo molto quando sento la domanda "come hai fatto a capire i puntatori". Ho sempre pensato che il concetto fosse incredibilmente semplice e un'evoluzione logica delle lingue che fornisse un grande potere ai programmatori.

La cosa che mi preoccupa è che non ho mai avuto difficoltà a comprendere il concetto di puntatori. Quindi, quando qui "quando l'hai finalmente capito" ancora e ancora, inizi a pensare:

Lo capisco davvero? Forse non l'ho mai fatto?

Forse il motivo per cui il concetto sembra essere complicato, è perché continuiamo a dire a tutti coloro che devono ancora incontrarli che i puntatori sono così difficili, e qui ci sono cento modi in cui puoi imparare?

Basta lanciare quell'idea là fuori, ovviamente personalmente adoro un buon diagramma e Steve Gibson fa sempre un lavoro fantastico nel spiegare qualcosa !

10
Marcus Whybrow

Non ho mai avuto grossi problemi con i puntatori in C, ma ciò potrebbe essere dovuto al fatto che prima dovevo imparare l'assemblatore. In realtà è stato un sollievo non dover più gestire gli indirizzi da solo. Quindi forse la risposta (supponendo che si tratti di qualcosa che stai insegnando) è di dare agli studenti un linguaggio dell'Assemblea emulato con cui lavorare. --- ) lo capiranno nel processo di scrittura di qualcosa di più sofisticato di "Ciao, mondo".

7
Larry Coleman

Un puntatore è una variabile il cui valore è l'indirizzo di memoria di un'altra variabile.

7
kirk.burleson

Come ho davvero imparato a conoscere i puntatori? Scrivendo un semplice compilatore matricole anno del college.

Come spiegare i suggerimenti nei termini dei laici? Mi piace l'analogia (datata?) Di un catalogo di una biblioteca memorizzato su schede. Ogni carta ("puntatore") contiene informazioni su dove si trova un libro ("dati"), ma in realtà non contiene il libro stesso. Se modifichi la carta ("aritmetica del puntatore"), tutto ciò che fa è cambiare il libro a cui punta e non ha alcun impatto sul libro stesso - fai solo attenzione a non rovinare l'indirizzo o potresti indicare un libro inesistente o anche la libreria sbagliata. Tuttavia, se segui l '"indirizzo" sulla scheda e vai nella parte corretta della libreria ("dereference the pointer"), puoi vedere/modificare il libro stesso.

6

Modificato a supporto del requisito rivisto della domanda

Il mio percorso verso la comprensione "post-pointer" (se ricordo bene) è andato così. Ho avuto una semplice esperienza di programmazione di Assembly da quando ero ancora scherzando con un BBC Micro quindi ho avuto il concetto di memoria come un mucchio di scatole (vedi sotto per questo). Ciò è stato rafforzato dall'uso di array. Tuttavia, stavo andando nel mondo di C e dovevo occuparmi di stringhe e questo significava indicatori. In BASIC questo è stato banale, in assemblatore non ho mai dovuto lavorare con loro, e ora nel classico C sono tutti puntatori e cose del genere. Ah, ma posso tornare indietro alle matrici con stringhe (con terminazione null) come questa:

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

Va bene, è solo una serie di caratteri (8 bit per personaggio nel mio piccolo mondo) con un carattere zero alla fine per mostrare dove finisce. Printf prende semplicemente quell'array e lo scorre sopra stampandolo. E se volessi passare questa stringa in una funzione?

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

È quello che dice il manuale, ma di che si tratta? Hmm, char * significa "puntatore a un carattere". OK ... mi ha perso. Poi ho capito che il carattere * rende p equivalente a s [0]. OK, posso usarlo, ma non ho ancora modificato i puntatori. Voglio dire, come posso impostare alcuni dati con una di queste cose? Di nuovo al manuale ...

char* p = "Hello World!";

Mentre scrivo quanto sopra sto dicendo a me stesso "dichiarare un puntatore a un carattere e impostarlo uguale a questo array di caratteri". In qualche modo quel puntatore elimina la necessità di un array. Immagino sia il compilatore che sta facendo delle cose per me per cambiare. Quindi, come posso cambiare l'array con questo puntatore? So che potrei usare la versione dell'array

 s[2] = 'L'; 

ma qual è l'equivalente in "pointer speak"? Di nuovo a quel manuale ...

*(p+2) = 'L';

Suppongo che * significhi semplicemente "il contenuto dell'indirizzo di memoria" e (p+2) è s[2]. Il che significava che il puntatore p era ... solo ... un ... indirizzo ... bong!

Che c'è il suono dell'Illuminismo. Improvvisamente ho modificato i puntatori (è stato molto tempo fa, noi vecchi timer non abbiamo "grugnito" fino a dopo). Era solo indiretto.


Originale:

OK, il mio valore 2c:

Immagina che la memoria sia un mucchio di scatole. Ogni casella ha un numero sul lato (l'indirizzo). Ogni casella contiene un numero (il contenuto). Puoi lavorare con queste caselle in 2 modi: variabili (Voglio il contenuto della casella N), puntatori (Voglio il contenuto della casella qualunque cosa sia nella casella N ). I puntatori sono semplicemente indiretti.

E per la grande risposta che copre tutto ciò che avrai mai bisogno di sapere - leggi questo .

5
Gary Rowe

Presumo che qualcuno imparerà i puntatori sa quali sono le variabili normali e come funzionano in C. Ora, proviamo a definire i puntatori con alcuni dei suoi attributi-

  • Sono anche variabili, ma di diversa natura. Supponiamo che ci siano due livelli nello spazio variabile. Le normali variabili di diverso tipo risiedono nel livello superiore e i puntatori nel livello inferiore. Come questa figura

    alt text

  • Come suggerisce il nome "Puntatore", i puntatori possono PUNTARE a qualcosa. Come il nostro dito può indicare un oggetto. Quali sono le cose che indicano? Queste sono le variabili normali. In breve, "I puntatori puntano a variabili normali".

  • Come le normali variabili, anche i puntatori sono dello stesso numero di tipi come int, char o float. E un puntatore di un tipo specifico può puntare solo allo stesso tipo di variabili.
  • Un puntatore può puntare a una variabile e successivamente lo stesso puntatore può puntare a un'altra variabile. Solo il tipo dovrebbe essere lo stesso. Pertanto, l'associazione del puntatore a una variabile non è permanente e può essere modificata.
  • Quindi, come viene dichiarato un puntatore? Quasi come le normali variabili. Devi precedere il nome con un asterisco (*). Piace-

    int *pointer;
    
  • Quindi, come viene associato un puntatore a una variabile? Usando il & operatore prima della variabile come questa affermazione-

    pointer = &variable;
    
  • Come viene utilizzato un puntatore indicando una variabile? Questo viene fatto anche precedendo il nome con un asterisco (*). Quindi può essere utilizzato al posto della variabile che punta ora-

    *pointer = var1 + var2;
    

    invece di

    variable = var1 + var2;
    
  • Ora gioca con i puntatori con un po 'di codice. Abituati a queste caratteristiche dei puntatori ora. Fino a questo punto, stiamo parlando di cosa fanno i puntatori. Una volta che sei d'accordo, quindi inizia a studiare come i puntatori indicano una variabile e come reagiscono se vengono applicate le normali operazioni aritmetiche. Quindi andare per la relazione tra puntatori e matrici e puntatori a puntatori.

Questo è tutto ciò che suggerirò sui suggerimenti per l'apprendimento.

5
Gulshan

Prendi dei piccoli blocchi di legno.

aggiungi ganci di metallo a un'estremità e occhi di metallo all'altra.

ora puoi fare un elenco collegato in cose con cui puoi giocare.

Prova a spiegare con questo sostegno fisico. Spesso desideravo avere questo quando insegnavo puntatori agli studenti del primo anno (matricole).

Il piccolo gancio di metallo è il puntatore, il blocco di legno a cui puntava la cosa.

DEFINO a chiunque di non ottenerlo dopo aver giocato con i blocchi.

4
Tim Williscroft

Ho semplificato la mia vita quando ho appena rimosso tutta la lanugine e ho iniziato a trattare il puntatore come qualsiasi altra variabile piuttosto che come qualche entità magica (molto tempo fa nel grado 11) .. basta sapere 3 cose:

  1. Il puntatore è una variabile che memorizza l'indirizzo di un'altra variabile (o semplicemente qualsiasi indirizzo).
  2. * viene utilizzato per ottenere il valore nella posizione di memoria memorizzata nella variabile puntatore.
  3. & operator fornisce l'indirizzo di una posizione di memoria.

Il resto è zucchero sintattico e buon senso. Basta scrivere alcuni semplici programmi in C (come implementare una libreria di elenchi collegati) usando i puntatori per capire.

4
Sridhar Iyer

La spiegazione che mi è davvero piaciuta è stata:

Considera una griglia di città con case diverse costruite su pezzi di terra. Tieni in mano un pezzo di carta. Sulla carta hai scritto:


La casa di David,

112 Così e così via.


Il pezzo di carta (variabile puntatore) contiene un indirizzo che punti alla casa di David. Quando vuoi dire a un amico di dare un'occhiata alla bella casa di David, è molto più facile usare il pezzo di carta come riferimento alla casa piuttosto che inviare il vero edificio a due piani per posta.

Come con i puntatori reali, potresti avere dei problemi quando segui l'indirizzo sul tuo foglio di carta. David avrebbe potuto muoversi e quando arrivi lì trovi solo un grosso buco nel terreno. In questo caso sarebbe stato meglio cancellare l'indirizzo sul foglio quando David si è spostato o almeno cambiarlo con quello nuovo. Potresti anche scoprire che vai all'indirizzo e inserisci quello che pensi sia il soggiorno del tuo amico David, ma questa volta finisci in una piscina completa per sconosciuti. Qualcun altro ha usato lo spazio all'indirizzo che hai avuto per qualcosa di completamente diverso.

2
Per Wiklander
  1. Il puntatore può essere pensato come una generalizzazione di un indice in un array.
    • Considera che un array grande può essere suddiviso in un numero di array più piccoli, non sovrapposti, di dimensioni variabili. Ora, questi array più piccoli sono ciò che di solito pensiamo come array. Quello più grande è quindi l'intero spazio di memoria del computer. Il processo di troncatura di array più piccoli si chiama allocazione della memoria.
  2. Un insieme di strutture che sono collegate tra loro da alcuni puntatori può essere considerato come un grafico diretto .
    • Ogni vertice è una variabile che può contenere un valore.
    • Alcune variabili sono puntatori e ogni puntatore può avere esattamente un bordo in uscita in qualcos'altro.
    • Le variabili che non sono puntatori non avranno alcun Edge in uscita. Potrebbero avere un numero qualsiasi di Edge in arrivo.
2
rwong

Se vuoi spiegare i puntatori devi prima spiegare la memoria. Di solito lo faccio usando carta millimetrata/carta quadrata con righe e colonne. Se lo "studente" capisce la memoria, può capire cos'è un indirizzo. Se hai l'indirizzo hai puntatori.

Puoi giocare con questa astrazione. Per esempio. scrivere l'indirizzo (numero) di un quadrato in un altro quadrato. Ora disegna una freccia dal quadrato del puntatore al quadrato di destinazione. Ora sovrascrivi il puntatore (ad es. Incrementalo) e regola la freccia. Scrivi un indirizzo in un'altra casella e lascia che lo studente disegna la freccia ...

Passaggio successivo: assegna un nome a determinati quadrati (come il puntatore). Ora puoi spiegare la dereferenziazione. Questo è tutto.

2
EricSchaefer

Non riesco proprio a ricordare le circostanze intorno ai miei puntatori-aha-moment, ma ho retroattivamente modificato la memoria attorno alla mia comprensione di un array in stile c. (ovvero arr[3] è uguale a *(arr+3))

Per qualche ragione trovo immensamente utile visualizzare i puntatori come matrici ogni volta che mi capita di trovarmi in una situazione di puntatore.

2
Zaz

Fondamentalmente @Gary Rowe ha introdotto il modello giusto. Memoria come un insieme di caselle con indirizzi (numeri) su di essi. Ogni casella memorizza un valore (numero).

L'idea di un puntatore è di interpretare il valore in una casella come l'indirizzo di un'altra casella. Questo valore viene utilizzato per riferimento a una casella specifica, motivo per cui viene chiamato riferimento. Pertanto dereferencing è il processo di apertura della casella a cui si fa riferimento.

se v è una variabile (casella), quindi l'istruzione

  • v indica il valore di v, ovvero dammi quello che c'è nella scatola
  • *v indica il valore di v, ovvero dammi ciò che è nella casella a cui fa riferimento il valore di v
  • &v significa riferimento v, ovvero dammi l'indirizzo sulla casella

Penso che non serva allo scopo di introdurre i puntatori come qualcosa di completamente diverso. Era un concetto difficile da capire per me quando ero un bambino. Sembrava sempre una magia oscura che non avevo mai veramente capito, che aveva bisogno di molti personaggi speciali. La prima volta che ho capito è stato quando ho scritto un piccolo gioco usando la doppia indiretta in una lingua che non ha l'aritmetica del puntatore. Questo mi ha illuminato.

I puntatori sono una questione di interpretazione. Penso che spiegare ciò renda le cose molto più facili. E l'aritmetica del puntatore sono operazioni estremamente semplici e intuitive se mostrate un semplice esempio con una memoria di 10 variabili.

2
back2dos

Forse sono solo io, ma lavoro bene con le analogie. Quindi supponiamo che tu abbia un amico (funzione/classe) "Foo", che vuole avere qualcun altro (funzione/classe diversa), "Bar", contattarti per qualche motivo. "Foo" potrebbe portarti a vedere "Bar", ma non è conveniente, spostando tutti quegli esseri (istanze) in giro. Tuttavia, "Foo" potrebbe inviare a "Bar" il tuo numero di telefono (puntatore). In questo modo, indipendentemente da dove ti trovi, "Foo" sa come contattarti senza doverti trovare.

E, diciamo, "Bar" ha una conoscenza, "Baz", che vuole anche mettersi in contatto con te. Ma sei protettivo del tuo numero di telefono e non vuoi che tutti lo abbiano, "Baz" può chiamare "Bar" (telefono come puntatore), che può quindi inoltrarti la chiamata (un altro puntatore). E così via lungo la catena degli amici di "Baz" e degli amici di amici.

2
Hugo

I puntatori hanno way più senso se hai studiato il linguaggio Assembly e/o l'architettura del computer. Penso che se insegno a una classe C, inizierei con un paio di settimane di architettura per spiegare il modello di memoria e il tipo di istruzioni effettivamente eseguite dal processore.

2
Barry Brown

Il mio "aha!" è arrivato il momento in questo tutorial:

n tutorial su puntatori e matrici in C

Per l'esattezza, è arrivato in questo capitolo: Capitolo 3: Puntatori e stringhe

Per essere ancora più precisi, è arrivato con questa frase:

Il parametro passato a put () è un puntatore, ovvero il valore di un puntatore (poiché tutti i parametri in C vengono passati per valore) e il valore di un puntatore è l'indirizzo a cui punta, o, semplicemente, un indirizzo .

Quando l'ho letto, le nuvole si sono separate e gli angeli hanno suonato fanfare della tromba.

Perché, vedi, ogni tutorial o libro di C che avevo letto prima affermava che C poteva passare per valore o per riferimento, una bugia nefasta. La verità è che C passa sempre per valore, ma a volte il valore passato sembra essere un indirizzo. All'interno del metodo, viene creata una copia di quell'indirizzo, proprio come una copia di un int trasmesso. Una copia non è non fatta del valore a cui punta il puntatore. Pertanto, utilizzando il puntatore all'interno del metodo è possibile accedere al valore originale e modificarlo.

Non sono mai diventato un programmatore C, ma sono diventato un programmatore .NET e gli oggetti e i riferimenti agli oggetti funzionano allo stesso modo; il riferimento all'oggetto viene passato per valore (e quindi copiato), ma l'oggetto stesso non viene copiato. Ho lavorato con molti programmatori che non lo capiscono perché non hanno mai imparato i puntatori.

2
Kyralessa

Un puntatore è una nota adesiva che ti dice dove si trova qualcosa di utile. Contiene la posizione della cosa e ti dice quanto è grande la cosa (in C, comunque). Quindi un doppio puntatore è come una nota adesiva che dice "C'è un pacchetto da sei in frigo". Devi effettivamente andare a prendere il pacchetto di sei per capire se è Coca-Cola o Budweiser.

1
philosodad

http://cslibrary.stanford.edu/

Questo sito ha grandi tutorial per l'apprendimento di puntatori e gestione della memoria.

Ti suggerirei di consultare le basi dei puntatori, i puntatori e la memoria forniti sul sito. È inoltre possibile esaminare i problemi relativi agli elenchi collegati indicati sul collegamento per rafforzare ulteriormente i concetti del puntatore.

1
deovrat singh

Dato il codice:

int v=42; // dichiara e inizializza una variabile semplice

int *p = &v; // creando un punto p nella variabile v

Di seguito si può dire del codice sopra:

int * p // "int pointer p" ... ecco come dichiarare un puntatore a una variabile di tipo int

*p // "indicato da p" ... ovvero i dati a cui p punta, è uguale a v.

&v // "indirizzo della variabile v" ... rappresenta il valore letterale di p

1
zener

La chiave per spiegare i suggerimenti è assicurarsi che le persone a cui stai spiegando, abbiano già una comprensione del concetto di memoria. Sarebbe bello se lo capissero davvero a basso livello, credendo che la memoria esista come un array enorme e capire che è possibile accedere a qualsiasi posizione dell'array dalla sua posizione di indice è sufficiente.

Il passaggio successivo, avere il concetto di passare la posizione dell'indice anziché copiare l'intera memoria ha senso per la maggior parte delle persone. E questo è sufficiente per consentire alla maggior parte delle persone di capire perché i puntatori sono utili.

il passaggio finale per comprendere i puntatori è spiegare come è possibile passare come parametro una posizione di indice di memoria per il metodo per memorizzare la posizione di indice per la quale sono memorizzati tutti i dati. Ho scoperto che questo può essere un passo troppo avanti per alcune persone da affrontare.

Una volta che qualcuno ha afferrato questi passaggi di base, è subito chiaro per loro che è possibile incatenare i puntatori a tempo indeterminato, purché si tenga traccia di quante volte è necessario guardare gli indirizzi per trovare l'oggetto dati effettivo.

Una volta che qualcuno ha afferrato i puntatori, la prossima cosa che devono afferrare rapidamente è la differenza tra la memoria dell'heap e la memoria dello stack e perché i puntatori alla memoria dello stack sono pericolosi se passati al di fuori del metodo.

1
Michael Shaw

Il trucco è spiegare che la posizione di una cosa e la cosa stessa non sono le stesse, proprio come l'immagine di una pipa non è una pipa . Quando sposti una cosa, la sua posizione cambia. La posizione rimane e qualche altra cosa può essere messa lì.

1
sal

Supponendo che tu capisca già le matrici almeno a livello superficiale, la mia migliore spiegazione per i puntatori sarebbe questa:

Immagina tutta la memoria del tuo computer (o lo spazio degli indirizzi nel tuo processo se vuoi essere più preciso) come un gigantesco array di byte. Un puntatore è solo un indice in quell'array. I puntatori sono quindi solo un tipo speciale di numero intero.

Conoscere tutti i trucchi che i codificatori C e Assembly potrebbero fare trattando i puntatori come numeri interi e come la distinzione sia puramente convenzionale a livello di linguaggio Assembly, mi ha aiutato a consolidare questa comprensione per me.

0
dsimcha

Quando ero all'università, il mio professore aveva delle diapositive PowerPoint davvero ordinate che descrivevano un punto come una variabile separata da solo con una freccia in una posizione di memoria (rappresentata come un array) e quando stavamo facendo liste collegate, lo farebbe passo - passo dopo passo, mostrando quando la freccia cambia, quando il puntatore è deferenziato, ecc ..., non è stato possibile capirlo in un paio di minuti. Il concetto in sé è davvero semplice, ma farlo nel modo giusto o applicarlo in programmi pratici richiede più pratica.

0
chiurox

Prima di farlo, spiego che nella programmazione "tutto utilizza la memoria" e l'allocazione di variabili (statiche) in memoria. Spiegherò anche cos'è un indirizzo di memoria e la relazione tra spazio di memoria, indirizzo di memoria e variabili.

Spiego infine che esistono tipi di dati e variabili integer, tipo di dati stringa e variabili ... e così via, fino a quando non viene spiegato che esiste un tipo di dati speciale che memorizza gli indirizzi di memoria, che ha un valore vuoto come 0 o "", chiamato null.

E, infine, variabili allocate dinamicamente attraverso l'uso di puntatori.

0
umlcat

Ricordo un libro "C puzzle" o simile, che ho letto puramente perché era uno dei pochi libri di programmazione/computer disponibili in biblioteca, la mia comprensione di C era rudimentale. Ti ha lanciato un expresison in C e ti ha chiesto di esplorarlo, diventando sempre più complicato.

0
peterchen