C++ Zeiger



  • Hey, ich bin ja kein Anfänger in C++ mehr, aber eines habe ich noch nie kapiert: Zeiger..
    In Irrlicht brauch ich das ja anscheinend:

    IrrlichtDevice *device =
    #ifdef _IRR_OSX_PLATFORM_
    		createDevice( video::EDT_OPENGL, dimension2d<s32>(640, 480), 16,
    			false, false, false, 0);
    #else
    		createDevice( video::EDT_SOFTWARE, dimension2d<s32>(640, 480), 16,
    			false, false, false, 0);
    #endif
    	if (!device)
    		return 1;
    

    Aber was machen Zeiger jetzt genau? Im Internet gibt es zwar haufenweise Tuts, aber alle in so einer Fachsprache, dass ich das nicht versteh.. Haben Zeiger einfach nur den gleichen Inhalt, als die Variable auf die sie zeigen?
    Hier bei Irrlicht muss die Zeigervariable ja 1 betragen, aber warum?

    Kann mir einer von euch in normalen Worten ausdrücken was eine Zeigervariable macht und wie man sie Anwendet?
    Danke schon mal im Voraus,
    mfg
    Schoasch


  • Administrator

    Schoasch schrieb:

    Hier bei Irrlicht muss die Zeigervariable ja 1 betragen, aber warum?

    Nein, es wird geprüft, ob der Zeiger ein Nullzeiger ist, danach wird 1 zurückgegeben. Denn operator ! angewendet auf einen Nullzeiger gibt 1. operator ! angewendet auf irgendeine Zahl ausser 0, gibt 0.

    Schoasch schrieb:

    Kann mir einer von euch in normalen Worten ausdrücken was eine Zeigervariable macht und wie man sie Anwendet?

    Das sind aber absolute Anfänger Grundlagen 😉
    Ein Zeiger ist grundsätzlich nichts anderes, als eine Speicheradresse eines Objektes eines bestimmten Types. Punkt.
    In der Zeigervariable wird somit die Adresse des Objektes gespeichert.
    Beim Dereferenzieren wird auf das Objekt an der entsprechenden Adresse zugegriffen.

    Sonstige Fragen zu Zeiger?

    Grüssli



  • Ein Zeiger speichert die Adresse einer Variable!

    int variable = 3;        //Initialisierung einer Variable...
    int* zeiger = &variable; //Einen Zeiger definieren der auf die Adresse von "variable" zeigt...
    
    *zeiger = 5;            //Mit dem *-Operator beziehen wir uns jetzt auf das Objekt, auf das gezeigt wird...
    // und ändern die Variable "variable" in 5...
    

    Zeiger spielen aber eine wichtige Rolle bei Funktionen. Da sie dort den übergebenen Wert ändern können.

    Hoffe ich konnte dir es einiger Maßen erklären!

    Lg Mentras



  • Du möchtest es anschaulich haben. Kannst Du kriegen!
    Stelle Dir einen Schrank mit drei Schubladen vor, in denen sich folgende Dinge befinden: Oben - Pullover / Mitte - Hosen / Unten - Socken. Die Imhalte der Schubladen sind die Variable. Ein Zeiger zeigt auf die Schublade, in der sich etwas konkretes befindet. Hat der Zeiger den Wert Oben findest Du in der gezeigten Schublade die Pullover. Verstanden?



  • Schoasch schrieb:

    Hey, ich bin ja kein Anfänger in C++ mehr, aber eines habe ich noch nie kapiert: Zeiger..

    Das meinst du nicht ernst oder? 🙄 😮



  • Teufelsbraten schrieb:

    Schoasch schrieb:

    Hey, ich bin ja kein Anfänger in C++ mehr, aber eines habe ich noch nie kapiert: Zeiger..

    Das meinst du nicht ernst oder? 🙄 😮

    Nur weil du´s verstanden hast, musst du nicht auf andere runtergucken und eine blöde Bemerkung abliefern. Das Kapitel Zeiger ist etwas komplex. Die meisten Neulinge stellen sich die Frage wozu es die überhaupt gibt.

    Ein gutes Beispiel und schon verstehen sie es.



  • Mentras schrieb:

    Zeiger spielen aber eine wichtige Rolle bei Funktionen. Da sie dort den übergebenen Wert ändern können.

    Als Ergänzung: das nennt man dann call-by-reference, im Gegensatz zur reinen Wert- bzw. Kopie-Übergabe call-by-value (nach diesen Stichwörtern lässt sich ggf. besser suchen). 🙂

    EDIT: Und zum Thema Zeiger haben wir hier doch was Schönes zum Lesen:

    http://magazin.c-plusplus.net/artikel/Pointer in C(PlusPlus)



  • Mentras schrieb:

    Zeiger spielen aber eine wichtige Rolle bei Funktionen. Da sie dort den übergebenen Wert ändern können.

    Naja, bei Funktionsübergaben können Zeiger oft durch Referenzen ersetzt werden. Ein meiner Ansicht nach wichtigerer Anwendungsbereich ist die manuelle Speicherverwaltung über new und delete . Auch Polymorphie erfordert oft Zeiger. Oder simple Verweise, die ungültig sein können oder sich während der Lebenszeit ändern. Oder...

    Mentras schrieb:

    Nur weil du´s verstanden hast, musst du nicht auf andere runtergucken und eine blöde Bemerkung abliefern. Das Kapitel Zeiger ist etwas komplex. Die meisten Neulinge stellen sich die Frage wozu es die überhaupt gibt.

    Eben, Neulinge. 😉



  • Hey, danke für eure Antworten 🙂
    Das mit den Zeigern hab ich jetzt verstanden aber das:

    Hier bei Irrlicht muss die Zeigervariable ja 1 betragen, aber warum?

    Nein, es wird geprüft, ob der Zeiger ein Nullzeiger ist, danach wird 1 zurückgegeben. Denn operator ! angewendet auf einen Nullzeiger gibt 1. operator ! angewendet auf irgendeine Zahl ausser 0, gibt 0.

    .. noch nicht ganz.
    Als Beispiel:

    IrrlichtDevice *device =createDevice(video::EDT_SOFTWARE,dimension2d<s32>(640, 480), 16,false, false, false, 0);
    

    Hier ist ja *device die Zeigervariable. Da sie aber auf CreateDevice() zeigt, ist es kein Nullzeiger oder?
    Wenn der Befehl (createDevice()) aber nicht ausgeführt werden konnte, dann wird 0 zurückgegeben, und daher ist die variable ein Nullzeiger, richtig?
    Und durch...

    if (!device)
    		return 1;
    

    ...wird dann geprüft ob device 0 ist. Bitte korrigiert mich wenn ich das falsch verstanden habe. Btw. warum ist im letzten code der if() Befehl ohne {} Klammern?

    Und dann noch ne Kleinigkeit..

    int* zeiger = &variable; //Einen Zeiger definieren der auf die Adresse von "variable" zeigt...
    

    Warum ist vor "variable" so ein & Zeichen?

    mfg
    Schoasch



  • [quote="Schoasch"]Hey, danke für eure Antworten 🙂
    Das mit den Zeigern hab ich jetzt verstanden aber das:

    Hier bei Irrlicht muss die Zeigervariable ja 1 betragen, aber warum?

    Und dann noch ne Kleinigkeit..

    int* zeiger = &variable; //Einen Zeiger definieren der auf die Adresse von "variable" zeigt...
    

    Warum ist vor "variable" so ein & Zeichen?

    mfg
    Schoasch

    Das ist der &-Adressoperator, also die Speicheradresse...


  • Administrator

    @Schoasch,
    Ehm, ich dachte du seist kein Anfänger? Weisst aber nicht was Zeiger sind, Adressoperator, Funktionen oder eine if Anweisung ohne geschweifte Klammern. Tut mir Leid, wenn ich da ein wenig schmunzeln muss und das Lachen nur knapp unterdrücken kann 🙂
    Also ist wirklich nicht böse gemeint, aber damit bist du in meinen Augen definitiv immer noch ein Anfänger 😉

    Schoasch schrieb:

    IrrlichtDevice *device =createDevice(video::EDT_SOFTWARE,dimension2d<s32>(640, 480), 16,false, false, false, 0);
    

    Hier ist ja *device die Zeigervariable. Da sie aber auf CreateDevice() zeigt, ist es kein Nullzeiger oder?

    Nein, createDevice ist eine Funktion, welche einen Zeiger auf ein IrrlichtDevice Objekt zurückgibt. device ist somit ein Zeiger auf ein IrrlichtDevice Objekt.

    Schoasch schrieb:

    Wenn der Befehl (createDevice()) aber nicht ausgeführt werden konnte, dann wird 0 zurückgegeben, und daher ist die variable ein Nullzeiger, richtig?

    Auch wieder falsch. Es geht wahrscheinlich darum, wenn die Funktion das IrrlichtDevice Objekt nicht erstellen konnte, dann wird ein Nullzeiger zurückgegeben. Das ist also ein Fehlerfall. Die Funktion wird immer ausgeführt.

    Schoasch schrieb:

    Und durch...

    if (!device)
    		return 1;
    

    ...wird dann geprüft ob device 0 ist.

    Das ist richtig. Wobei ich nicht 0 sagen würde, sondern Nullzeiger. Ist einfach klarer, was man meint 😉

    Schoasch schrieb:

    Btw. warum ist im letzten code der if() Befehl ohne {} Klammern?

    Weil dies möglich ist, da die Anweisung bis zum nächsten Semikolon gilt. Ein wenig anschaulicher dargestellt:

    if(!device) return 1;
    

    Nur wenn man einen Block an Befehlen ausführen lassen will, braucht man geschweifte Klammern. Allerdings nehme ich sogar für eine einzelne Anweisung bei einer if-Anweisung geschweifte Klammer, um die Übersicht zu verbessern.

    Schoasch schrieb:

    Warum ist vor "variable" so ein & Zeichen?

    Dies ist der Address-Of Operator. Er holt die Adresse, also den Zeiger, der entsprechenden Variable.

    Grüssli



  • Schoasch schrieb:

    IrrlichtDevice *device =createDevice(video::EDT_SOFTWARE,dimension2d<s32>(640, 480), 16,false, false, false, 0);
    

    Hier ist ja *device die Zeigervariable. Da sie aber auf CreateDevice() zeigt, ist es kein Nullzeiger oder?
    Wenn der Befehl (createDevice()) aber nicht ausgeführt werden konnte, dann wird 0 zurückgegeben, und daher ist die variable ein Nullzeiger, richtig?

    CreateDevice gibt einfach einen Zeiger zurück. Das kann ein gültiger Zeiger (respektive ein Zeiger, der auf ein Objekt zeigt), oder einer, der nicht gültig ist, was dann einfach 0 ist. (Beachte hier aber, dass es nicht so etwas, wie NULL ist, wie in anderen Sprachen, sondern einfach ein gültiger Wert, der einfach anderst interpretiert werden muss). CreateDevice wird auf jeden Fall "richtig" ausgeführt, kann aber unter Umständen 0 zurückgeben (ich gehe jetzt einfach mal davon aus, dass das so ist..) , was signalisieren soll, dass ein Fehler passiert ist.

    Und durch...

    if (!device)
    		return 1;
    

    ...wird dann geprüft ob device 0 ist. Bitte korrigiert mich wenn ich das falsch verstanden habe. Btw. warum ist im letzten code der if() Befehl ohne {} Klammern?

    if () ruft immer nur den nächsten Block an Code auf, was entweder eine Zeile ist, oder eine Sammlung von Anweisungen, wass durch die Klammern gemacht wird.

    Und dann noch ne Kleinigkeit..

    int* zeiger = &variable; //Einen Zeiger definieren der auf die Adresse von "variable" zeigt...
    

    Warum ist vor "variable" so ein & Zeichen?

    mfg
    Schoasch

    & ist ein Operator, welcher dir im Normalfall die Addresse der Variable zurückgibt. Jedoch lässt sich dieser Operator, wie die meisten auch überladen und könnte etwas anderes tun, als die Addresse zurückzugeben. (z.B bei einem Smart Pointer)

    EDIT:
    Mist.. Das waren ja 2 Seiten.. -.-



  • Hey, danke für eure Antworten 🙂

    Den & Operator braucht man aber außer bei Zeigern nicht, oder?

    CreateDevice gibt einfach einen Zeiger zurück. Das kann ein gültiger Zeiger (respektive ein Zeiger, der auf ein Objekt zeigt), oder einer, der nicht gültig ist, was dann einfach 0 ist. (Beachte hier aber, dass es nicht so etwas, wie NULL ist, wie in anderen Sprachen, sondern einfach ein gültiger Wert, der einfach anderst interpretiert werden muss). CreateDevice wird auf jeden Fall "richtig" ausgeführt, kann aber unter Umständen 0 zurückgeben (ich gehe jetzt einfach mal davon aus, dass das so ist..) , was signalisieren soll, dass ein Fehler passiert ist.

    Ist IrrlichtDevice denn vergleichbar mit Variablentypen? Denn der Zeiger wurde ja vorher nicht definiert (z.B. als int).
    Und hier beim nächsten Code:

    device->setWindowCaption(L"Hello World! - Irrlicht Engine Demo");
    

    steht device->... was heißt das?
    Sry für meine blöden Fragen , aber ich als ehemaliger BB prorammierer, komme von dem alten Prinzip nur schwer los, da sagt man zum Beispiel: mesh = LoadMesh(), wobei mesh eine Variable ist und den Wert von LoadMesh zurückliefert..
    mfg
    Schoasch



  • Üblicherweise wird der &-Operator lediglich in Zusammenhang mit Zeigern gebraucht ja.

    Doch device wird deklariert:

    IrrlichtDevice *device =createDevice(video::EDT_SOFTWARE,dimension2d<s32>(640, 480), 16,false, false, false, 0);
    

    und ist vom Typ IrrlichtDevice, was eine Klasse ist.



  • Danke für deine Antwort 🙂

    Aber wird durch device-> einfach nur ein weiterer Wert über den Zeiger an die Klasse IrrlichtDevice übergeben?

    mfg
    Schoasch



  • IrrlichtDevice *device = createDevice( ... );
    

    device ist ein Zeiger auf ein Irrlicht-Objekt.
    *device ist das Objekt hinter dem Zeiger.

    device->doSomething();
    

    ist kurz für

    (*device).doSomething();
    

    und das solltest du ja kennen.

    Und schaff dir bitte ein ordentliches Grundlagenbuch an. Wenn du aus den paar Kommentaren schlau geworden bist, sagt das nix gutes über dein Buch (oder deine non-digitalen Lesefähigkeiten ;)) aus.


  • Administrator

    Schoasch schrieb:

    Den & Operator braucht man aber außer bei Zeigern nicht, oder?

    Doch.

    int x = 2342;
    int y = x & 1; // Bitwise AND
    
    int& r = x; // Reference
    
    int* p = &x; // Address-Of
    

    Schoasch schrieb:

    Ist IrrlichtDevice denn vergleichbar mit Variablentypen? Denn der Zeiger wurde ja vorher nicht definiert (z.B. als int).

    IrrlichtDevice ist eine Klasse, welche irgendwo definiert wurde.
    IrrlichtDevice* (der zusätzliche Stern) bedeutet, dass man einen Zeiger auf ein IrrlichtDevice Objekt möchte.
    IrrlichtDevice** bedeutet, dass man einen Zeiger auf einen Zeiger auf ein IrrlichtDevice Objekt möchte.
    IrrlichtDevice*** bedeutet, dass man einen Zeiger auf einen Zeiger auf einen Zeiger usw. 😉

    Schoasch schrieb:

    device->setWindowCaption(L"Hello World! - Irrlicht Engine Demo");
    

    steht device->... was heißt das?

    Das ist der operator -> . Erbedeutet das gleiche wie:
    (*device).
    Also das Objekt wird dereferenziert und danach wird auf ein entsprechendes Element des Objekts zugegriffen. In diesem Fall ist es die setWindowCaption Funktion.

    Aber ganz ehrlich, das sind absolute Grundlagen. Das findest du in jedem vernünftigen Grundlagenbuch. Es gibt wirklich genügend Lektüre ...

    Grüssli



  • Danke für eure Antworten 🙂

    Aber was bringt sich das wenn man sagt IrrlichtDevice *device = CreateDevice()?
    Viel einfacher wäre es doch zu schrieben IrrlichtDevice.CreateDevice();
    Denn CreateDevice ist doch eine Funktion von der Klasse IrrlichtDevice, und gibt daher auch einen Wert zurück, mit dem man dann überprüfen kann, ob CreateDevice() erfolgreich ausgeführt wurde.
    Macht man die Zeigervariable nur aus Faulheitsgründen, um nicht immer z.B. IrrlichtDevice.setWindowCaption(), sonder nur (*device).setWindowCaption() schreiben zu müssen?

    mfg
    Schoasch


  • Administrator

    Schoasch schrieb:

    Denn CreateDevice ist doch eine Funktion von der Klasse IrrlichtDevice, ...

    HALLOOOO?
    Tipp: Lern zuerst mal C++ ...

    Es tut mir leid, aber darauf fällt mir echt nichts anderes mehr ein. Du weisst anscheinend nicht einmal was eine freie Funktion ist. Kauf dir ein gutes C++ Buch, dort wirst du dann auch in aller Ruhe mit C++ Zeiger vertraut gemacht. Oft werden hier die folgenden zwei Bücher empfohlen:
    - C++ Primer
    - Thinking in C++ 1&2 (auch gratis als PDF erhältlich, nur Englisch)

    Alles andere scheint mir echt sinnlos zu sein. Dir fehlen anscheinend jegliche Art von Grundlagen, was C++ betrifft. Anderst kann ich mir deine Aussagen einfach nicht mehr erklären.

    Grüssli



  • Du weisst anscheinend nicht einmal was eine freie Funktion ist.

    Also das brauchst du mir jetzt aber wirklich nicht vorzuwerfen, zumal ich schon viele Programmiersprachen beherrsche und das selbst in C++ gut beherrsche.

    Nur weil ich mich bei diesem Bereich nicht auskenne lass ich mich nicht beleidigen. Außedem besitze ich den C++ Primer, der ist mir aber bei den meisten Stellen zu ausführlich, und das Kapitel der Zeiger habe ich gelesen, wegen den vielen Fachbegriffen aber nicht verstanden (...und nein, ich will jetzt keine dummen Anmachsprüche).

    mfg
    Schoasch


Anmelden zum Antworten