¿¿¿¿ Zeiger ¿¿¿¿
-
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!
-
jetzt ists klar, danke!
