it-swarm-eu.dev

Was ist eine schöne Erklärung für Zeiger?

Hatten Sie in Ihrem eigenen Studium (allein oder für eine Klasse) einen "ah ha" -Moment, als Sie endlich wirklich Hinweise verstanden haben? Haben Sie eine Erklärung für Anfänger, die besonders effektiv erscheint?

Wenn Anfänger beispielsweise zum ersten Mal auf Zeiger in C stoßen, fügen sie möglicherweise nur & Und * S hinzu, bis sie kompiliert werden (wie ich es selbst einmal getan habe). Vielleicht war es ein Bild oder ein wirklich gut motiviertes Beispiel, das Zeiger für Sie oder Ihren Schüler zum "Klicken" brachte. Was war es und was hast du versucht, bevor das nicht zu funktionieren schien? Waren Themenvoraussetzungen (z. B. Strukturen oder Arrays)?

Mit anderen Worten, was war notwendig, um die Bedeutung von & S und * Zu verstehen, wenn Sie sie mit Vertrauen verwenden konnten? Das Erlernen der Syntax und Terminologie oder der Anwendungsfälle reicht nicht aus. Irgendwann muss die Idee verinnerlicht werden.


Update: Ich mag die Antworten bisher sehr; Bitte lass sie kommen. Hier gibt es viele großartige Perspektiven, aber ich denke, viele sind gute Erklärungen/Slogans für uns , nachdem wir das Konzept verinnerlicht haben. Ich suche nach den detaillierten Kontexten und Umständen, als es Ihnen dämmerte.

Zum Beispiel :

Ich habe Zeiger in C nur ein wenig syntaktisch verstanden. Ich hörte zwei meiner Freunde, die einem anderen Freund Zeiger erklärten, der fragte, warum ein struct mit einem Zeiger übergeben wurde. Der erste Freund sprach darüber, wie es referenziert und geändert werden musste, aber es war nur ein kurzer Kommentar des anderen Freundes, bei dem es mich traf: "Es ist auch effizienter." Das Übergeben von 4 Bytes anstelle von 16 Bytes war die letzte konzeptionelle Verschiebung, die ich brauchte.

72
Macneil

Memory-as-a-Grid-Diagramm

Normalerweise stelle ich den Speicher als "Gitter" dar, damit ich Adressen erstellen, verschiedene Speicherbereiche hervorheben und in die Zellenwerte (oder sogar deren binäre Darstellungen) schreiben und die Zeiger im Speicher mit den Werten verknüpfen kann, die sie enthalten zeigen auf. (Und dann noch erwähnen, dass es eine Vereinfachung ist).

Normalerweise ist es für die meisten meiner Schüler ein "ohhhh" Moment.

Symbol Jonglieren

Wenn sie dann aufhören sollen, die Verwendung von & und * zu vergessen, ist es sehr einfach: Präsentieren Sie es genauso, wie sie mathematische oder physikalische Berechnungen durchführen. Wenn Sie eine Entfernung in km durch eine Zeit in Stunden teilen, erhalten Sie eine Geschwindigkeit in km/h. Was drin ist, muss draußen sein. Einfach.

printf zur Rettung

Wenn Sie nur ein paar grundlegende Beispiele machen, die visuell darstellen, was Sie mit diesen erklärt haben, trösten Sie sie in dem, was sie zu verstehen glauben, oder geben Sie ihnen die Möglichkeit zu sagen: "Ah, ich verstehe das nicht.".

Seien Sie umfangreich

Decken Sie Zeiger für einfache Typen ab und stellen Sie sicher, dass sie den Unterschied zwischen der Adressierung und der Größe eines Datentyps, dann Strukturen, dann Arrays und mehreren Ebenen verstehen.

Starten Sie dann die Zeigerarithmetik.


Nachtrag: Rekursion

Normalerweise erkläre ich die Rekursion auf ähnliche Weise anhand einer visuellen Darstellung. Lassen Sie sie das Alphabet mit einer vorgefertigten Funktion drucken, die ein einzelnes Zeichen schreibt, und bitten Sie sie, es in umgekehrter Reihenfolge zu drucken, indem Sie nur zwei Zeilen ändern.

Normalerweise gibt es ein "Was zum ...?" Moment, und wenn Sie Ihrem printf nur einen weiteren Parameter hinzufügen, um numerische Werte zu drucken und die Schritte einzurücken, wird es zu einem Seufzer der Erleichterung.


Alternativen: Das Play-Doh-Modell und die Wasserbecher

Ich hatte tatsächlich einige Mitarbeiter an einer Universität, die Studenten ein Video zeigten, in dem Zeiger und Speicherzugriffe mit Play-Doh-Paste erklärt wurden. Es war unglaublich klug und gut gemacht, obwohl ich diese Technik selbst nie wirklich angewendet habe, außer für sehr junge Lernende, die sich für das Erlernen der Programmierung interessieren (aber normalerweise würde ich sie nicht zu früh mit Zeigern zu einer Sprache führen). Grundsätzlich werden winzige Play-Doh-Bälle verwendet, die Sie an andere größere Play-Doh-Bälle anhängen können, die Speicherplätze darstellen, und die Sie kombinieren können, um sie entweder zu verknüpfen (wie in einer verknüpften Datenstruktur) oder zusammenzuführen (wie in einem zusammenhängenden) Speicherplatz). Die Verwendung unterschiedlicher Farben für die Speicherplätze, auf die verwiesen wird, und die Zeiger helfen ebenfalls. Aber ich denke immer noch, dass das Memory-as-a-Grid-Ding besser funktioniert, da Sie deutlich zeigen können, dass das Zeigen wirklich eine Frage der "Adressierung" ist, wie auf einer "Karte/einem Raster". Während der Play-Doh-Modus sie immer noch verwirrt, zu denken, dass sich die Dinge im Gedächtnis wirklich "berühren".

Das Water Cup-Ding wurde auch direkt von einer Kollegin benutzt, aber ich weiß nicht, ob sie darauf gekommen ist. Es war ein interessanter Ansatz, aber ich bemerkte, dass viele Schüler von der Erklärung verwirrt waren. Etwas Ähnliches wie DevSolos Kaffeetassen-Technik . Aber ich denke, es ist tatsächlich irreführend, wenn Sie die Schüler dazu bringen, Container, Datenstrukturen, Zeiger und Arrays zu verwirren. Es mag ein interessanter Ansatz sein, Arrays am Anfang zu erklären, aber ich würde mich nicht lange daran halten.

25
haylem

Jemand viel weiser als ich einmal sagte:

Die Nonne Wu Jincang fragte den sechsten Patriach Huineng: "Ich habe viele Jahre lang das Mahaparinirvana-Sutra studiert, aber es gibt viele Bereiche, die ich nicht ganz verstehe. Bitte klären Sie mich auf."

Der Patriach antwortete: "Ich bin Analphabet. Bitte lesen Sie mir die Zeichen vor und vielleicht kann ich die Bedeutung erklären."

Die Nonne sagte: "Sie können nicht einmal die Zeichen erkennen. Wie können Sie dann die Bedeutung verstehen?"

"Wahrheit hat nichts mit Worten zu tun. Wahrheit kann mit dem hellen Mond am Himmel verglichen werden. Wörter können in diesem Fall mit einem Finger verglichen werden. Der Finger kann auf die Position des Mondes zeigen. Der Finger ist jedoch nicht der Mond. Um auf den Mond zu schauen, muss man über den Finger hinausblicken, oder? "

80
Frank Shearar

Ich fand, dass Diagramme sehr hilfreich waren. Beispiel:

pointer diagram


Diese Art von Diagramm half mir zu erkennen, dass Zeiger ihre eigene Variable waren, aber einen Wert enthielten, der die Position eines anderen Objekts war, d. H. Eines Arrays oder einer Zeichenfolge. Wenn ich mit Bleistift fertig bin, kann ich damit auch mein Programm auf Papier oder auf einer Tafel/einem Whiteboard nachzeichnen.

46
Michael K

Als ich zum ersten Mal etwas über Zeiger "lernte", wurde ich irgendwie hineingestoßen. Meine Universität hatte die Entscheidung lange Zeit getroffen, bevor ich mich einschrieb, um den Lehrplan auf Java zu konzentrieren. Als mein Professor für Datenstrukturen einen Vortrag über C hielt und uns bat, eine XOR-Liste mit Hinweisen zu implementieren, hatte ich das Gefühl, in etwas einzusteigen Weg über meinen Kopf.

Ich habe die Definition verstanden:

Ein Zeiger ist eine Variable, die eine Adresse einer Variablen enthält

Aber ich habe immer noch keinen großen Teil des Konzepts verstanden. Rückblickend denke ich, dass es um drei Dinge ging:

  1. Was genau ist ein Speicherort? (Zu der Zeit habe ich keinen Computer Organization Kurs besucht)

  2. Die umständliche Syntax (Also ähm ... warum genau ist sie wie "int * ip" definiert, aber anschließend bezeichne ich die Variable als "ip"?)

  3. Wie genau ist es vorteilhaft, die Adresse einer Variablen zu speichern, anstatt nur die Variable zu verwenden?

Erst als ich das K & R-Buch kaufte und jedes Problem erledigte, bekam ich wirklich ein Gespür für Hinweise. Abgesehen von der Tatsache, dass ich die Computer Organization-Klasse lange abgeschlossen hatte (was meiner Meinung nach vor dem Erlernen von C erforderlich sein sollte), hatte ein Teil davon damit zu tun, dass mir klar wurde, dass Zeiger für Funktionen, Arrays, Strukturen ... verwendet werden können. nützliche Dinge zu tun und nicht nur als Speicher für Adressen gewöhnlicher Variablen.

Aber mein "Aha" -Moment war bei weitem die Art und Weise, wie K & R die umständliche Syntax der Definition eines einfachen Zeigers erklärte. Ich habe mir im gesamten Buch Notizen gemacht (in denen ich die Punkte des Buches in meine eigenen Worte umformuliere, um mein Verständnis zu fördern), und dies ist derjenige, der sich darauf bezieht:

Ein Zeiger ist eine Variable, die eine Adresse zu einer Variablen enthält. Ein Zeiger wird mit dem Operator '*' sowohl definiert als auch dereferenziert (was den Wert ergibt, der an dem Speicherort gespeichert ist, auf den er zeigt). der Ausdruck ist mnemonisch.

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

Ich hatte immer das Gefühl, dass ich die fortgeschritteneren Konzepte von Zeigern nicht vollständig erfassen konnte, bis ich etwas so Elementares in meinem Kopf hatte. Es hatte mich nach dieser Aufgabe endlos gestört (was ich übrigens nicht so gut gemacht habe;)), warum "* ip" nicht existierte, nachdem ich (dachte ich) "* ip" definiert hatte. Dies zu beherrschen ist wichtig für fortgeschrittenere Konzepte mit Zeigern wie Funktionszeigern und komplizierteren Definitionen wie diesen:

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

Alles in allem denke ich, dass das Konzept der Zeiger Folgendes erfordert:

  1. Ein grundlegendes Verständnis darüber, wie Speicher in einem Computer angeordnet ist (und was Speicher ist).

  2. Wissen, wie mächtig Zeiger sein können (reale Verwendung, nicht nur ein anderes abstraktes Konzept, das sie zum Zwecke des Lernens lernen).

  3. Entschlüsselung der Hieroglyphen umgangssprachlich als "Definition eines Zeigers" bekannt

Alles in allem denke ich, dass es mindestens 3 "Aha" -Momente geben sollte, wenn man etwas über Zeiger lernt. Ich bin noch ein Student, also dachte ich, Sie würden den Standpunkt von jemandem schätzen, der noch (relativ) frisch vom Erlernen des Konzepts ist.

32
Kevin

Zeiger sind ein bisschen wie die Anwendungsverknüpfungen auf Ihrem Desktop. Löschen Sie die Verknüpfung und das Ziel ist noch vorhanden. Starten Sie die Verknüpfung und das Ziel wird gestartet.

Ich erkläre die Funktionsweise immer, indem ich einfach eine txt-Datei auf meinem Desktop und zwei Verknüpfungen zur Datei erstelle. Nach dem Kopieren und Löschen der Verknüpfungen können Sie sehen, dass die Leute die Idee hinter 'Referenzen' verstehen.

Sobald die Gruppe die Grundlagen hinter den Verknüpfungen verstanden hat, können Sie beginnen, Zeiger zu erklären, wie Sie möchten. Sie werden es wahrscheinlich ziemlich leicht verstehen.

19
Barfieldmv

Vor 8-10 Jahren unterrichtete ich einen Intro "C" -Kurs an einem Community College. Dies war immer ein lustiges Thema zu erkunden. Was am besten zu funktionieren schien, und dies geschah, nachdem ich einige Male mit einem Kollegen gesprochen hatte, war, eine Kaffeetasse und Ihre Hand zu benutzen.

Ich habe die Analogie einer Kaffeetasse (oder einer Reihe davon für Arrays) als Variable verwendet (sie kann etwas enthalten). Ich benutzte dann meine Hand, die auch etwas halten konnte oder indem ich meinen Zeigefinger ausstreckte, um auf eine Kaffeetasse zu "zeigen".

Eine enge Hand war null, ein Finger, der auf meinen Kopf zeigte (wie eine Scheinwaffe), war ein baumelnder Zeiger.

Dann, mit ein paar Demonstrationen und Ausflügen durch den Debugger, klickte es mit den meisten.

14
DevSolo

Ich mache mir wirklich große Sorgen, wenn ich die Frage "Wie haben Sie Zeiger verstanden?" Höre. Ich fand das Konzept immer unglaublich einfach und eine logische Weiterentwicklung der Sprachen, die den Programmierern große Macht verleiht.

Was mich beunruhigt, ist, dass ich es nie schwierig fand, das Konzept der Zeiger zu verstehen. Wenn Sie hier also immer wieder "wann haben Sie es endlich bekommen", denken Sie:

Bekomme ich es tatsächlich Vielleicht habe ich es nie getan?

Vielleicht liegt der Grund dafür, dass das Konzept schwierig zu sein scheint, darin, dass wir jedem, der ihnen noch nicht begegnet ist, immer wieder sagen, dass Zeiger so schwierig sind, und hier sind hundert Möglichkeiten, wie Sie lernen können?

Ich persönlich liebe ein gutes Diagramm und Steve Gibson macht immer einen fantastischen Job, um irgendetwas zu erklären !

10
Marcus Whybrow

Ich hatte nie ein großes Problem mit Zeigern in C, aber das könnte daran liegen, dass ich zuerst Assembler lernen musste. Es war eigentlich eine Erleichterung, die Adressen nicht mehr selbst verwalten zu müssen. Vielleicht besteht die Antwort (vorausgesetzt, Sie unterrichten dies) darin, den Schülern eine emulierte Assemblersprache zu geben, mit der sie arbeiten können. Sie werden es herausfinden, während sie etwas anspruchsvolleres als "Hallo Welt" schreiben.

7
Larry Coleman

Ein Zeiger ist eine Variable, deren Wert die Speicheradresse einer anderen Variablen ist.

7
kirk.burleson

Wie habe ich wirklich etwas über Zeiger gelernt? Durch das Schreiben eines einfachen Compiler-Studienanfängers.

Wie kann man Zeiger in Laienbegriffen erklären? Ich mag die (datierte?) Analogie eines Bibliothekskatalogs, der auf Karteikarten gespeichert ist. Jede Karte ("Zeiger") enthält Informationen darüber, wo sich ein Buch ("Daten") befindet, enthält jedoch nicht das Buch selbst. Wenn Sie die Karte ändern ("Zeigerarithmetik"), ändert sie lediglich das Buch, auf das sie zeigt, und hat keine Auswirkungen auf das Buch selbst. Achten Sie nur darauf, die Adresse nicht zu vermasseln, da Sie sonst möglicherweise auf ein nicht vorhandenes Buch verweisen oder sogar die falsche Bibliothek. Wenn Sie jedoch der "Adresse" auf der Karte folgen und zum richtigen Teil der Bibliothek gehen ("Dereferenzieren des Zeigers"), können Sie das Buch selbst sehen/ändern.

6

Bearbeitet zur Unterstützung der überarbeiteten Anforderung der Frage

Mein Weg zum "Post-Pointer" -Verständnis (wenn ich mich richtig erinnere) verlief so. Ich hatte einige einfache Erfahrungen mit der Assembly-Programmierung, als ich noch mit einem BBC Micro herumgespielt habe , also hatte ich das Konzept des Speichers als eine Reihe von Boxen (siehe unten dazu). Dies wurde durch die Verwendung von Arrays verstärkt. Ich ging jedoch in die Welt von C und musste mich mit Strings auseinandersetzen, und das bedeutete Zeiger. In BASIC war das trivial, in Assembler musste ich nie mit ihnen arbeiten, und jetzt in klassischem C sind es alles Zeiger und so. Ah, aber ich kann mit (nullterminierten) Zeichenfolgen wie folgt zu Arrays zurückkehren:

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

Alles schön und gut, das ist nur eine Reihe von Zeichen (8 Bit pro Zeichen in meiner kleinen Welt) mit einem Nullzeichen am Ende, um zu zeigen, wo es endet. Der printf nimmt nur dieses Array und läuft darüber, um es zu drucken. Aber was ist, wenn ich diesen String an eine Funktion übergeben möchte?

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

Ist das, was im Handbuch steht, aber worum geht es hier? Hmm, char * bedeutet "Zeiger auf ein Zeichen". OK ... habe mich verloren. Dann wurde mir klar, dass das Zeichen * p gleichbedeutend mit s [0] macht. OK, ich kann das verwenden, aber ich habe immer noch nicht herausgefunden, was Zeiger sind. Ich meine, wie setze ich einige Daten mit einem dieser Dinge? Wieder zum Handbuch ...

char* p = "Hello World!";

Während ich das Obige schreibe, sage ich mir: "Deklariere einen Zeiger auf ein Zeichen und setze ihn gleich dieser Zeichenfolge." Irgendwie macht dieser Zeiger die Notwendigkeit eines Arrays überflüssig. Ich denke, es ist der Compiler, der zur Abwechslung ein paar Sachen für mich macht. Wie kann ich das Array mit diesem Zeiger ändern? Ich weiß, dass ich die Array-Version verwenden könnte

 s[2] = 'L'; 

aber was ist das Äquivalent in "Zeiger sprechen"? Wieder zu diesem Handbuch ...

*(p+2) = 'L';

Ich nehme an, dass * einfach "den Inhalt der Speicheradresse" bedeutet und (p+2) ist s[2]. Was bedeutete, dass der Zeiger p ... nur ... eine ... Adresse ... Bong war!

Dass es den Klang der Erleuchtung gibt. Ich habe plötzlich Zeiger gezerrt (es ist lange her, wir Oldtimer "grok" erst später). Es war nur eine Indirektion.


Original:

OK, mein 2c wert:

Stellen Sie sich vor, das Gedächtnis ist ein Haufen Kisten. Jede Box hat eine Nummer auf der Seite (die Adresse). Jede Box enthält eine Nummer (den Inhalt). Sie können mit diesen Feldern auf zwei Arten arbeiten: Variablen (ich möchte den Inhalt von Feld N), Zeiger (ich möchte den Inhalt von Feld , was auch immer in Feld N ist ). Zeiger sind einfach Indirektion.

Und für die große Antwort, die alles abdeckt, was Sie jemals wissen müssen - lesen Sie das .

5
Gary Rowe

Ich gehe davon aus, dass jemand, der Zeiger lernen wird, weiß, was die normalen Variablen sind und wie sie in C funktionieren. Nun wollen wir versuchen, Zeiger mit einigen ihrer Attribute zu definieren.

  • Sie sind auch Variablen, aber unterschiedlicher Natur. Angenommen, der variable Raum enthält zwei Ebenen. Die normalen Variablen verschiedener Typen befinden sich in der oberen Ebene und die Zeiger in der unteren Ebene. Wie diese Figur-

    alt text

  • Wie der Name 'Zeiger' andeutet, können Zeiger auf etwas zeigen. Als ob unser Finger auf ein Objekt zeigen könnte. Worauf weisen sie hin? Dies sind die normalen Variablen. Kurz gesagt, "Zeiger zeigen auf normale Variablen".

  • Wie normale Variablen haben auch Zeiger die gleiche Anzahl von Typen wie int, char oder float. Ein Zeiger eines bestimmten Typs kann nur auf denselben Variablentyp verweisen.
  • Ein Zeiger kann auf eine Variable zeigen und später kann derselbe Zeiger auf eine andere Variable zeigen. Nur der Typ sollte gleich sein. Die Zuordnung eines Zeigers zu einer Variablen ist also nicht permanent und kann geändert werden.
  • Wie wird ein Zeiger deklariert? Fast wie normale Variablen. Vor dem Namen muss ein Sternchen stehen (*). Mögen-

    int *pointer;
    
  • Wie wird dann ein Zeiger einer Variablen zugeordnet? Verwenden Sie den Operator & Vor der Variablen wie folgt:

    pointer = &variable;
    
  • Wie wird ein Zeiger verwendet, wenn auf eine Variable gezeigt wird? Dies geschieht auch, indem dem Namen ein Sternchen vorangestellt wird (*). Dann kann es anstelle der Variablen verwendet werden, auf die es jetzt zeigt.

    *pointer = var1 + var2;
    

    anstatt

    variable = var1 + var2;
    
  • Spielen Sie jetzt mit Zeigern mit etwas Code. Gewöhnen Sie sich jetzt an diese Eigenschaften von Zeigern. Bis zu diesem Punkt sprechen wir darüber, was Zeiger tun. Sobald Sie damit einverstanden sind, beginnen Sie zu untersuchen, wie Zeiger auf eine Variable zeigen und wie sie reagieren, wenn normale arithmetische Operationen auf sie angewendet werden. Gehen Sie dann für die Beziehung zwischen Zeigern und Arrays und Zeigern auf Zeiger.

Das ist alles, was ich über das Lernen von Zeigern vorschlagen werde.

5
Gulshan

Holen Sie sich ein paar kleine Holzklötze.

fügen Sie an einem Ende Metallhaken und am anderen Metallösen hinzu.

sie können jetzt eine verknüpfte Liste mit Dingen erstellen, mit denen Sie spielen können.

Versuchen Sie es mit dieser physischen Requisite. Ich wünschte mir oft, ich hätte dies, wenn ich Schülern im ersten Jahr (Erstsemester) Hinweise gab.

Der kleine Metallhaken ist der Zeiger, der Holzblock, auf den das Ding zeigte.

Ich verweigere jedem, es nicht zu bekommen, nachdem er mit den Blöcken gespielt hat.

4
Tim Williscroft

Ich habe mir das Leben leichter gemacht, als ich einfach alle Flusen entfernt und angefangen habe, Zeiger als jede andere Variable und nicht als magische Einheit zu behandeln (vor langer, langer Zeit in Klasse 11). Ich weiß nur drei Dinge:

  1. Der Zeiger ist eine Variable, die die Adresse einer anderen Variablen (oder einer beliebigen Adresse) speichert.
  2. * wird verwendet, um den Wert an dem Speicherort abzurufen, der in der Zeigervariablen gespeichert ist.
  3. & operator gibt die Adresse eines Speicherorts an.

Der Rest ist syntaktischer Zucker und gesunder Menschenverstand. Schreiben Sie einfach einige einfache C-Programme (wie das Implementieren einer verknüpften Listenbibliothek) mit Zeigern, um sich ein Bild davon zu machen.

4
Sridhar Iyer

Die Erklärung, die ich wirklich geärgert habe, war:

Stellen Sie sich ein Stadtgitter mit verschiedenen Häusern vor, die auf Grundstücken gebaut wurden. In deiner Hand hältst du ein Stück Papier. Auf dem Papier, das Sie geschrieben haben:


Davids Haus,

112 So und so Straße.


Das Blatt Papier (Zeigervariable) enthält eine Adresse, die zeigt auf Davids Haus. Wenn Sie einem Freund sagen möchten, dass er sich Davids cooles Haus ansehen soll, ist es viel einfacher, das Stück Papier als Referenz für das Haus zu verwenden, als das eigentliche zweistöckige Gebäude per Post zu versenden.

Wie bei echten Zeigern können Sie Probleme bekommen, wenn Sie der Adresse auf Ihrem Blatt Papier folgen. David hätte umziehen können und wenn Sie dort ankommen, finden Sie einfach ein großes Loch im Boden. In diesem Fall wäre es besser gewesen, die Adresse auf dem Papier zu löschen, wenn David umgezogen ist, oder sie zumindest in die neue zu ändern. Sie könnten auch feststellen, dass Sie zur Adresse gehen und das Wohnzimmer Ihres Freundes David betreten, aber diesmal landen Sie in einem völlig fremden Schwimmbad. Jemand anderes hat den Platz an der Adresse, die Sie hatten, für etwas völlig anderes verwendet.

2
Per Wiklander
  1. Der Zeiger kann als Verallgemeinerung eines Index in ein Array betrachtet werden.
    • Bedenken Sie, dass ein großes Array in mehrere kleinere, nicht überlappende Arrays mit variabler Größe zerlegt werden kann. Diese kleineren Arrays sind das, was wir normalerweise als Array betrachten. Der größere ist dann der gesamte Speicherplatz des Computers. Das Abhacken kleinerer Arrays wird als Speicherzuweisung bezeichnet.
  2. Eine Reihe von Strukturen, die durch einige Zeiger miteinander verbunden sind, kann als gerichteter Graph betrachtet werden.
    • Jeder Scheitelpunkt ist eine Variable, die einen Wert enthalten kann.
    • Einige Variablen sind Zeiger, und jeder Zeiger kann genau eine ausgehende Kante in etwas anderes haben.
    • Variablen, die keine Zeiger sind, haben keine ausgehende Kante. Sie könnten eine beliebige Anzahl von eingehenden Edge haben.
2
rwong

Wenn Sie Zeiger erklären möchten, müssen Sie zuerst den Speicher erklären. Normalerweise mache ich das mit Millimeterpapier/Karopapier mit Zeilen und Spalten. Wenn der "Student" das Gedächtnis versteht, kann er verstehen, was eine Adresse ist. Wenn Sie eine Adresse haben, haben Sie Hinweise.

Sie können mit dieser Abstraktion spielen. Z.B. Schreiben Sie die Adresse (Nummer) eines Quadrats in ein anderes Quadrat. Zeichnen Sie nun einen Pfeil vom Zeigerquadrat zum Zielquadrat. Überschreiben Sie nun den Zeiger (z. B. erhöhen Sie ihn) und passen Sie den Pfeil an. Schreiben Sie eine Adresse in ein anderes Quadrat und lassen Sie den Schüler den Pfeil zeichnen ...

Nächster Schritt: Geben Sie bestimmten Quadraten (wie dem Zeiger) einen Namen. Jetzt können Sie die Dereferenzierung erklären. Das ist es.

2
EricSchaefer

Ich kann mich nicht ganz an die Umstände um meinen Zeiger-Aha-Moment erinnern, aber ich habe die Erinnerung rückwirkend um mein Verständnis eines Arrays im C-Stil angepasst. (d. h. arr[3] ist dasselbe wie *(arr+3))

Aus irgendeinem Grund finde ich es immens hilfreich, Zeiger immer dann als Arrays anzusehen, wenn ich auf eine Zeigersituation stoße.

2
Zaz

Grundsätzlich hat @Gary Rowe das richtige Modell vorgestellt. Speicher als eine Reihe von Feldern mit Adressen (Nummern) darauf. Jedes Feld speichert einen Wert (eine Nummer).

Die Idee eines Zeigers besteht darin, den Wert in einem Feld als Adresse eines anderen Feldes zu interpretieren. Dieser Wert wird verwendet, um refer auf ein bestimmtes Feld zu verweisen, weshalb er als reference bezeichnet wird. Somit ist Dereferenzierung der Vorgang des Öffnens der Box, auf die verwiesen wird.

wenn v eine Variable (Feld) ist, dann die Anweisung

  • v bedeutet den Wert von v, d. h. geben Sie mir, was in der Box ist
  • *v bedeutet, den Wert von v zu dereferenzieren, d. h. geben Sie mir, was in dem Feld steht, auf das sich der Wert von v bezieht
  • &v bedeutet Referenz v, d. h. geben Sie mir die Adresse auf dem Feld

Ich denke, es dient nicht dem Zweck, Zeiger als etwas völlig anderes einzuführen. Als Kind war es für mich schwer zu verstehen. Es schien immer eine dunkle Magie zu sein, die ich nie wirklich verstanden habe und die viele Sonderzeichen brauchte. Das erste Mal, dass ich es verstand, war, als ich ein kleines Spiel mit doppelter Indirektion in einer Sprache schrieb, die keine Zeigerarithmetik hat. Das hat mich aufgeklärt.

Zeiger sind eine Frage der Interpretation. Ich denke, das zu erklären macht die Dinge viel einfacher. Zeigerarithmetik ist eine äußerst einfache und intuitive Operation, wenn ein einfaches Beispiel mit einem Speicher von 10 Variablen gezeigt wird.

2
back2dos

Vielleicht bin ich es nur, aber ich arbeite gut mit Analogien. Nehmen wir also an, Sie haben einen Freund (Funktion/Klasse) "Foo", der jemanden haben möchte (andere Funktion/Klasse), "Bar", der Sie aus irgendeinem Grund kontaktiert. "Foo" könnte dich dazu bringen, "Bar" zu sehen, aber das ist nicht bequem, all diese Wesen (Instanzen) zu bewegen. "Foo" könnte jedoch "Bar" Ihre Telefonnummer (Zeiger) senden. Auf diese Weise weiß "Foo", egal wo Sie sich befinden, wie er Sie kontaktieren kann, ohne Sie finden zu müssen.

Nehmen wir an, "Bar" hat einen Bekannten, "Baz", der sich auch mit Ihnen in Verbindung setzen möchte. Aber Sie schützen Ihre Telefonnummer und möchten nicht, dass jeder sie hat. "Baz" kann "Bar" (Telefon als Zeiger) anrufen, der den Anruf dann an Sie weiterleiten kann (ein weiterer Zeiger). Und so weiter und so fort entlang der Kette von "Baz" Freunden und Freunden von Freunden.

2
Hugo

Zeiger sind Weg sinnvoller, wenn Sie Assemblersprache und/oder Computerarchitektur studiert haben. Ich denke, wenn ich eine C-Klasse unterrichte, würde ich mit ein paar Wochen Architektur beginnen, um das Speichermodell und die Art der Anweisungen zu erklären, die der Prozessor tatsächlich ausführt.

2
Barry Brown

Mein "Aha!" Moment kam in diesem Tutorial:

Ein Tutorial zu Zeigern und Arrays in C

Um genau zu sein, kam es in diesem Kapitel: Kapitel 3: Zeiger und Zeichenfolgen

Um noch genauer zu sein, kam es mit diesem Satz:

Der an put () übergebene Parameter ist ein Zeiger, dh der Wert eines Zeigers (da alle Parameter in C als Wert übergeben werden), und der Wert eines Zeigers ist die Adresse, auf die er zeigt, oder einfach eine Adresse .

Als ich das las, teilten sich die Wolken und Engel bliesen Trompetenfanfaren.

Sie sehen, jedes C-Tutorial oder Buch, das ich zuvor gelesen hatte, hatte behauptet, C könne als Wert oder als Referenz eine schändliche Lüge sein. Die Wahrheit ist, dass C immer als Wert übergeben wird, aber manchmal ist der übergebene Wert eine Adresse. Innerhalb der Methode wird eine Kopie dieser Adresse erstellt, genau wie eine Kopie eines übergebenen Int. Eine Kopie wird nicht von der Adresse erstellt Wert, auf den der Zeiger zeigt. Mit dem Zeiger innerhalb der Methode können Sie also auf den ursprünglichen Wert zugreifen und ihn ändern.

Ich wurde nie ein C-Programmierer, aber ich wurde ein .NET-Programmierer, und Objekte und Objektreferenzen funktionieren auf die gleiche Weise. Der Verweis auf das Objekt wird als Wert übergeben (und somit kopiert), aber das Objekt selbst wird nicht kopiert. Ich habe mit vielen Programmierern zusammengearbeitet, die das nicht verstehen, weil sie nie Zeiger gelernt haben.

2
Kyralessa

Ein Zeiger ist eine Haftnotiz, die Ihnen sagt, wo etwas Nützliches ist. Es enthält die Position der Sache und sagt Ihnen, wie groß die Sache ist (jedenfalls in C). Ein Doppelzeiger ist also wie eine Haftnotiz mit der Aufschrift "Es gibt ein Sixpack im Kühlschrank". Sie müssen tatsächlich das Sixpack holen, um herauszufinden, ob es Cola oder Budweiser ist.

1
philosodad

http://cslibrary.stanford.edu/

Diese Seite bietet großartige Tutorials zum Lernen von Zeigern und zur Speicherverwaltung.

Ich würde Ihnen empfehlen, die Grundlagen, Zeiger und den Speicher der Zeiger auf der Website durchzugehen. Sie können sich auch die Probleme mit verknüpften Listen ansehen, die auf dem Link angegeben sind, um die Zeigerkonzepte weiter zu stärken.

1
deovrat singh

Angesichts des Codes :

int v=42; // Deklarieren und Initialisieren einer einfachen Variablen

int *p = &v; // einen Punkt p zur Variablen v erstellen

Über den obigen Code kann folgendes gesagt werden :

int * p // "int pointer p" ... so deklarieren Sie einen Zeiger auf eine Variable vom Typ int

*p // "von p gezeigt" ... das sind die Daten, auf die p zeigt, es ist dasselbe wie v.

&v // "Adresse der Variablen v" ... dies repräsentiert den Literalwert für p

1
zener

Der Schlüssel zur Erklärung von Zeigern besteht darin, sicherzustellen, dass die Personen, denen Sie erklären, das Konzept des Gedächtnisses bereits verstehen. Es wäre zwar schön, wenn sie es wirklich auf niedriger Ebene verstehen würden, aber es reicht aus, zu glauben, dass der Speicher als massives Array existiert, und zu verstehen, dass Sie über seine Indexposition auf jede Position im Array zugreifen können.

Der nächste Schritt, das Konzept, den Indexspeicherort zu übergeben, anstatt den gesamten Speicher zu kopieren, ist für die meisten Menschen sinnvoll. Und das reicht aus, damit die meisten Menschen verstehen, warum Zeiger nützlich sind.

der letzte Schritt zum Verständnis von Zeigern besteht darin, zu erklären, wie Sie als Parameter einen Speicherindexspeicherort für die Methode zum Speichern des Indexspeicherortes übergeben können, für den alle Daten gespeichert sind. Ich habe festgestellt, dass dies für manche Menschen zu weit gehen kann, um damit fertig zu werden.

Sobald jemand diese grundlegenden Schritte verstanden hat, ist es für ihn einfach zu verstehen, dass Sie Zeiger unbegrenzt verketten können, solange Sie nachverfolgen, wie oft Sie nach Adressen suchen müssen, um das eigentliche Datenobjekt zu finden.

Sobald jemand Zeiger erfasst hat, muss er als Nächstes schnell den Unterschied zwischen Heap- und Stapelspeicher erfassen und erklären, warum Zeiger auf Stapelspeicher gefährlich sind, wenn sie außerhalb der Methode übergeben werden.

1
Michael Shaw

Der Trick besteht darin zu erklären, dass der Ort eines Dings und das Ding selbst nicht dasselbe sind, genau wie ein Bild einer Pfeife ist keine Pfeife . Wenn Sie ein Objekt bewegen, ändert sich seine Position. Der Standort bleibt erhalten und etwas anderes kann dort platziert werden.

1
sal

Angenommen, Sie verstehen Arrays zumindest oberflächlich bereits, wäre meine beste Erklärung für Zeiger folgende:

Stellen Sie sich den gesamten Speicher Ihres Computers (oder den Adressraum in Ihrem Prozess, wenn Sie genauer sein möchten) als ein riesiges Array von Bytes vor. Ein Zeiger ist nur ein Index in dieses Array. Zeiger sind daher nur eine besondere Art von Ganzzahl.

Das Erlernen aller Tricks, die C- und Assembly-Codierer ausführen könnten, indem Zeiger als Ganzzahlen behandelt werden, und wie die Unterscheidung auf der Ebene der Assembly-Sprache rein konventionell ist, hat mir geholfen, dieses Verständnis zu festigen.

0
dsimcha

Als ich an der Universität war, hatte mein Professor einige wirklich nette PowerPoint-Folien, die einen Punkt als separate Variable mit einem Pfeil zu einem Speicherort (dargestellt wie ein Array) darstellten, und wenn wir verknüpfte Listen machten, machte er es Schritt für Schritt - Schritt für Schritt wird angezeigt, wann sich der Pfeil ändert, wann der Zeiger dereferenziert wird usw. Es gab keine Möglichkeit, ihn innerhalb weniger Minuten nicht zu verstehen. Das Konzept selbst ist wirklich einfach, aber es richtig zu machen oder es in praktischen Programmen anzuwenden, erfordert mehr Übung.

0
chiurox

Bevor ich das mache, erkläre ich, dass bei der Programmierung "alles Speicher verwendet" und (statische) Variablenzuordnung im Speicher. Ich werde auch erklären, was eine Speicheradresse ist und welche Beziehung zwischen Speicherplatz, Speicheradresse und Variablen besteht.

Abschließend erkläre ich, dass es ganzzahlige Datentypen und Variablen, Zeichenfolgendatentypen und Variablen usw. gibt, bis ich erkläre, dass es einen speziellen Datentyp gibt, der Speicheradressen speichert und einen leeren Wert wie 0 o "" hat. genannt null.

Und schließlich dynamisch zugewiesene Variablen durch die Verwendung von Zeigern.

0
umlcat

Ich erinnere mich an ein Buch "C-Rätsel" oder ähnliches, das ich nur gelesen habe, weil es eines der wenigen programmier-/computerbezogenen Bücher in der Bibliothek war. Mein Verständnis von C war rudimentär. Es warf einen C-Ausdruck auf dich und bat darum, es zu erklären, was immer komplizierter wurde.

0
peterchen