Qual è una bella spiegazione per i puntatori? [chiuso]

71

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

Ad esempio, quando i principianti incontrano per la prima volta i puntatori in C, potrebbero semplicemente aggiungere & s e * s fino a quando non compila (come facevo io stesso una volta). Forse è stata una foto, o un esempio davvero ben motivato, che ha fatto puntare "click" a te o al tuo studente. Cos'era e cosa hai provato prima che non sembrasse funzionare? Sono stati riscontrati prerequisiti di argomenti (ad esempio, strutture o matrici)?

In altre parole, cosa era necessario per capire il significato di & s e * , 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: mi piacciono molto le risposte finora; per favore, continuate a farli venire Ci sono molte grandi prospettive qui, ma penso che molte siano buone spiegazioni / slogan per noi dopo abbiamo interiorizzato il concetto. Sto cercando i contesti e le circostanze dettagliate quando ti è venuto in mente.

Ad esempio:

I only somewhat understood pointers syntactically in C. I heard two of my friends explaining pointers to another friend, who asked why a struct was passed with a pointer. The first friend talked about how it needed to be referenced and modified, but it was just a short comment from the other friend where it hit me: "It's also more efficient." Passing 4 bytes instead of 16 bytes was the final conceptual shift I needed.

    
posta Macneil 30.07.2015 - 15:56
fonte

32 risposte

25

Diagramma 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 più, le loro rappresentazioni binarie) e collegare i puntatori in memoria a i valori a cui puntano. (E poi menziona ancora che è una semplificazione).

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

Giocoleria dei simboli

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

printf to the Rescue

Facendo 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 esteso

Puntatori di copertina per tipi semplici e assicurati che comprendano la differenza tra l'indirizzo e la dimensione di un tipo di dati, quindi structs, quindi matrici e più livelli.

Quindi avvia l'aritmetica del puntatore.

Addendum: ricorsione

Di solito spieghiamo la ricorsione in modo simile, usando una rappresentazione visiva. Fagli stampare l'alfabeto usando una funzione pre-scritta che scrive un singolo carattere, quindi chiedi loro di stamparlo in ordine inverso semplicemente cambiando due righe.

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

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

In realtà ho avuto alcuni colleghi di lavoro in un'università che hanno mostrato agli studenti un video che spiega i puntatori e gli accessi alla memoria usando la pasta play-doh. E 'stato incredibilmente intelligente e ben fatto, anche se non ho mai usato questa tecnica da solo, tranne che per gli studenti molto giovani interessati a cogliere la programmazione (ma di solito non li guiderei verso una lingua usando i puntatori troppo presto). In pratica si usano piccole sfere di gioco-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 di dati collegata) o unire insieme (come in un contiguo spazio di memoria). Usare colori diversi per gli spazi di memoria puntati e anche i puntatori aiutano. Ma io continuo a pensare che la cosa di Memory-as-a-Grid funzioni meglio, come puoi chiaramente dimostrare che il puntamento è davvero una questione di "indirizzamento", come su una "mappa / griglia". Mentre la modalità Play-doh li confonde ancora nel pensare che le cose si "toccano" in memoria.

La cosa Water Cup è stata usata direttamente da un collega, ma non so se l'ha inventato. Era un approccio interessante, ma ho notato che molti studenti erano rimasti perplessi dalla spiegazione. Qualcosa di simile alla tecnica della tazza di caffè DevSolo . Ma penso che sia in realtà fuorviante mentre fai confondere gli studenti contenitori, strutture dati, indicatori e array. Potrebbe essere un approccio interessante per spiegare gli array all'inizio, presumo, ma non lo terrei molto a lungo.

    
risposta data 12.04.2017 - 09:31
fonte
79

Qualcuno molto più saggio di quanto ho detto una volta:

The nun Wu Jincang asked the Sixth Patriach Huineng, "I have studied the Mahaparinirvana sutra for many years, yet there are many areas i do not quite understand. Please enlighten me."

The patriach responded, "I am illiterate. Please read out the characters to me and perhaps I will be able to explain the meaning."

Said the nun, "You cannot even recognize the characters. How are you able then to understand the meaning?"

"Truth has nothing to do with words. Truth can be likened to the bright moon in the sky. Words, in this case, can be likened to a finger. The finger can point to the moon’s location. However, the finger is not the moon. To look at the moon, it is necessary to gaze beyond the finger, right?"

    
risposta data 09.11.2010 - 16:16
fonte
46

Ho trovato che i diagrammi erano molto utili. Esempio:


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

    
risposta data 09.11.2010 - 21:02
fonte
32

Quando ho "imparato" per la prima volta dei puntatori, mi è stato in qualche modo spinto. La mia università ha preso la decisione molto tempo prima di iscrivermi per centrare il curriculum attorno a Java, quindi quando il mio professore di Data Structures ha tenuto una conferenza su C e ci ha chiesto di implementare una XOR-List con dei suggerimenti mi sembrava di entrare in qualcosa modo sopra la mia testa.

Ho capito la definizione:

A pointer is a variable that contains an address of a variable

Ma ancora non capivo gran parte del concetto. Guardando indietro, penso che sia centrato su tre cose:

  1. Che cosa esattamente è una posizione di memoria? (Al momento non ho seguito una lezione di Computer Organization)

  2. La sintassi scomoda (quindi um ... perché è esattamente definito come "int * ip" ma successivamente mi riferisco al variabile come "ip"?)

  3. In che modo è vantaggioso memorizzare l'indirizzo di una variabile anziché utilizzare semplicemente la variabile?

Non è stato fino a quando non ho acquistato il libro di K & R e ho completato tutti i problemi che ho davvero capito per i puntatori. Oltre al fatto che avevo da tempo completato la classe Computer Organization (che credo dovesse essere richiesta prima di apprendere C), parte di essa ha 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" di gran lunga è stato il modo in cui K & R ha spiegato la scomoda sintassi di definire un semplice puntatore. Ho preso appunti in tutto il libro (in cui riformulo i punti fatti dal libro nelle mie stesse parole per approfondire la mia comprensione), e questo è quello relativo a questo:

A pointer is a variable that contains an address to a variable. A pointer is both defined and dereferenced (yielding the value stored at the memory location that it points to) with the '*' operator; the expression is mnemonic.

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 senza sosta dopo quell'incarico (che non ho fatto troppo bene, a proposito;)) perché "* ip" non esisteva subito dopo che io (pensavo) definito "* ip". La padronanza di questo è essenziale per concetti più avanzati che coinvolgono i puntatori, come i puntatori di 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 è disposto in un computer (e cosa la memoria è).

  2. Conoscenza di quanto potente     i puntatori possono essere (uso del mondo reale,     non solo un altro concetto astratto     che apprendono per il bene di     learning).

  3. Decifrare il     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 apprezzassi il punto di vista di qualcuno che è ancora (relativamente) fresco nell'apprendere il concetto.

    
risposta data 10.11.2010 - 01:01
fonte
18

I puntatori sono un po 'come le scorciatoie dell'applicazione sul desktop. Elimina il collegamento e il target 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 al file. Dopo aver copiato ed eliminato le scorciatoie, puoi vedere le persone capire l'idea alla base di "riferimenti".

Una volta che il gruppo comprende le basi dietro le scorciatoie, puoi iniziare a spiegare i puntatori in ogni caso. Probabilmente lo capiranno abbastanza facilmente.

    
risposta data 10.11.2010 - 12:00
fonte
12

8-10 anni fa, ho insegnato un corso introduttivo di "C" in un college comunitario. Questo è sempre stato un argomento divertente da esplorare. Quello che sembrava funzionare meglio, e questo dopo aver discusso con un collega, alcune volte è stato usare una tazza di caffè e la tua mano.

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

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

Poi con alcune dimostrazioni e viaggi attraverso il debugger, ha cliccato di più.

    
risposta data 09.11.2010 - 16:20
fonte
10

Mi sono davvero preoccupato 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 forniva un grande potere ai programmatori.

La cosa che mi preoccupa è che non ho mai trovato difficoltà a comprendere il concetto di puntatori. Quindi quando sei qui "quando l'hai finalmente fatto" più e più volte, inizi a pensare:

Do I actually get it? Maybe I never did?

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

Lancia semplicemente quell'idea là fuori, naturalmente personalmente adoro un buon diagramma e Steve Gibson fa sempre un ottimo lavoro di spiegazione di qualsiasi cosa !

    
risposta data 11.11.2010 - 09:45
fonte
7

Non ho mai avuto un grosso problema con i puntatori in C, ma potrebbe essere perché ho dovuto imparare prima l'assembler. In realtà era un sollievo non dovere più gestire gli indirizzi da solo. Quindi forse la risposta (supponendo che questo sia qualcosa che stai insegnando) è di dare agli studenti un linguaggio di assemblaggio emulato con cui lavorare. Loro ci lo capiranno nel processo di scrivere qualcosa di più sofisticato di "Hello, world."

    
risposta data 09.11.2010 - 18:31
fonte
6

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

Come spiegare i puntatori in parole povere? Mi piace l'analogia (datata?) Di un catalogo di librerie 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 attenzione a non rovinare l'indirizzo o potresti puntare a un libro inesistente o anche la libreria sbagliata. Tuttavia, se si segue l '"indirizzo" sulla scheda e si passa alla parte corretta della libreria ("dereferenziazione del puntatore"), è possibile visualizzare / modificare il libro stesso.

    
risposta data 09.11.2010 - 19:36
fonte
6

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

    
risposta data 09.11.2010 - 20:26
fonte
5

Supporrò che qualcuno che impara 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 diversi tipi risiedono nel livello superiore e puntatori nel livello inferiore. Come questa figura -

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

  • Come le variabili normali, anche i puntatori sono dello stesso numero di tipi come int, char o float. E un puntatore di un tipo specifico può puntare solo sullo 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 variabili normali. Devi precedere il nome con un asterisco ( * ). Mi piace-

    int *pointer;
    
  • Quindi, come un puntatore è associato a una variabile? Utilizzando l'operatore & prima della variabile come questa istruzione-

    pointer = &variable;
    
  • Come si usa un puntatore puntando a una variabile? Ciò viene fatto anche precedendo il nome con un asterisco ( * ). Quindi può essere utilizzato al posto della variabile che sta puntando ora -

    *pointer = var1 + var2;
    

    invece di

    variable = var1 + var2;
    
  • Ora gioca con i puntatori con un po 'di codice. Basta abituarsi a queste caratteristiche dei puntatori ora. Fino a questo punto, stiamo parlando di ciò che fanno gli indicatori. Una volta che sei d'accordo, inizia a studiare come i puntatori indicano una variabile e come reagiscono se vengono applicate normali operazioni aritmetiche. Poi vai per la relazione tra puntatori e matrici e puntatori ai puntatori.

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

    
risposta data 10.11.2010 - 06:30
fonte
5

Modificato a supporto del requisito rivisto della domanda

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

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

Tutto bene, questa è solo una serie di caratteri (8 bit per personaggio nel mio piccolo mondo) con un carattere zero alla fine per mostrare dove finisce. Il printf prende solo quell'array e lo gira sopra stampandolo. Ma cosa succede se voglio passare questa stringa in una funzione?

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

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

char* p = "Hello World!";

Mentre scrivo quanto sopra dico a me stesso "dichiarare un puntatore a un carattere e impostarlo uguale a questa matrice di caratteri". In qualche modo quel puntatore elimina la necessità di un array. Credo che sia il compilatore a fare alcune cose per me per un cambiamento. 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"? Spegni di nuovo il manuale ...

*(p+2) = 'L';

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

Che c'è il suono dell'illuminazione. All'improvviso ho twittato i puntatori (era tanto tempo fa, noi vecchi non li abbiamo "rotti" fino a dopo). Era solo indiretta.

originale:

OK, il mio 2c vale:

Immagina che la memoria sia un mucchio di scatole. Ogni casella ha un numero sul lato (l'indirizzo). Ogni scatola contiene un numero (il contenuto). Puoi lavorare con queste scatole 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 sempre bisogno di sapere - leggi questo .

    
risposta data 02.12.2010 - 01:04
fonte
4

Prendi alcuni piccoli blocchi di legno.

aggiungi ganci metallici ad un'estremità e occhi metallici all'altro

ora puoi fare una lista collegata in cose con cui puoi giocare.

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

Il piccolo gancio metallico è il puntatore, il blocco di legno su cui punta la cosa.

NON RISPETTO a nessuno di non averlo capito dopo aver giocato con i blocchi.

    
risposta data 11.11.2010 - 23:45
fonte
4

Mi sono reso più facile la vita quando ho rimosso tutto il lanugine e ho iniziato a trattare il puntatore come qualsiasi altra variabile piuttosto che come un'entità magica (molto tempo fa nel grado 11). Conosciamo solo 3 cose:

  1. Il puntatore è una variabile che memorizza l'indirizzo di un'altra variabile (o di qualsiasi indirizzo).
  2. * è usato per ottenere il valore nella posizione di memoria che è memorizzata nella variabile del puntatore.
  3. & l'operatore 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 come funziona.

    
risposta data 11.11.2010 - 23:59
fonte
2
  1. Il puntatore può essere pensato come una generalizzazione di un indice in un array.
    • Considera che un grande array può essere tagliato in un numero di array più piccoli, non sovrapposti e di dimensioni variabili. Ora, questi array più piccoli sono ciò che normalmente pensiamo come array. Quello più grande è quindi l'intero spazio di memoria del computer. Il processo di smantellamento di array più piccoli è chiamato allocazione di memoria.
  2. Un insieme di strutture collegate da alcuni indicatori può essere pensato come un grafico diretto .
    • Ogni vertice è una variabile che può contenere qualche valore.
    • Alcune variabili sono puntatori e ogni puntatore può avere esattamente un margine in uscita in qualcos'altro.
    • Le variabili che non sono puntatori non avranno margini in uscita. Potrebbero avere qualsiasi numero di bordo in entrata.
risposta data 10.11.2010 - 06:23
fonte
2

Non ricordo affatto le circostanze intorno ai miei indicatori - aha-moment, ma ho ripristinato retroattivamente la memoria attorno alla mia comprensione di un array in stile c. (cioè arr[3] è uguale a *(arr+3) )

Per qualche motivo trovo estremamente utile visualizzare i puntatori come array ogni volta che mi capita su una situazione di puntatore.

    
risposta data 10.11.2010 - 09:16
fonte
2

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

L'idea di un puntatore è interpretare il valore in una casella come l'indirizzo di un'altra casella. Questo valore è usato per refer in una casella specifica, motivo per cui è chiamato reference . Quindi dereferenziazione è 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 , quindi dammi cosa è nella casella
  • *v significa dereferenziare il valore di v , ad esempio, darmi quello che è nella casella cui fa riferimento il valore di v
  • &v significa riferimento v , cioè dammi l'indirizzo sulla casella

Penso che non server lo scopo di introdurre i puntatori come qualcosa di completamente diverso. Era un concetto difficile da capire per me quando ero bambino. Mi è sempre sembrata una magia oscura che non ho mai capito veramente, che aveva bisogno di molti personaggi speciali. La prima volta che ho capito è stato quando ho scritto un piccolo gioco usando la doppia indirezione in un linguaggio che non ha aritmetica puntatore. Questo mi ha illuminato.

I puntatori sono una questione di interpretazione. Penso che spiegare ciò rende le cose molto più semplici. E l'aritmetica dei puntatori è un'operazione estremamente semplice e intuitiva se viene mostrato un semplice esempio con una memoria di 10 variabili.

    
risposta data 10.11.2010 - 13:04
fonte
2

La spiegazione che ho davvero preso in giro è stata:

Consider a city grid with different houses built on pieces of land. In your hand you hold a piece of paper. On the paper you have written:


David's house,

112 So and so street.


The piece of paper (pointer variable) contains an address that points to David's house. When you want to tell a friend to have a look at David's cool house it is much easier to use the pice of paper as a reference to the house than to send the actual two story building in the mail.

As with real pointers you can get into some trouble when you follow the address on your piece of paper. David could have moved and when you get there you just find a big hole in the ground. In this case it would have been better to erase the address on the paper when David moved or at least change it to the new one. You could also find that you go to the address and enter what you think is your friend David's living room but this time you end up in a complete strangers swimming pool. Someone else has used the space at the address you had for something completely different.

    
risposta data 12.11.2010 - 00:20
fonte
2

Se vuoi spiegare i puntatori devi prima spiegare la memoria. Di solito lo faccio usando carta millimetrata / carta a quadretti con righe e colonne. Se lo "studente" comprende la memoria, può capire che indirizzo è. Se hai un indirizzo hai dei puntatori.

Puoi giocare con questa astrazione. Per esempio. scrivi l'indirizzo (numero) di un quadrato in un altro quadrato. Ora traccia 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 altro quadrato e lascia che lo studente disegna la freccia ...

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

    
risposta data 13.11.2010 - 16:27
fonte
2

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

E, diciamo, "Bar" ha un conoscente, "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ì avanti e indietro lungo la catena di amici e amici di amici di "Baz".

    
risposta data 14.11.2010 - 03:44
fonte
2

I puntatori rendono modo più sensato se hai studiato linguaggio assembly e / o architettura del computer. Penso che se insegno in 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.

    
risposta data 18.11.2010 - 22:39
fonte
2

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

Un tutorial su puntatori e matrici in C

Per essere precisi, è arrivato in questo capitolo: Capitolo 3: Pointers and Strings

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

The parameter passed to puts() is a pointer, that is the value of a pointer (since all parameters in C are passed by value), and the value of a pointer is the address to which it points, or, simply, an address.

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

Perché, vedi, ogni tutorial o libro C che avevo letto prima aveva affermato che C poteva passare per valore o per riferimento, una nefasta bugia. La verità è che C passa sempre per valore, ma a volte il valore passato sembra essere un indirizzo. All'interno del metodo, viene fatta una copia di tale indirizzo, proprio come una copia sarebbe fatta di un int passato. Una copia è 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 oggetti e riferimenti a 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 su molti programmatori che non lo capiscono perché non hanno mai imparato i puntatori.

    
risposta data 21.04.2011 - 22:11
fonte
1

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

    
risposta data 09.11.2010 - 16:24
fonte
1

Un puntatore è una nota adesiva che ti dice dove è utile qualcosa. 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'è una confezione da sei in frigo". Devi effettivamente andare a prendere il pacchetto di sei per capire se si tratta di Coca-Cola o Budweiser.

    
risposta data 09.11.2010 - 17:47
fonte
1

Dato il codice:

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

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

Di seguito è riportato il seguente codice:

int * p // "int pointer p" ... questo è il modo in cui dichiari un puntatore alla variabile di tipo int

*p // "puntato da p" ... cioè i dati a cui p punta, è uguale a v.

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

    
risposta data 09.11.2010 - 23:50
fonte
1

link

Questo sito offre eccellenti tutorial per l'apprendimento dei puntatori e la gestione della memoria.

Ti suggerisco di passare attraverso i concetti fondamentali, i puntatori e la memoria forniti nel sito. Puoi anche esaminare i problemi degli elenchi collegati riportati sul link per rafforzare ulteriormente i concetti del puntatore.

    
risposta data 15.11.2010 - 07:43
fonte
1

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

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

Il passo finale per comprendere i puntatori è spiegare come è possibile passare come parametro una posizione di indice di memoria per il metodo per memorizzare la posizione dell'indice per cui sono memorizzati tutti i dati. Ho scoperto che questo può essere un passo troppo lontano per alcune persone.

Una volta che qualcuno ha afferrato questi passaggi fondamentali, è chiaro che è possibile limitare i puntatori a catena a tempo indeterminato, purché si tenga traccia di quante volte è necessario esaminare 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 heap e la memoria dello stack e perché i puntatori allo stack della memoria sono pericolosi quando vengono passati al di fuori del metodo.

    
risposta data 02.12.2010 - 02:25
fonte
0

Ricordo un libro "C enigmi" o simili, che ho letto solo perché era uno dei pochi libri di programmazione / computer disponibili in biblioteca, la mia comprensione di C era rudimentale. Ti ha lanciato un'espressione C e ha chiesto di esplodere, diventando sempre più complicato.

    
risposta data 10.11.2010 - 13:07
fonte
0

Quando ero all'università, il mio professore aveva delle diapositive powerpoint davvero nitide che descrivevano un punto come una variabile separata da sola con una freccia in una posizione di memoria (rappresentata come un array) e quando stavamo facendo liste collegate, lui fatelo passo dopo passo, mostrando quando cambia la freccia, quando il puntatore è dereferenziato ecc ..., non c'era modo di non riuscire a capirlo entro un paio di minuti. Il concetto stesso è davvero facile, ma farlo correttamente o applicarlo in programmi pratici richiede più pratica.

    
risposta data 10.12.2010 - 14:38
fonte
0

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

Infine, spiego che esistono tipi di dati interi e variabili, 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.

    
risposta data 11.03.2011 - 22:27
fonte

Leggi altre domande sui tag