1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

[C++] Stacks?

Discussion in 'Fragen & Antworten' started by Dendox, Oct 4, 2014.

Thread Status:
Not open for further replies.
  1. Dendox

    Dendox New Member

    Joined:
    Jan 17, 2014
    Messages:
    38
    Likes Received:
    0
    Hallo,
    ich arbeite ja grad das Buch "C++ für Spieleprogrammierer" von Kalista ab und bin mittlerweile bei Kapitel 6 (Zeiger und Referenzen) angelangt, dort komme ich aber überhaupt nicht klar. Video- und Texttutorials auf Deutsch habe ich nirgendwo im Internet gefunden. Kann mir vielleicht jemand ne kurze Erklärung liefern?
    Hier der Abschnitt aus dem Buch (ich weis dass das reinstellen nicht erlaubt ist, aber ich denke 2 Seiten sollten jetzt kein Problem sein...)
    http://puu.sh/bZkMd/82339edc34.png
    http://puu.sh/bZkNz/686905bd9e.png
    http://puu.sh/bZkOO/7ee4826bde.png
    http://puu.sh/bZkQm/cbd07d8cf7.png

    Vielleicht hat ja auch jemand so viel Zeit und Lust und könnte mir ab und zu mal in Skype ein paar Fragen beantworten falls ich am lernen bin? ^^

    MfG
     
  2. Cre3per

    Cre3per Member

    Joined:
    Oct 22, 2012
    Messages:
    764
    Likes Received:
    2
    Seite 1
    Stell dir vor, dass du eine Funktion haben willst die dir zwei Zahlen addiert UND subtrahiert. Jetzt könntest du eine Klasse schreiben die zwei Werte speichert oder es mit arrays regeln. z.B:

    class ZweiZahlen
    {
    int iZahl1, iZahl2;
    };

    ZweiZahlen Rechne(int a, int b)
    {
    ZweiZahlen ergebniss;
    ergebniss.iZahl1 = a - b;
    ergebniss.iZahl2 = a + b;
    return ergebniss
    }

    ZweiZahlen apfel = Rechne(3, 4);
    std::cout << apfel.iZahl1 << apfel.iZahl2;

    sry für schreckliche Formatierung, bin am Handy.
    Das würde so zwar funktionieren, wird aber sehr unordenlich wenn du viele verschiedene Dinge zurückgeben willst. Also kannst du das gleiche mit Pointern erreichen.

    void Rechne(int a, int b, int* pRaus1, int* pRaus2)
    {
    *pRaus1 = a - b;
    *pRaus2 = a + b;
    }

    int banane, kuchen;
    Rechne(3, 4, &banane, &kuchen);
    std::cout << banane << kuchen;

    Das & vor einer Variable heißt, dass du die Adresse von diesem Wert haben willst. Also ist
    &banane meinetwegen 0x492A8B. Und wenn du jetzt daraus wieder den Wert machen willst schreibst du einfach ein * davor. Bsp:
    int a = 5;
    int* b = &a; //Das sternchen heiß, dass es ein pointer ist
    *b = 1;
    std::cout << a;

    Die Ausgabe ist 1


    Sowas geht nicht
    int a = 3;
    int* b = &a;
    b = 5;

    weil b eine Adresse in deinem Ram ist. zB 0x100
    Davor steht 0x9F und dannach 0x100 also da ist logischerweise alles in einer festen reihenfolge. Das ist so als würdest du sagen, dass dein haus jetzt die 40 hat. Geht nicht.
     
  3. Dendox

    Dendox New Member

    Joined:
    Jan 17, 2014
    Messages:
    38
    Likes Received:
    0
    Deine Codebeispiele habe ich nicht zu 100% verstanden, das liegt wohl daran, dass ich Klassen noch nicht behandelt habe und mir manche Zeichenketten noch nicht bekannt sind. Aber ich habe jetzt immerhin den Sinn von Zeigern verstanden, danke ;)
     
  4. krusty

    krusty New Member

    Joined:
    Sep 8, 2012
    Messages:
    182
    Likes Received:
    0
    Das ganze hat eher indirekt was mit Stacks zu tun.
    Der Speicher besteht aus Adressen. Jede Adresse adressiert ein Byte.
    Jede Variable, die du deklarierst, besitzt eine Adresse, an der der Wert der Variablen liegt.
    Legen wir eine Variable an:
    Code:
    int i = 12;
    Lassen wir uns die Adresse ausgeben, an der der Wert der Variablen liegt. Dazu verwenden wir den Adressoperator, das kaufmännische und (&):
    Code:
    cout << &i;
    Du kennst ja schon einige Datentypen, int, char, float, string, jeder Datentyp besitzt einen bestimmten Wertebereich. In String speichert man Texte, im Int zeichnet man Ganzzahlen. C++ kennt auch einen Datentyp für Adressen, dazu setzt man einen Stern hinter den Datentyp, von dem man einen Zeiger erstellen will:
    Code:
    int *i_zeiger;
    Um dem Zeiger jetzt eine Adresse zuzuweisen:
    Code:
    i_zeiger = &i;
    Lassen wir uns die Adresse ausgeben:
    Code:
    cout << i_zeiger;
    Oftmals hat man einen Zeiger auf eine Variable und möchte auf den Inhalt der Variable zugreifen. Dazu verwendet man den Dereferenzierungsoperator, den Stern.
    Dereferenzieren bedeutet: die Adresse "auflösen":
    Code:
    cout << *i_zeiger
    Durch den Stern wird der Inhalt ausgelesen, der an der Adresse liegt, die in i_zeiger gespeichert ist.

    Wozu braucht man das jetzt ?
    Da du den Stack ansprichst:
    der Stack ist ein Speicherbereich, auf dem Parameter und Variablen abgelegt werden. Immer wenn du eine Funktion aufrufst, werden die Parameter der Funktion auf dem Stack abgelegt,
    also wenn du z.B. die folgende Funktion hast:
    Code:
    int addAll(int a, int b, int c){
    return a+b+c;
    }
    und in deinem Programm die Funktion aufrufst:
    cout << addAll(10,20,30);
    Dann läuft im Hintergrund folgendes ab:
    Code:
    Lege 30 auf den Stack
    Lege 20 auf den Stack
    Lege 10 auf den Stack
    Spring in die Funktion addAll
    Addiere die Zahlen
    Lege Ergebnis in ein Register
    Springe zurück
    Stell dir mal vor dein Programm soll jetzt zwei große Bilder vergleichen, die beide 100MB groß sind:
    void calculatePicture( Picture a, Picture b) {...}
    Code:
    Lege 1. Bild (100mb) auf den Stack
    Lege 2. Bild (100mb) auf den Stack
    Spring in die Funktion calculatePicture
    berechne Bilder
    ...
    Springe zurück
    Wie du siehst, werden insgesammt 200 mb auf dem Stack platziert, weil die Bilder "direkt" als Parameter übergeben werden.
    Der Stack hat nur eine Begrenzte Größe.
    Wenn die Bilder einmal im Speicher sind, ist es viel effizienter, nicht das ganze Bild auf den Stack zu legen, sondern nur die Adresse, an der das Bild geladen ist:
    void calculatePicture( Picture *a, Picture *b) {...}
    Code:
    Lege Adresse vom 1. Bild (4byte) auf den Stack
    Lege Adresse vom 2. Bild (4byte) auf den Stack
    Spring in die Funktion calculatePicture
    berechne Bilder
    ...
    Springe zurück
    Wie man sieht, werden hier nur 2*4bytes auf dem Stack platziert und nicht 200mb...

    bin penne, gn8 ^_^
     
Thread Status:
Not open for further replies.