In C ++ kann ich Zeiger und Klassen nicht erfassen

Ich bin frisch vom College und arbeite seit einiger Zeit in C ++. Ich verstehe alle Grundlagen von C ++ und benutze sie, aber es fällt mir schwer, fortgeschrittenere Themen wie Zeiger und Klassen zu verstehen. Ich habe ein paar Bücher und Tutorials gelesen und ich verstehe die Beispiele darin, aber wenn ich mir einige fortgeschrittene Beispiele aus dem wirklichen Leben anschaue, kann ich sie nicht herausfinden. Das bringt mich um, weil ich fühle, dass es mich davon abhält, meine C ++ - Programmierung auf die nächste Stufe zu bringen. Hatte jemand anderes dieses Problem? Wenn ja, wie hast du es durchbrochen? Kennt jemand Bücher oder Tutorials, die Pointer und Klassenkonzepte wirklich gut beschreiben? oder vielleicht ein Beispielcode mit guten beschreibenden Kommentaren unter Verwendung von fortgeschrittenen Zeigern und Klassentechniken? jede Hilfe würde sehr geschätzt werden.

0
hinzugefügt bearbeitet
Ansichten: 5
FYI, Zeiger und Klassen sind die Grundlagen von C ++.
hinzugefügt der Autor Wedge, Quelle
P.S. C ++ ist eine sehr reiche und breite Sprache. Wenn du fortgeschrittene Beispiele nicht verstehen kannst, bedeutet das nicht notwendigerweise, dass du etwas verpasst hast (das "fortgeschrittene" C ++ Kaninchenloch geht sehr, sehr tief). Es wäre hilfreich, wenn Sie genauere Informationen zur Verfügung stellen würden.
hinzugefügt der Autor Wedge, Quelle
Lass mich raten - du schreibst mathematischen Rechencode und dein mangelndes Verständnis von Zeigern behindert die Verarbeitung multidimensionaler Daten. Schließen?
hinzugefügt der Autor Arkadiy, Quelle
Viele Antworten waren wirklich gut. Vielen Dank an alle, die geantwortet haben. Ich werde einigen Antworten folgen, aber es scheint, dass ich einfach dabei bleiben und mehr Erfahrung sammeln muss.
hinzugefügt der Autor timmyg, Quelle
Ich habe versucht, es in meiner Frage deutlich zu machen, aber vielleicht habe ich nicht verstanden, dass ich Zeiger und Klassen in Bezug auf Lehrbücher und Beispiele verstehe. Aber wenn ich den Code von jemand anderem lesen und verstehen muss, zum Beispiel eine Software-API, mit Zeigern und Klassen, habe ich Probleme zu verstehen.
hinzugefügt der Autor timmyg, Quelle
Wie genau arbeitest du für eine Weile ohne dieses Wissen mit C ++? C ++ w/o-Klassen klingt wie C, und C w/o-Zeiger klingt wie um .....
hinzugefügt der Autor Aardvark, Quelle
Du kennst keine Ahnung von C ++, wenn du das Konzept von Klassen nicht verstehst. Und wenn du Zeiger nicht verstehst, dann kennst du wahrscheinlich auch C nicht ... Bildungssystem versagt
hinzugefügt der Autor FlySwat, Quelle
Welche Sprachen haben Sie aus Neugier gelernt, während Sie in der Schule waren? Anders als reine funktionale Sprachen kann ich mir keine Sprachen vorstellen, die weder Zeiger noch Klassen haben.
hinzugefügt der Autor David Locke, Quelle

27 Antworten

Um Zeiger besser zu verstehen, denke ich, kann es nützlich sein, zu sehen, wie die Assemblersprache mit Zeigern arbeitet. Das Konzept der Zeiger ist wirklich einer der grundlegenden Teile der Assemblersprache und x86-Prozessor-Befehlsarchitektur. Vielleicht lässt es dich fallen, als ob Zeiger ein natürlicher Teil eines Programms sind.

Was Klassen betrifft, so mag es, abgesehen vom OO-Paradigma, interessant sein, Klassen aus einer binären Perspektive auf niedriger Ebene zu betrachten. Sie sind in dieser Hinsicht auf der grundlegenden Ebene nicht so komplex.

You may read Inside the C++ Object Model if you want to get a better understanding of what is underneath C++ object model.

0
hinzugefügt

Sie können diesen Artikel von Joel aufschlussreich finden. Abgesehen davon, wenn Sie schon eine Weile in C ++ gearbeitet haben und Ihren Abschluss in CS gemacht haben, sind Sie vielleicht zu einer JavaSchool gegangen (ich würde behaupten, dass Sie überhaupt nicht in C ++ gearbeitet haben; arbeitete in C, aber mit dem C ++ - Compiler).

Um die Antworten von hojou und nsanders zu bestätigen, sind Zeiger für C ++ sehr wichtig. Wenn Sie Zeiger nicht verstehen, dann verstehen Sie nicht die Grundlagen von C ++ (diese Tatsache anzuerkennen ist übrigens der Anfang, C ++ zu verstehen). Ähnlich, wenn Sie Klassen nicht verstehen, dann verstehen Sie nicht die Grundlagen von C ++ (oder OO für diese Angelegenheit).

Für Zeiger halte ich das Zeichnen mit Kästchen für eine gute Idee, aber es ist auch eine gute Idee, in der Montage zu arbeiten. Irgendwelche Anweisungen, die relative Adressierung verwenden, werden Sie dazu bringen zu verstehen, welche Zeiger ziemlich schnell sind, denke ich.

Wie für Klassen (und objektorientierte Programmierung allgemeiner), würde ich Stroustrups "Die C ++ Programmiersprache" neueste Ausgabe empfehlen. Es ist nicht nur das kanonische C ++ - Referenzmaterial, sondern es enthält auch einiges an Material, von grundlegenden objektorientierten Klassenhierarchien und Vererbung bis hin zu Designprinzipien in großen Systemen. Es ist eine sehr gute Lektüre (wenn nicht ein bisschen dick und knapp an Stellen).

0
hinzugefügt
lol, ich habe gerade diesen Artikel von Joel gelesen, und das hat mich dazu gebracht, hierher zu kommen und nach Fragen über Zeiger zu suchen.
hinzugefügt der Autor Spidey, Quelle

Lernen Sie die Assemblersprache und lernen Sie dann C. Dann werden Sie wissen, was die zugrundeliegenden Prinzipien der Maschine sind (und damit auch Hinweise).

Zeiger und Klassen sind grundlegende Aspekte von C ++. Wenn Sie sie nicht verstehen, bedeutet das, dass Sie C ++ nicht wirklich verstehen.

Persönlich habe ich mich mehrere Jahre in C ++ zurückgehalten, bis ich das Gefühl hatte, dass ich C fest im Griff hatte und was in der Assemblersprache unter der Haube passierte. Obwohl dies schon ziemlich lange her ist, glaube ich, dass es meiner Karriere wirklich geholfen hat zu verstehen, wie der Computer auf einer niedrigen Ebene funktioniert.

Das Programmieren kann viele Jahre dauern, aber Sie sollten dabei bleiben, weil es eine sehr lohnende Karriere ist.

0
hinzugefügt

Aus lasseveks Antwort auf eine ähnliche Frage zu SO :

Pointers ist ein Konzept, das für viele   kann zunächst verwirrend sein   insbesondere wenn es um das Kopieren geht   Zeigerwerte herum und still   referenziert den gleichen Speicherblock.

     

Ich habe herausgefunden, dass die beste Analogie darin besteht   Betrachten Sie den Zeiger als ein Stück von   Papier mit einer Hausadresse darauf, und   der Speicherblock, auf den er verweist   tatsächliches Haus. Alle Arten von Operationen   kann also leicht erklärt werden:

     
      
  • Kopieren Sie den Zeigerwert, schreiben Sie die Adresse einfach auf ein neues Stück Papier
  •   
  • Verknüpfte Listen, Zettel im Haus mit der Adresse des nächsten   Haus drauf
  •   
  • Befreie die Erinnerung, zerstöre das Haus und lösche die Adresse
  •   
  • Speicherleck, du verlierst das Stück Papier und kannst das Haus nicht finden
  •   
  • Befreie die Erinnerung, behalte aber eine (jetzt ungültige) Referenz, zerstöre die   Haus, lösche eines der Stücke von   Papier, aber ein anderes Stück Papier haben   mit der alten Adresse, wenn du   Geh zu der Adresse, du wirst kein finden   Haus, aber Sie könnten etwas finden   das ähnelt den Ruinen eines
  •   
  • Buffer overrun, du bewegst mehr Sachen ins Haus als du kannst   möglicherweise passend, verschüttet in die   Nachbarhaus
  •   
0
hinzugefügt

Zeiger und Klassen sind völlig verschiedene Themen, also würde ich sie nicht so zusammenklumpen. Von den beiden würde ich sagen, dass Zeiger grundlegender sind.

Eine gute Übung, um darüber zu lernen, was Zeiger sind, ist Folgendes:

  1. Erstellen Sie eine verknüpfte Liste
  2. durchlaufen Sie von Anfang bis Ende
  3. kehre es um, so dass der Kopf jetzt der Rücken und der Rücken jetzt der Kopf ist

Mach alles zuerst auf einem Whiteboard. Wenn Sie das leicht machen können, sollten Sie keine Probleme mehr haben zu verstehen, was Zeiger sind.

0
hinzugefügt

Wir diskutierten gerade einige der Aspekte von C ++ und OO beim Mittagessen, jemand (ein großer Ingenieur tatsächlich) sagte, dass, wenn Sie nicht einen wirklich starken Programmierhintergrund haben, bevor Sie C ++ lernen, wird es Sie buchstäblich ruinieren.

Ich empfehle dringend, zuerst eine andere Sprache zu lernen und dann nach C ++ zu wechseln, wenn Sie sie brauchen. Es ist nicht so, als gäbe es etwas Tolles an Zeigern, sie sind einfach ein Reststück, das übrig geblieben ist, als es für einen Compiler schwierig war, Operationen ohne sie effizient zu assemblieren.

Heutzutage, wenn ein Compiler eine Array-Operation nicht besser optimieren kann als mit Pointern, ist der Compiler kaputt.

Bitte versteh mich nicht falsch, ich sage nicht, dass C ++ schrecklich ist oder irgendwas, und ich möchte kein Advocacy-Gespräch beginnen, ich habe es benutzt und nutze es gelegentlich, ich empfehle dir nur, mit etwas anderem anzufangen .

Es ist wirklich NICHT so, als würde man lernen, ein manuelles Auto zu fahren, dann kann man es leicht auf eine Automatik anwenden, es ist eher so, als würde man lernen, auf einem dieser riesigen Baukräne zu fahren und dann davon auszugehen, dass es zutrifft, wenn man anfängt, ein Auto zu fahren finde, dass du mit deiner Notbeleuchtung das Auto mit 5 Stundenmeilen in der Mitte der Straße fährst.

[Bearbeiten] Rückblick auf den letzten Absatz - ich denke, das war vielleicht meine genaueste Analogie aller Zeiten!

0
hinzugefügt
irgendwelche Sprachen, die Sie vorschlagen, zuerst zu lernen? wäre Python eine gute Wahl? Ich versuche im Moment, sowohl PHP als auch C ++ zu lernen, syntaxmäßig sind sie ziemlich ähnlich.
hinzugefügt der Autor timmyg, Quelle
Oh, und wenn Sie WIRKLICH neue Programmierkonzepte lernen wollen, schauen Sie sich Scala an. Ehrlich gesagt, das kann das Beste sein, wegen all der Konzepte, die es Ihnen direkt aussetzt. Hascal und Lisp sind auch dafür bekannt, gute Programmierkonzepte zu vermitteln.
hinzugefügt der Autor Bill K, Quelle
C # und Java sind gut, weil sie zur Kompilierzeit überprüft werden und ehrlich, das ist eine wirklich gute Angewohnheit. Wenn Sie nur herumalbern wollen, ist Python gut. Wenn Sie eine Website machen, ruby on Rails - Punkt.
hinzugefügt der Autor Bill K, Quelle

Ich hatte ein Problem, Zeiger in Pascal Weg zurück zu verstehen :) Sobald ich anfing Assembler Zeiger war wirklich die einzige Möglichkeit, auf Speicher zugreifen und es traf mich einfach. Es mag sich wie ein Fernschuss anhören, aber das Ausprobieren von Assembler (was immer eine gute Idee ist, zu versuchen, zu verstehen, worum es bei Computern wirklich geht) wird Ihnen wahrscheinlich Hinweise beibringen. Klassen - nun, ich verstehe dein Problem nicht - war deine Ausbildung reine strukturierte Programmierung? Eine Klasse ist nur eine logische Art, reale Modelle zu betrachten - Sie versuchen ein Problem zu lösen, das sich in einer Anzahl von Objekten/Klassen zusammenfassen lässt.

0
hinzugefügt

Für Zeiger:

Ich fand in diesem Post eine sehr nachdenkliche Diskussion über Zeiger. Vielleicht würde das helfen. Sind Sie vertraut mit Refrescen wie in C #? Das ist etwas, was sich auf etwas anderes bezieht? Das ist wahrscheinlich ein guter Anfang, um Zeiger zu verstehen.

Schau dir auch Kent Fredrics Post auf einem anderen Weg an, um dich mit Zeigern vertraut zu machen.

0
hinzugefügt

Für Klassen:

Der Breakdruhmoment für mich war, als ich von Interfaces erfuhr. Die Idee, die Details Ihrer Schreibweise zu abstrahieren, löste ein Problem, und nur eine Liste von Methoden, die mit der Klasse interagieren, war sehr aufschlussreich.

Tatsächlich sagte mir mein Professor ausdrücklich, dass er unsere Programme benoten würde, indem er unsere Klassen in sein Testkabinett stopfte. Die Einstufung würde anhand der Anforderungen erfolgen, die er an uns gestellt hat und ob das Programm abgestürzt ist.

Lange Rede, kurzer Sinn: Mit Klassen können Sie die Funktionalität einpacken und sie sauberer aufrufen (meistens gibt es Ausnahmen)

0
hinzugefügt
Ein Test-Kabelbaum ist ein Code, der einen anderen Satz von Code ausübt. Mein Professor hatte im Grunde ein Hauptprogramm, das Funktionen in unserer Klasse nannte. Er würde den Test durchführen, eine Note markieren, deine Datei löschen und die nächste Studentendatei in seine Lösung einfügen und den gesamten Prozess wiederholen.
hinzugefügt der Autor Jason Z, Quelle
Was ist ein "Prüfgeschirr"?
hinzugefügt der Autor DarenW, Quelle

Vorgeben, ein Zeiger ist eine Array-Adresse.

x = 500;//memory address for hello;
MEMORY[x] = "hello"; 
print  MEMORY[x]; 

Es ist eine grafische Vereinfachung, aber größtenteils, solange Sie nie wissen wollen, was diese Nummer ist oder von Hand gesetzt haben, sollten Sie in Ordnung sein.

Damals, als ich C verstanden habe, hatte ich ein paar Makros, die mehr oder weniger Ihnen erlaubten, Zeiger zu verwenden, genau wie sie ein Array-Index im Speicher waren. Aber ich habe diesen Code längst verloren und längst vergessen.

Ich erinnere mich, dass es damit begann

#define MEMORY 0; 
#define MEMORYADDRESS( a ) *a;

und das allein ist kaum nützlich. Hoffentlich kann jemand anderes diese Logik erweitern.

0
hinzugefügt
Ja, ich verstehe es nicht, ich denke, das ist ein guter Weg, um Zeiger zu verstehen. Arrays sind leichter zu verstehen als Zeiger, IMO, also denke ich, es ist ein guter Ausgangspunkt.
hinzugefügt der Autor Doug T., Quelle
Ich denke, das ist eine sehr nützliche Übung. Heck in vielen eingebetteten Systemen hatte ich keinen Zeiger auf Dinge, die für mich zugewiesen wurden, ich hatte einen Array-Index :).
hinzugefügt der Autor Doug T., Quelle
für diejenigen von euch, die mich für diesen Beitrag runtermetzeln, es funktioniert. Ich habe es benutzt, ich habe anderen dabei geholfen. Die Tatsache, dass das OS alles für Sie abstrahiert, ist für die Übung unwichtig.
hinzugefügt der Autor Kent Fredric, Quelle

To understand pointers, I can't recommend the K&R book highly enough.

0
hinzugefügt

Hast du Bjarne Stroustrups C ++ Programmiersprache gelesen? Er hat C ++ erstellt.

Die C ++ FAQ Lite ist auch gut.

0
hinzugefügt

Der Punkt, an dem ich wirklich Hinweise bekam, war die Codierung von TurboPascal auf einem FatMac (um 1984 oder so) - damals die native Mac-Sprache.

Der Mac hatte ein merkwürdiges Speichermodell, bei dem bei Zuweisung der Adresse der Speicher in einem Zeiger auf dem Heap gespeichert wurde, dessen Speicherort jedoch nicht garantiert war und stattdessen die Speicherbehandlungsroutinen einen Zeiger auf den Zeiger zurückgaben - bezeichnet als ein Handle . Um auf irgendeinen Teil des zugewiesenen Speichers zuzugreifen, musste das Handle zweimal dereferenziert werden. Es dauerte eine Weile, aber ständige Übung trieb die Lektion schließlich nach Hause.

Pascals Zeigerhandling ist leichter zu verstehen als C ++, wo die Syntax dem Anfänger nicht hilft. Wenn Sie wirklich und wirklich stecken, Verweise in C zu verstehen, dann Ihre beste Option könnte sein, eine Kopie einen Pascal-Compiler zu erhalten und versuchen, einige grundlegende Zeiger Code darin schreiben (Pascal ist nahe genug zu C Sie erhalten die Grundlagen in ein paar Stunden ). Verknüpfte Listen und Ähnliches wären eine gute Wahl. Sobald Sie sich mit der Rückkehr nach C ++ und mit den gemeisterten Konzepten auskennen, werden Sie feststellen, dass die Klippe nicht so steil aussieht.

0
hinzugefügt

Zeiger scheinen in anderen Antworten bereits angesprochen zu sein (kein Wortspiel beabsichtigt).

Klassen sind grundlegend für OO. Ich hatte enorme Schwierigkeiten, meinen Kopf in OO-artige, zehn Jahre fehlgeschlagene Versuche zu reißen. Das Buch, das mir schließlich geholfen hat, war Craig Larmans "Anwenden von UML und Mustern". Ich weiß, es klingt, als ob es um etwas anderes geht, aber es ist wirklich eine großartige Arbeit, dich in die Welt der Klassen und Objekte zu entführen.

0
hinzugefügt

This link has a video describing how pointers work, with claymation. Informative, and easy to digest.

This page has some good information on the basic of classes.

0
hinzugefügt
Alles mit Claymation bekommt in meinem Buch +1.
hinzugefügt der Autor Aardvark, Quelle

Das beste Buch, das ich zu diesen Themen gelesen habe, ist Thinking in C ++ von Bruce Eckel. Sie können es kostenlos herunterladen hier .

0
hinzugefügt
danke das heruntergeladene Buch kommt mit vielen Beispielen
hinzugefügt der Autor timmyg, Quelle

Klassen sind relativ einfach zu verstehen; OOP kann viele Jahre dauern. Persönlich habe ich das wahre OOP erst im letzten Jahr richtig verstanden. Es ist schade, dass Smalltalk in Colleges nicht so verbreitet ist, wie es sein sollte. Es bringt wirklich den Punkt nach Hause, an dem OOP über Objekte handelt, die Nachrichten handeln, statt dass Klassen selbständige globale Variablen mit Funktionen sind.

Wenn Sie wirklich neu in Klassen sind, dann kann das Konzept eine Weile dauern, um zu begreifen. Als ich sie das erste Mal in der 10. Klasse kennenlernte, habe ich es erst verstanden, als ich jemanden hatte, der wusste, was sie taten, den Code durchgehen und erklären, was vor sich ging. Das ist es, was ich dir vorschlage.

0
hinzugefügt

In gewissem Sinne können Sie "Zeiger" als einen der zwei grundlegendsten Typen in der Software betrachten - die anderen sind "Werte" (oder "Daten") - die in einem riesigen Block von eindeutig adressierbaren Speicherorten existieren. Denk darüber nach. Objekte und Strukturen usw. existieren nicht wirklich im Speicher, nur Werte und Zeiger tun es. Tatsächlich ist ein Zeiger auch ein Wert .... der Wert einer Speicheradresse, die wiederum einen anderen Wert enthält .... und so weiter.

So, in C/C++, when you declare an "int" (intA), you are defining a 32bit chunk of memory that contains a value - a number. If you then declare an "int pointer" (intB), you are defining a 32bit chunk of memory that contains the address of an int. I can assign the latter to point to the former by stating "intB = &intA", and now the 32bits of memory defined as intB, contains an address corresponding to intA's location in memory.

Wenn Sie den intB-Zeiger "dereferenzieren", betrachten Sie die Adresse, die im Speicher des intB gespeichert ist, suchen diesen Ort und schauen sich dann den dort gespeicherten Wert (eine Zahl) an.

Commonly, I have encountered confusion when people lose track of exactly what it is they're dealing with as they use the "&", "*" and "->" operators - is it an address, a value or what? You just need to keep focused on the fact that memory addresses are simply locations, and that values are the binary information stored there.

0
hinzugefügt

Zeiger und Klassen sind in C ++ keine wirklich fortgeschrittenen Themen. Sie sind ziemlich grundlegend.

Für mich verfestigten sich die Zeiger, als ich anfing, Boxen mit Pfeilen zu zeichnen. Zeichne eine Box für einen int. Und int * ist jetzt eine separate Box mit einem Pfeil, der auf die int-Box zeigt.

Damit:

int foo = 3;          //integer
int* bar = &foo;      //assigns the address of foo to my pointer bar

Mit meiner Pointer-Box (Bar) habe ich die Wahl, entweder auf die Adresse in der Box zu schauen. (Welches ist die Speicheradresse von foo). Oder ich kann manipulieren, wo auch immer ich eine Adresse habe. Diese Manipulation bedeutet, dass ich diesen Pfeil zur Ganzzahl (foo) folge.

*bar = 5; //asterix means "dereference" (follow the arrow), foo is now 5
bar = 0;  //I just changed the address that bar points to

Klassen sind ein anderes Thema. Es gibt ein paar Bücher über objektorientiertes Design, aber ich kenne keine guten Bücher für Anfänger von oben. Vielleicht haben Sie Glück mit einem Intro-Java-Buch.

0
hinzugefügt
Nun, sie sind fortgeschrittene Themen für mich, haha, ich verstehe deine Beispiele hier, aber wenn ich versuche, den Code eines anderen zu verstehen, kann ich es nicht herausfinden ... vielleicht brauche ich einfach mehr Erfahrung ... Danke für die Antwort.
hinzugefügt der Autor timmyg, Quelle
Ich unterstütze das. Für Anfänger, übersetzen Sie immer "Zeiger" zu "Adresse" und "Dereferenzierung" zu "Reise-zur-Adresse", genau wie ein Auto zu fahren. Zeiger zu Zeigern werden zu Weiterleitungs-Postfächern - Adressen, bei denen Sie eine andere Adresse anstelle eines Speicherortes finden.
hinzugefügt der Autor Aaron, Quelle
Es kann gut sein, dass viel von diesem Code nicht zu gut geschrieben ist. Ich habe einmal viel Zeit damit verbracht, herauszufinden, wie funktionierender Pointer-Code funktioniert. Ich gab auf und fragte einen Vorgesetzten. Er schaute es für 2 Sekunden an und sagte "Huh. Das wird einen Absturz verursachen. Besser es reparieren." Erfahrung: Die Fähigkeit, ein Exemplar anzusehen, etwas Bizarres zu sehen und zu denken "Da stimmt etwas nicht" und nicht "Es stimmt etwas nicht mit mir".
hinzugefügt der Autor deworde, Quelle

Zeiger in C/C ++ verstehen

Bevor man verstehen kann, wie Zeiger funktionieren, muss man verstehen, wie Variablen in Programmen gespeichert und aufgerufen werden. Jede Variable hat zwei Teile - (1) die Speicheradresse, in der die Daten gespeichert sind und (2) den Wert der gespeicherten Daten.

Die Speicheradresse wird oft als L-Wert einer Variablen bezeichnet, und der Wert der gespeicherten Daten wird als R-Wert bezeichnet (l und r bedeutet links und rechts).

Betrachten Sie die Aussage:

int x = 10;

Intern ordnet das Programm eine Speicheradresse der Variablen x zu. Nehmen wir in diesem Fall an, dass das Programm x der Adresse 1001 zuweist (keine realistische Adresse, sondern der Einfachheit halber gewählt). Daher ist der L-Wert (Speicheradresse) von x 1001 und der R-Wert (Datenwert) von x ist 10.

The rvalue is accessed by simply using the variable “x”. In order to access the lvalue, the “address of” operator (‘&’) is needed. The expression ‘&x’ is read as "the address of x".

Expression          Value
----------------------------------
x                   10
&x                  1001

The value stored in x can be changed at any time (e.g. x = 20), but the address of x (&x) can never be changed.

Ein Zeiger ist einfach eine Variable, die zum Ändern einer anderen Variablen verwendet werden kann. Es tut dies, indem es eine Speicheradresse für seinen rvalue hat. Das heißt, es zeigt auf einen anderen Speicherort im Speicher.

Erstellen Sie einen Zeiger auf "x" wie folgt:

int* xptr = &x;

The “int*” tells the compiler that we are creating a pointer to an integer value. The “= &x” part tells the compiler that we are assigning the address of x to the rvalue of xptr. Thus, we are telling the compiler that xptr “points to” x.

Angenommen, dass xptr einer Speicheradresse von 1002 zugewiesen ist, sieht der Speicher des Programms möglicherweise so aus:

Variable    lvalue    rvalue
--------------------------------------------
x           1001      10   
xptr        1002      1001

Das nächste Puzzleteil ist der "Indirektionsoperator" ('*'), der wie folgt verwendet wird:

int y = *xptr;

Der Indirektionsoperator weist das Programm an, den rvalue von xptr eher als Speicheradresse als als Datenwert zu interpretieren. Das heißt, das Programm sucht nach dem Datenwert (10), der unter der von xptr (1001) bereitgestellten Adresse gespeichert ist.

Alles zusammenfügen:

Expression      Value
--------------------------------------------
x                   10
&x                  1001
xptr                1001
&xptr               1002
*xptr               10

Nun, da die Konzepte erklärt wurden, folgt hier ein Code, um die Macht der Zeiger zu demonstrieren:

int x = 10;
int *xptr = &x;

printf("x = %d\n", x);
printf("&x = %d\n", &x);        
printf("xptr = %d\n", xptr);
printf("*xptr = %d\n", *xptr);

*xptr = 20;

printf("x = %d\n", x);
printf("*xptr = %d\n", *xptr);

Für die Ausgabe würden Sie sehen (Hinweis: die Speicheradresse wird jedes Mal anders sein):

x = 10
&x = 3537176
xptr = 3537176
*xptr = 10
x = 20
*xptr = 20

Notice how assigning a value to ‘*xptr’ changed the value of ‘x’. This is because ‘*xptr’ and ‘x’ refer to the same location in memory, as evidenced by ‘&x’ and ‘xptr’ having the same value.

0
hinzugefügt
Danke für die sehr hilfreiche Antwort
hinzugefügt der Autor timmyg, Quelle
Lvalues ​​und Rvalues ​​haben nichts mit Speicheradressen zu tun.
hinzugefügt der Autor Puppy, Quelle

The book that cracked pointers for me was Illustrating Ansi C by Donald Alcock. Its full of hand-drawn-style box and arrow diagrams that illustrate pointers, pointer arithmetic, arrays, string functions etc...

Offensichtlich ist es ein "C" -Buch, aber für Kern-Grundlagen ist es schwer zu schlagen

0
hinzugefügt

Eines der Dinge, die mir beim Verständnis dieser Konzepte geholfen haben, ist UML - die Unified Modeling Language - zu lernen. Konzepte des objektorientierten Designs in einem grafischen Format zu sehen, hat mir wirklich geholfen zu verstehen, was sie bedeuten. Manchmal kann es schwierig sein, diese Konzepte zu verstehen, indem man sich einmal ansieht, welcher Quellcode sie implementiert.

Objektorientierte Paradigmen wie Vererbung in graphischer Form zu sehen, ist eine sehr wirkungsvolle Möglichkeit, das Konzept zu verstehen.

Martin Fowlers UML Distilled ist eine gute, kurze Einführung.

0
hinzugefügt

Es gibt keine Subventionen für das Üben.

Es ist einfach, ein Buch durchzulesen oder einen Vortrag zu hören und zu fühlen, als würde man verfolgen, was vor sich geht.

Was ich empfehlen würde ist, einige der Codebeispiele zu nehmen (ich nehme an, Sie haben sie irgendwo auf der Festplatte), kompilieren Sie sie und führen Sie sie aus, dann versuchen Sie sie zu ändern, um etwas anderes zu machen.

  • Fügen Sie einer Hierarchie eine weitere Unterklasse hinzu
  • Hinzufügen einer Methode zu einer vorhandenen Klasse
  • Ändern Sie einen Algorithmus, der iteriert Vorwärts durch eine Sammlung zu gehen rückwärts statt.

Ich denke nicht, dass es ein "Silberkugel" -Buch gibt, das es tun wird.

Was für mich nach Hause fuhr, was Zeiger bedeuteten, war die Arbeit in Assembly, und zu sehen, dass ein Pointer eigentlich nur eine Adresse war, und dass ein Pointer nicht bedeutete, dass das, worauf er hinwies, ein bedeutungsvolles Objekt war.

0
hinzugefügt

Für Zeiger und Klassen, hier ist meine Analogie. Ich werde ein Kartenspiel verwenden. Das Kartenspiel hat einen Nennwert und einen Typ (9 von Herzen, 4 von Pik usw.). In unserer C ++ - ähnlichen Programmiersprache "Deck of Cards" sagen wir Folgendes:

HeartCard card = 4;//4 of hearts!

Jetzt weißt du, wo die 4 Herzen sind, denn bei Gott, du hältst das Deck offen in deiner Hand und es ist ganz oben! In Bezug auf den Rest der Karten sagen wir einfach, dass die 4 der Herzen am Anfang ist. Also, wenn ich dich gefragt hätte, welche Karte zu Beginn ist, würdest du sagen: "Die 4 Herzen natürlich!". Nun, Sie haben mich einfach darauf hingewiesen, wo die Karte ist. In unserer Programmiersprache "Deck of Cards" könnte man auch Folgendes sagen:

HeartCard card = 4;//4 of hearts!
print &card//the address is BEGINNING!

Jetzt drehe dein Kartenspiel um. Die Rückseite beginnt jetzt und Sie wissen nicht, was die Karte ist. Aber lassen Sie uns sagen, Sie können es machen, was Sie wollen, weil Sie voller Magie sind. Lass es uns in unserer "Deck of Cards" -Sprache machen!

HeartCard *pointerToCard = MakeMyCard( "10 of hearts" );
print pointerToCard//the value of this is BEGINNING!
print *pointerToCard//this will be 10 of hearts!

Nun, MakeMyCard ("10 of hearts") hast du gezaubert und wusstest, dass du auf ANFANGEN zeigen wolltest und die Karte zu einer 10er Herzen macht! Du drehst deine Karte um und, voila! Jetzt kann dich der * wegwerfen. Wenn ja, überprüfen Sie dies:

HeartCard *pointerToCard = MakeMyCard( "10 of hearts" );
HeartCard card = 4;//4 of hearts!
print *pointerToCard;//prints 10 of hearts
print pointerToCard;//prints BEGINNING
print card;//prints 4 of hearts
print &card;//prints END - the 4 of hearts used to be on top but we flipped over the deck!

Was Klassen betrifft, haben wir in diesem Beispiel Klassen verwendet, indem wir einen Typ als HeartCard definiert haben. Wir wissen, was eine HeartCard ist ... Es ist eine Karte mit einem Wert und der Art des Herzens! Also haben wir das als HeartCard klassifiziert. Jede Sprache hat eine ähnliche Art zu definieren oder zu "klassifizieren", was Sie wollen, aber sie alle teilen das gleiche Konzept! Hoffe das half ...

0
hinzugefügt
Das war eine ziemlich lausige Analogie.
hinzugefügt der Autor FlySwat, Quelle

Pointers are not some sort of magical stuff, you're using them all the time!
When you say:

int a;

and the compiler generates storage for 'a', you're practically saying that you're declaring
an int and you want to name its memory location 'a'.

When you say:

int *a;

Sie deklarieren eine Variable, die eine Speicherstelle eines int enthalten kann. So einfach ist das. Haben Sie auch keine Angst vor Zeigerarithmetik, nur immer Denken Sie an eine "Gedächtniskarte", wenn Sie mit Zeigern zu tun haben und in Begriffen denken durch Speicheradressen zu gehen.

Klassen in C ++ sind nur eine Möglichkeit, abstrakte Datentypen zu definieren. Ich würde vorschlagen, ein gutes OOP-Buch zu lesen, um das Konzept zu verstehen. Wenn Sie interessiert sind, erfahren Sie, wie C ++ - Compiler Code generieren, um OOP zu simulieren. Aber dieses Wissen wird rechtzeitig kommen, wenn du lange genug bei C ++ bleibst :)

0
hinzugefügt

Your problem seems to be the C core in C++, not C++ itself. Get yourself the Kernighan & Ritchie (The C Programming Language). Inhale it. It's very good stuff, one of the best programming language books ever written.

0
hinzugefügt

Im Fall von Klassen hatte ich drei Techniken, die mir wirklich dabei halfen, in eine echte objektorientierte Programmierung zu springen.

Das erste war, dass ich an einem Spielprojekt arbeitete, das Klassen und Objekte stark benutzte, mit starker Verallgemeinerung (Art oder ist eine Beziehung, zB Student ist eine Art Person) und Komposition (hat eine Beziehung, ex. Student hat ein Studentendarlehen). Es hat viel Arbeit gekostet, diesen Code zu durchbrechen, aber er hat die Dinge wirklich relativiert.

The second thing that helped was in my System Analysis class, where I had to make http://www.agilemodeling.com/artifacts/classDiagram.htm">UML class diagrams. These I just really found helped me understand the structure of classes in a program.

Schließlich helfe ich Tutoren Studenten an meiner Hochschule in der Programmierung. Alles, was ich dazu sagen kann, ist, dass du viel lernst, indem du lehrst und die Herangehensweise anderer Leute an ein Problem erkennst. Oftmals wird ein Student Dinge ausprobieren, an die ich nie gedacht hätte, die aber meistens sehr sinnvoll sind und nur Probleme bei der Umsetzung ihrer Idee haben.

Mein bester Ratschlag ist, dass es viel Übung braucht, und je mehr Sie programmieren, desto besser werden Sie es verstehen.

0
hinzugefügt