Zeiger
-
Wie warscheinlich jedem Newbie liegen mir Zeiger recht schwer im Magen. Habe mir in vielen tutorials schon das Tehma Zeiger angesehen, aber meist wird es (finde ich) viel zu kurz oder ohne "gute" Beispiele erklärt. Aber dann ist mir etwas in den Sinn gekommen, wäre nett wenn ihr mir einfach nur sagen könnt ob ich damit recht habe oder nicht. Sin Zeiger (und referenzen) dazu da um Lokale Varaiblen zu ändern? Und wenn ich damit recht habe ist das doch nicht die einzige Aufgabe eines Zeigers, oder? Könnt ihr ein "schön" formuliertes beispiel für eine Zeiger geben? Wäre auch gut wenn ihr es an hand eines Spieles erklärt, denn ich finde dort ist es meist am verständlichsten?!?
Und sollte ich tatsächlich recht mit meiner Idee haben. Wieso deklariert man die Variablen dann nicht gleich als Globale?Thx
-
stell dir mal folgendes vor
du schreibst command and conquer und hast nen array mit allen einheiten
+ einen zeiger der auf den general der einheiten zeigt.am anfang lässt du den generalzeiger auf die einheit mit der meisten erfahrung zeigen
falls die einheit stirbt setzt du den zeiger auf 0 oder lässt ihn auf eine andere einheit zeigenoder anderes beispiel
n panzer hat drei besatzungsmitglieder d.h. drei zeiger die auf infantrieeinheiten zeigen. wenn die besatzung aussteigt werden die zeiger auf 0 gesetzt wenn die besatzung einsteigt zeigen sie auf die eingestegenen einheitender punkt is hier, dass die einheiten wenn sie aus dem panzer aussteigen ja nicht sterben... sie haben nur keine verbindung zu dem panzer mehr
keine ahnung ob das verständlich war
nurn versuch
-
Schon nicht schlecht. Muss ich mir jede einheit in dem Panzer als Klasse vorstellen? Und der Zeiger zeigt auf diese Klasse?
-
Hier hab ich mal nen beispiel in dem es nur eine Zeiger gibt:
#include <iostream> using namespace std; int main() { int basis, size; cout<<"Welche Zahl soll als Basis dienen? "; cin>>basis; cout<<"Wieviele Zahlen sollen berechnet werden? "; cin>>size; int* reihe=new int[size]; reihe[0]=basis; int i; for(i=1;i<size;++i) { reihe[i]=reihe[i-1]*2; } for(i=size-1;i>=0;--i) { cout<<reihe[i]<<"\n"; } delete[] reihe; return 0; }
Das Programm gibt eine Zweierreihe aus!
Ich versteh jetzt nur nicht was ist hier der Zeiger, und wo drauf zeigt er. Und was hab ich davon das er darauf zeigt? Also eigentlich versteh ich ga rnichts *g*
-
Zeiger haben zwei Aufgaben: Sie sind einmal Iteratoren und sie sind auch Moniker.
// als Iterator: int feld[20]; for (int * iterator =feld; iterator < feld+20; ++iterator) { cout << *iterator << ' '; }
Als Moniker:
//Moniker class Person; class Motorad { public: Motorad () : fahrer(0) {} void aufsteigen (Person & person) { fahrer = &person; } void absteigen () { fahrer = 0; } private: Person * fahrer; };
Beide Beispiel, aber vor allem das letzte sind nciht gerade toll, gebe ich zu.
Zeiger setze ich direkt eigentlich gar nicht mehr bewusst ein. Nurnoch indirekt:
// Iterator boost::array<int, 20> feld; std::sort (feld.begin(), feld.end()); // hier werden Zeiger verwendet
Oder auch
// Moniker boost::shared_ptr<Foo> foo (new Foo); // intern werden Zeiger verwendet. ...
-
Frusciante schrieb:
Hier hab ich mal nen beispiel in dem es nur eine Zeiger gibt:
#include <iostream> using namespace std; int main() { int basis, size; cout<<"Welche Zahl soll als Basis dienen? "; cin>>basis; cout<<"Wieviele Zahlen sollen berechnet werden? "; cin>>size; int* reihe=new int[size]; reihe[0]=basis; int i; for(i=1;i<size;++i) { reihe[i]=reihe[i-1]*2; } for(i=size-1;i>=0;--i) { cout<<reihe[i]<<"\n"; } delete[] reihe; return 0; }
Das Programm gibt eine Zweierreihe aus!
Ich versteh jetzt nur nicht was ist hier der Zeiger, und wo drauf zeigt er. Und was hab ich davon das er darauf zeigt? Also eigentlich versteh ich ga rnichts *g*
@helium ich glaub damit verwirrst du ihn nur
@frusci
int* reihe=new int[size];
hier hast du nen neuen array mit ints erzeugt
normalerweise würdest du es wohl so machenint reihe[size]; wenn du dasselbe erreichen willst schreibst dus so int reihe[size];//deine variablen int *zeigAufReihe[size];//deine zeiger for(int i=0;i<size;i++) zeigAufReihe[i]=&reihe[i];//lass die zeiger auf die reihe zeigen
der unterschied in deinem beispiel is, dass du die "echten" variablen nicht "siehst"
sie sind irgendwo im arbeitsspeicher und die zeiger sagen dir woint* reihe=new int[size];//erzeug mir zeiger die auf unsichtbare variablen zeigen for(int i=0;i<size;i++) reihe[i]=0;//die unsichtbaren variablen sind noch da aber du weisst nicht wo ->speicherleck der wichtigste unterschied is folgender void func() { int zahl; int zahlzeiger=new int; }
beim verlassen der funktion wurde jetzt zahl gelöscht aber zahlzeiger is immernoch im speicher, du hast nur keine ahnung wo, weil deine info wo sich die unsichtbare mit new erzeugte zahl befindet auch gelöscht wurde
ein zeiger is an sich nur ein long mit ner adresse
class foo{}; class auto{}; class pferd{}; void func() { foo einfoo; auto einauto; pferd einpferd; long einzeiger=0; einzeiger=(long)&einfoo;//jetzt speichern wir wo im speicher unser foo is einzeiger=(long)&einauto;//jetzt speichern wir wo im speicher unser auto is einzeiger=(long)&einpferd;//jetzt speichern wir wo im speicher unser pferd is }
-
Ok danke, jetzt versteh ich das ganze schon mehr. Aber eins noch:
Dafür gibt es doch hunder protzentig eine andere Lösung, oder? Also was habe ich davon? Die Frage soll jetzt nicht so rüber kommen als wenn ich was gegen Pointer hätte. Aber wo liegen die Vorteile? Wie würde die Funktion ohne Pointer ausehen?
-
soldat allearmeeeinheiten[100]; soldat armeeeinheitenaufplanetblob[20]; soldat alphasquadeinheiten[5]; soldat jim; nehmen wir an soldat jim ist im alpha squad, alphasquad is im container der einheiten auf planet blob und gehört zum container alle einheiten also machen wirs mit normalen variablen allearmeeeinheiten[0]=jim; armeeeinheitenaufplanetblob[0]=jim; alphasquadeinheiten[0]=jim; jim stirbt also jim.dead(); allearmeeeinheiten[0].dead(); armeeeinheitenaufplanetblob[0].dead(); alphasquadeinheiten[0].dead(); machen wirs mit zeigern soldat *allearmeeeinheiten[100]; soldat *armeeeinheitenaufplanetblob[20]; soldat *alphasquadeinheiten[5]; soldat jim; allearmeeeinheiten[0]=&jim; armeeeinheitenaufplanetblob[0]=&jim; alphasquadeinheiten[0]=&jim; jim stirbt wieder jim.dead();
das wars... die container benutzen exakt den gleichen jim und wissen jetzt auch alle dasses ihn nimmer gibt
vielleicht is das jetzt ein bischen klarer... beliebig viele zeiger können an beliebig vielen stellen im code auf das selbe objekt zeigen
das is einer der wichtigen vorteile
-
Ansonsten braucht man Zeiger für Objekte aufm Heap und Zeiger od. Referenzen, um Variablen und nicht Werte zu übergeben, bsp:
void foo(int& left, int& right) //soll Werte der Variablen vertauschen { int temp = left; left = right; right = temp; }
hoffe das konnte dir helfen
mfg
-
Angenommen Ein Objekt soll eine Beziehung zu einem anderen Objekt haben. Wie stellst du das dar?
Um nochmal auf mein Beispiel zurückzukommen: Dort gibt es Personen und Motoräder. Auf einem Motorad kann gerade eine Person sitzen oder eben nicht.
Wie stellst du diese beziehung jetz dar? Du musst im Motorad Speichern, wer das Motorad gerade Fährt. Du kannst ja schlecht ein Objekt des Typs Person im Motorad speichern. Dann würde es ja nur eine Person geben, die das Motorad fahren kann und diese ist fest mit dem Motorad verbunden. Das geht also nicht. Du must irgendwie auf eine Person verweisen, die irgendwo anders gespeichert ist. Es kann aber immer wieder eine andere Person sein, die das Motorad fährt und es kann auch mal gar keiner draufsitzen.
Umd diese Beziehung darzustellen kommst du nicht um Zeiger herum.