¿¿¿¿ Zeiger ¿¿¿¿
-
hallo. kann mir mal einer erklären wozu nun pointer also zeiger wirklich gut sind? ich denke zwar das ich die philosophie von zeigern verstehe, den einsatz jedoch nicht wirklich. soviel ich weiss man ein zeiger sowohl auf dem heap wie auch auf dem stack liegen. ein zeiger ist grundsätzlich eine adresse auf einen speicherbereich im arbeitsspeicher. heist also, ein objekt bzw. eine adresse das auf ein bestimmtes objekt oder variable im speicher zeigt. mal angenommen wir vergleichen das in der wirklichkeit:
ich bin der thomas. neben mir steht andrea. diese weiss bislang noch nicht das es an der kukuksstrasse eine tolle bar gibt. ich gebe ihr also einen zettel in die hand wodrauf die adresse dieser tollen bar steht. auf misteriöse weise löse ich mich dann plötzlich in luft auf, aber gut das ich andrea den zettel mit der adresse gegeben habe. sie weis nun wo die bar ist.
geht das so?

also ich verstehe nicht wirklich warum ich z.b. einen zeiger auf ein objekt haben muss das z.b. auf dem stack angelegt wurde. man könnte ja theoretisch alles mit globalen variablen machen wenn es um den zugriff geht. das einzigste wo ich mir zeiger vorstellen kann und es auch sinn(?) macht, ist, bei dynamisch erzeugten objekten, da es dort die syntax ja eigentlich sowieso nicht anderst zulässt oder irre ich mich? ich hoffe es kann mir endlich mal einer genau erklären wozu man zeiger anwendet, was ohne zeiger nicht gehen würde, etc. etc.
-
-
Hallo
Wenn du Werte an Funktionen übergibts, werden diese kopiert und nun eventuell verändert. Wenn du diese nun aber nicht zurück gibts, hat sich in deinem "Hauptprogramm" der Wert nicht verändert. Wenn du nun aber die Adresse übergibts, kannst du den Wert in der Adresse manipulieren.
Funktionen erlauben immer nur einen Rückgabewert. Wenn du aber Zeiger als Paraneter übergibst, dann kannst du belibig viele Werte in der Funktion verändern.
Bei grossen Objekten ist es sinnvoll Zeiger zu übergeben (oder Referenzen), weil dies schneller geht.
Ich hoffe, dass soweit alles richtig war.
chrische
-
Programmier einfach drauf los. Du wirst schon merken wenn du sie brauchst.
-
Programmier einfach drauf los
das ist eben nicht mein stil
ich beschäftige mich auch mit dem hintergrund.
aber das mit kopie und nicht kopie macht sinn. das wusste ich nicht, sowas rückt gleich etwas mehr licht ins dunkle! danke
-
Hallo
frickler schrieb:
Programmier einfach drauf los. Du wirst schon merken wenn du sie brauchst.
Halte ich auch nicht immer für das Beste.
chrische
-
chrische5 schrieb:
Hallo
frickler schrieb:
Programmier einfach drauf los. Du wirst schon merken wenn du sie brauchst.
Halte ich auch nicht immer für das Beste.
chrische
Wieso? So kann man selber Erfahrung sameln und weiß wann man sie einsetzen muss.
-
Hallo
alex89ru schrieb:
chrische5 schrieb:
Hallo
frickler schrieb:
Programmier einfach drauf los. Du wirst schon merken wenn du sie brauchst.
Halte ich auch nicht immer für das Beste.
chrische
Wieso? So kann man selber Erfahrung sameln und weiß wann man sie einsetzen muss.
Praxis ist wirklich wichtig, aber was ist denn verkehrt daran vorher etwas Theorie zum Thema zu hören. Wenn man gar nicht weiß, wie, wo und wann man etwas einsetzen kann, ist es mit der Praxis auch nicht weit her. Bei den wenigen Anregungen zu diesem komplexen Thema bleibt ja wohl noch genug Platz zum Probieren.
chrische
-
In der OOP kann man sowas öfter gebrauchen. Wenn du eine abstrakte Klasse hast und auch nur von dieser Objekte erzeugen kannst (z.B. bei einer Liste (Schnittstelle) die durch 2 Unterklassen (repräsentation einer leeren und nicht-leeren Liste) implementiert ist) würde man auch einen Pointer benötigen. Durch eine Fabrik-Methode erzeugt man dann erstmal eine leere Liste und kann durch verschiedene Operationen erreichen eine nicht-leere Liste zu haben. Man arbeitet aber immer mit einem Zeiger auf List.
Mach mal OOP, da wirst du einige Entwurfsmuster kennenlernen, bei denen du sicher irgendwo mal auf einen Pointer zurückgreifen wirst. Aber ich kann frickler und alex89ru nur zustimmen. Einfach mal drauf losprogrammieren. Wenn keine Ideen da sind, benutz google oder guck hier im Forum oder bei Unis und FHs. Da findest du immer irgendwo Aufgabenstellungen.
Netter Merksatz:
"Programmiere auf eine Schnittstelle hin, nicht auf eine Implementierung."
(und wenn man mit abstrakten Klassen arbeiten muss, welche als Schnittstelle zur Implementierung dienen, wird man nicht selten auf Zeiger stoßen)
-
nochmal kurz zur begrifflichkeit
Funktionsaufrufe mit kopierten objekt nennen sich call-by-value.
Funktionsaufrufe mit einem Pointer/Reference nennen sich call-by-refence.in c++ hast du aber 2 möglichkeiten einen call-by-refence zu implenetieren. zum einen über einen pointer(c) oder du könntest eine reference(c++) benutzen.
void funktion( int a ); //call by value
void funktion( int* a ); //call by reference
void funktion( int &a ); //call by referencetip: versuche immer mit call by reference zu arbeiten weil dieses meistens schneller ist..macht natürlich nur bei etwas größeren objekten wirklich etwas aus..oder wenn zb. das ursprügliche objekt nicht verändert werden soll.
außerdem läuftst du dann nicht gefahr mit dem "slicing-problem" konfrontiert zu werden.
wenn du nämlich ein abgeleitet objekt in einer basisklasse umwandelst gehen die "zusatz infos" verloren
-
also damit ich das nun richtig verstehe, anbei ein beispiel. beachtet bitte meine kommentare. diese drücken aus, wie ich das ganze interpretiere....
//--------------------------------------------------------------------------- #include <iostream.h> #include <conio.h> #pragma hdrstop #pragma argsused //--------------------------------------------------------------------------- void ExchangeWithoutRef(int number1, int number2) //erhält eine kopie von a und b { int temp = number1; //lokale variable temp wird der wert von a als kopie zugewiesen number1 = number2; //lokale variable number1 wird der wert von b als kopie zugewiesen number2 = temp; //lokale variable number2 wird der wert von temp zugewiesen } //--------------------------------------------------------------------------- void ExchangeWithRef(int *number1, int *number2) //als parameter werden zwei zeiger erwartet. //heisst also, der funktion werden später die speicheradressen übergeben. keine kopie von a und b. { int temp = *number1; //weisst temp den wert von der speicheradresse a zu. adresszuweisung wäre &number1 *number1 = *number2; //weisst den wert der speicheradresse (b) nun dem wert der speicheradresse (a) zu. *number2 = temp; //weisst den wert der lokalen variable temp nun an den wert der speicheradresse (b) zu. } //--------------------------------------------------------------------------- int main(int argc, char* argv[]) { int a = 10; //lokale variable a int b = 20; //lokale variable b ExchangeWithoutRef(a, b); //aufruf der funktion. a und b wird als kopie übergeben cout << a << " " << b << endl; ExchangeWithRef(&a, &b); //aufruf der funktion. a und b wird als referenz (adresse) übergeben. //a und b werden dadurch also direkt im speicher manipuliert. cout << a << " " << b << endl; getch(); return 0; } //---------------------------------------------------------------------------
-
ja, sieht doch alles schonmal ganz gut aus.
vergiss aber nicht das in deiner ersten funktion ExchangeWithoutRef(int number1, int number2) zwar in der funktion die werte getauscht werden aber dieses nach aussen hin nicht sichtbar ist.
also wenn du zb.
int a = 10, b= 20;ExchangeWithoutRef( a, b);
steht in a immer noch 10 und in b immer noch 20.
beim der 2ten funktion werden die sachen wirklich getauscht. bzw es ist auch außerhalb der funktion sichbar.
-
das ist mir schon klar deswegen hab ich ja extra ein beispiel gemacht
damit ich zugleich auch den sin von referenzen als parameter übergabe verstehe. wirklich eine tolle sache was man da alles lernt. 
eine kleine frage noch bezüglich referenzieren und dereferenzieren.
a) war das gerade richtig geschrieben? also referenzieren / dereferenzieren

b) wenn man von referenzieren spricht, meint man, das ein zeiger auf etwas zeigt?
c) wenn man von dereferenzieren spricht, meint man, das dem zeiger etwas zugewiesen wird?
-
also unter referenzieren verstehst du in meinen augen das richtige...eine referenz auf ein objekt.
als dereferenzierung würde ich das aufheben einer soclen referenz bezeichnen bzw. das löschen/entfernen einer referenz.noch mal kur die möglichkeit des referenzierens des objekts in c++
void ExchangeWithRef( int &a, int &b){ int temp; temp = a; a = b; b = temp }dann könntest du den aufruf so gestalten
int i =10, j = 23; ExchangeWithRef( i, j ); //i==23, j==10ich finde das so etwas angenehmer als mit pointern

-
Geh komm. Wie soll den da einer wissen was gemeint ist eimal ein '&' dann wieder nix.
So ist da wenigstens immer ein Sternderl.void ExchangeWithPtr( int *a, int *b){ int temp; temp = *a; *a = *b; *b = temp }Kurt

-
komisch. genau aus sollchen sachen finde ich die welt der zeiger verwirrend. dein beispiel sieht für mich so aus, als würdest du eine kopie als parameter übergeben.
ExchangeWithRef( i, j );
*bahnhof*..
desweiteren eine verständigungsfrage: der & operator = adresse des objekts. der * operator (je nach syntax) wert des objekt auf das es zeigt. richtig? eine referenz ist grundsätzlich ein alias eines objektes, auch richtig? sprich, angenommen ich habe ein objekt name und als referenz habe ich davon dann name1, name2, name3. wenn sich der wert von name ändert ist auch name1, name2, name3 dementsprechend oder?
dann verstehe ich jedoch den unterschied zwischen referenzen und zeiger nicht wirklich. ein zeiger ist ja eine adresse eines speicherbereichs das auf ein objekt zeigt. aber eine referenz ja dann eigentlich genauso..

-
Jetzt hast es kapiert. Eine Referenz ist eigentlich nix anderes als ein Zeiger. ( der einzige Unterschied ist dass eine Referenz immer mit einem object initialisiert werden muss daher wirds ein bissl schwieriger eine ungültige Referenz zu erzeugen ) der Rest ist nur syntax.
Kurtkomisch. genau aus sollchen sachen finde ich die welt der zeiger verwirrend. dein beispiel sieht für mich so aus, als würdest du eine kopie als parameter übergeben.
Es sieht nicht nur so aus es wird auch eine kopie übergeben. Nur zeigt eben die Kopie und das Original auf das selbe object.
-
also sowas dann?
int a = 25; //lokale variable mit 25 initialisieren int *b = &a; //zeiger auf int. adresse von a, b zuweisen (referenzieren). b zeigt nun auf a. *b = 10; // b ist eine referenz von a. b und a haben nun den wert 10.das ist aber schon recht verwirrend wenn zeiger und referenzen "eigentlich" das gleiche sind. naja mal schauen. lese gerade ein zweites buch. ist es normal das man sich anfangs zwar die logik und den sinn merken kann die fachbegriffe jedoch nicht? wie z.b. eben das referenzieren/dereferenziren etc.
variablen sind z.b. auch objekte oder? char abc. abc wäre ein objekt vom typ char oder falsch? bei klassen ist ein objekt nichts anderes als eine instanz der klasse? class MyClass .... MyClass xyz; .... xyz ist das objekt der klasse MyClass. Also eine instanz. man spricht auch von instantiieren oder so?
allozieren wäre das dynamische speicheranfordern mit dem new operator, ja?
-
int a = 25; //lokale variable mit 25 initialisieren int *b = &a; //zeiger auf int. adresse von a, b zuweisen (referenzieren). b zeigt nun auf a. *b = 10; // b ist eine referenz von a. b und a haben nun den wert 10. int & c = a; // c ist jetzt eien referenz auf a; c = 20; // c ist eine referenz auf a. c, *b und a haben nun den wert 20. // verhaltet sich ganz gleich syntax ist etwas anders.Kurt
-
@Zeiger: stimmt doch so ziemlich alles was du sagst

man darf den adress operator & nicht mit dem reference & operator verwechseln!