Wie verwendet man Zeiger in Strukturen? [Dringend :-(]



  • Schönen guten Tag,

    seit Sommer 2009 habe ich in der Schule nun auch das Fach Programmieren und dort nehmen wir C++ durch. Leider fehlt es uns bis heute an einem vernünftigen Buch und Arbeitsaufgaben auf Blättern gibt es für uns auch nicht. Die PCs in der Schule verfügen zwar über USB-Ports, doch diese sind für uns Schüler nicht benutzbar. Wenn ich was zu Hause lernen wollte, musste ich das Programm in der Schule abschreiben, da haben sich dann auch mal kleinere Fehler eingeschlichen. Naja, bis jetzt habe ich eigentlich alles ziemlich gut verstehen können, aber das jetzige Thema sind Zeiger, das davor waren Strukturen. Montag schreiben wir eine Klausur über beide Themen und der Lehrer kam heute an und meinte, dass er diese Themen irgendwie miteinander verbinden möchte. Zu Hause habe ich mich nun daran gesetzt und ein wenig herumprobiert, doch irgendwie führten meine Versuche nur zu unerwarteten Programmabstürzen.

    Kann mir vielleicht jemand von euch anhand eines minimalen (und, falls dieser Jemand noch Zeit dafür findet, kommentierten) Beispiels erklären, wie man Strukturen mit Zeigern erstellt (plus den Speicher ordnungsgemäß reserviert, benutzt und wieder freigibt)?

    Ich habe auch einige Seiten im Internet gefunden, die diese Themen behandeln, aber das ist mir alles viel zu hoch. Hunderte Fremdwörter, die ich alle nachschlagen muss und hinterher, wenn ich dann deren Bedeutungen herausgefunden habe, wieder den Satz vergesse oder nicht wiederfinde, in dem sie vorkommen.

    Vielen Dank schon einmal für's Lesen!



  • ... tut mir Leid, aber mir als Gast ist es nicht gestattet, meinen vorherigen Beitrag zu editieren. Mir ist gerade auch noch eingefallen, dass ebenfalls Arrays dran kamen? Kann man auch ein Array aus Strukturen erstellen? Wenn ja, wie würde es denn aussehen, wenn man so etwas einer eigenen Funktion übergibt und in der Funktion die Zeiger beschreibt? Wenn man den Speicher zum Funktionsende wieder freigibt, ist ja deren Inhalt wieder weg, oder nicht? Hätte das dann überhaupt einen Sinn? Oh man, ich habe das Gefühl, dass das absolut keine gute Klausur für mich wird 😞



  • Genauso wie in jeder anderen Situation auch, behaupte ich mal :o

    struct Foobar
    {
      int y ; // Integer
      int *a ; //Zeiger auf einen Integer
    
      y=5;
      a=&y ; // Zeiger zuweißen
    
    }
    

    Man möge mich korrigieren wenn das mächtiger Mist war.



  • Didi2010 schrieb:

    ...

    Man sollte Fragen stellen wenn noch Zeit ist. Ich glaube kaum das du Strukturen und Zeiger erst heute hattest.

    Zudem sollte man Fragen konkretisieren (WAS willst du konkret wissen).

    Aber davon abgesehen ein SEHR einfaches Beispiel (was wohl kaum deine Probleme mindert, aber wie gesagt musst du schon konkreter Fragen):

    struct Datum
    {
        int Tag;
        int Monat;
        int Jahr;
    };
    
    int void()
    {
        // Erstmal ohne Zeiger
        {
           Datum datum;
           datum.Tag   = 8;
           datum.Monat = 1;
           datum.Jahr  = 2010;
        }
        // Mit Zeigern:
        {
           Datum * pDatum = new Datum;
           pDatum->Tag   = 8;
           pDatum->Monat = 1;
           pDatum->Jahr  = 2010;
           delete pDatum;
        }
    }
    


  • Jau, kann ich.

    #include <iostream>
    
    struct Foo
    {
       // Zeiger auf eine ander Foo Struktur
       struct Foo* AnotherFoo;
    
       Foo() : 
          AnotherFoo( 0 ) // Pointer bei Erzeugung mit 0 besetzen
       {
       }
    
       void func()
       {
          std::cout << "Ich bin ein Foo!" << std::endl;
       }
    };
    
    void bar( Foo* Parent, Foo* Child )
    {
       // Adresse des zweiten Foo Objektes an Element 
       // des ersten Foo Objekte zuweisen
       Parent->AnotherFoo = Child;
    }
    
    int main()
    {
       // zwei Foo Objekte erzeugen
       Foo Foo1 = new Foo();
       Foo Foo2 = new Foo();
    
       // Foo2 in Foo1 einsetzen
       bar( Foo1, Foo2 );
    
       // Objekte wieder freigeben
       delete Foo1;
       delete Foo2;
    };
    

    Das Programm macht Folgendes:
    In der main() Funktion werden zwei Foo Objekte dynamisch per new() erzeugt, Foo1 bzw. Foo2 halten die Adressen der neu erzeugten Objekte. Anschliessend wird die Funktion bar() aufgerufen, die zwei Zeiger auf Foo Objekte erwartet. Im Funktionsrumpf wird die Adresse des zweiten Objektes an das AnotherFoo Element des ersten Objektes zugewiesen. Nach Rückkehr aus der bar() Funktion werden die beiden dynamisch erzeugten Objekte per delete wieder zerstört.

    Natürlich kannst du auch Arrays aus Strukturen erzeugen, das sähe dann so aus:

    int main()
    {
       // legt 5 Foo Objekte auf dem Stack an. Die Zugriffe auf die einzelnen Foo
       // Objekte geschieht über die Indizes 0-4
       Foo MyFoos[5];
    
       Foo* foo1 = &MyFoos[0]; // Adresse des 1. Foo Objektes bestimmen
       Foo* foo3 = &MyFoos[2]; // Adresse des 3. Foo Objektes bestimmen
    
       // foo3 als Kind in foo1 eintragen (s.o.)
       bar( foo1, foo3 );
    }
    

    Als Besonderheit ist noch anzumerken, dass Pointer den Wert 0 haben können, das heisst, dass sie auf keinen benutzbaren Wert zeigen. Das wird bei Funktionen oft dazu benutzt, optionale Parameter zu übergeben.

    void test_foo( Foo* foo )
    {
       // gültigen Zeiger übergeben?
       if( 0 != foo )
       {
          // ja, dann darf die Methode auf dem Objekt aufgerufen werden
          foo->func();
       }
    }
    
    int main()
    {
       Foo theFoo;
    
       // Aufruf mit ungültigem Foo Objekt
       test_foo( 0 );
    
       // Aufruf mit Adresse des existierenden Foo Objektes
       test_foo( &theFoo );
    }
    

    [/cpp]



  • Erst einmal ein riesen großes Dankeschön an euch dreien. Das ist genau das, worauf ich gehofft habe, als ich den ersten Beitrag verfasst habe. Wirklich prima.

    [quote=asc]Man sollte Fragen stellen wenn noch Zeit ist. Ich glaube kaum das du Strukturen und Zeiger erst heute hattest.[/quote]
    Strukturen haben wir schon vor längerer Zeit durch genommen. Bei denen bin ich mir relativ sicher, weshalb Fragen nicht nötig waren. Das Thema Zeiger jedoch haben wir wirklich erst in der letzten Stunde Programmieren (und die letzte Schulstunde überhaupt vor den Winterferien) behandelt. Die meisten meiner Mitschüler waren schon in totaler Feierlaune und haben gar nicht mitbekommen, dass wir ein neues Thema anfangen. Ich habe den Lehrer solange ich konnte mit Fragen bombardiert, denn von sich aus erklärt der Ar*** ja nichts (oder kaum etwas). Letzten Donnerstag war der erste und Freitag der zweite Tag nach den Ferien, für Schüler aus Nordrhein-Westfalen, und an keinem dieser beiden Tagen hatten wir Programmieren als Unterrichtsfach. Lediglich am Freitag kam der wehrte Herr Lehrer in den Mathematikunterricht hereingeschneit und fing seine Ansprache an die Klasse in etwa so an: "Wie ihr alle wisst, schreiben wir am Montag eine Klausur über Themen wie Arrays, Strukturen und Zeiger...". Naja, ich lerne dann mal fleißig mit Hilfe dessen, was ihr mir geschrieben habt.

    Vielen herzlichen Dank noch einmal!

    PS: Gibt es hier eigentlich einen Thread mit (aktuellen) C/C++-Buch-Kaufempfehlungen mit Schwerpunkt WinAPI? Das wird nämlich das nächste große Thema sein, bis zum Ende des ersten Halbjahres nächsten Jahres.



  • *Argh*, ich vermisse den "Modifizieren"-Button. Jetzt wo ich schon einmal auf dieses Forum gestoßen bin und mir hier meine Fragen beantwortet werden können, nutze ich das auch aus. Mein Lehrer in Programmieren scheint C++ zu verabscheuen und C sehr zu mögen, denn in der ersten Klausur hat er mir Punkte dafür abgezogen, iostream anstatt stdio.h bzw. cstdio benutzt zu haben, obwohl nicht anders explizit in der Aufgabenstellung angegeben. Letztens hat er von STL Containern (vorwiegend über Vektoren) gesprochen, doch diese Unterrichtseinheit mit einem Satz wie "... aber das ist zur Laufzeit unglaublich langsam, bläht das Programm unnötig auf und bietet dafür nur marginale Vorteile. Gute Programmierer verzichten deshalb auf die Verwendung." beendet.

    Fragen dazu:
    1. Was sind die Alternativen zu STL Containern?
    2. Sind diese Alternativen wirklich "schneller"?
    3. Warum blähen STL Container Programme auf?

    😕



  • Didi2010 schrieb:

    *Argh*, ich vermisse den "Modifizieren"-Button.

    Da hilft nur registrieren. Ist in ein paar Sekunden erledigt, dann kannst du deine Beiträge auch ändern.

    Die Aussagen deines Lehrer sind bezogen auf C++ indiskutabel. Ich bin ja sonst nicht für "Lehrerschelte", aber wenn er das tatsächlich so gesagt hat, dann kann man ihm getrost mangelndes Wissen attestieren.

    Spiel nach seinen Regelen um bessere Zensuren zu bekommen, aber wenn du tatsächlich an c++ interessiert bist, glaub ihm kein Wort. 😉


  • Mod

    Didi2010 schrieb:

    *Argh*, ich vermisse den "Modifizieren"-Button. Jetzt wo ich schon einmal auf dieses Forum gestoßen bin und mir hier meine Fragen beantwortet werden können, nutze ich das auch aus. Mein Lehrer in Programmieren scheint C++ zu verabscheuen und C sehr zu mögen, denn in der ersten Klausur hat er mir Punkte dafür abgezogen, iostream anstatt stdio.h bzw. cstdio benutzt zu haben, obwohl nicht anders explizit in der Aufgabenstellung angegeben. Letztens hat er von STL Containern (vorwiegend über Vektoren) gesprochen, doch diese Unterrichtseinheit mit einem Satz wie "... aber das ist zur Laufzeit unglaublich langsam, bläht das Programm unnötig auf und bietet dafür nur marginale Vorteile. Gute Programmierer verzichten deshalb auf die Verwendung." beendet.

    Dein Lehrer hat keine Ahnung. Vermeide in Zukunft etwas von ihm zu lernen.

    Fragen dazu:
    1. Was sind die Alternativen zu STL Containern?

    Selber programmieren.

    2. Sind diese Alternativen wirklich "schneller"?

    Wenn du mehr als 50 Mannjahre Entwicklungszeit reinsteckst, kannst du vielleicht noch was rauskitzeln.

    3. Warum blähen STL Container Programme auf?

    Tun sie nicht.



  • Didi2010 schrieb:

    Mein Lehrer in Programmieren scheint C++ zu verabscheuen und C sehr zu mögen, denn in der ersten Klausur hat er mir Punkte dafür abgezogen, iostream anstatt stdio.h bzw. cstdio benutzt zu haben, obwohl nicht anders explizit in der Aufgabenstellung angegeben.

    Wenn es sich um C++ Unterricht handelt, würde ich dagegen Einspruch einlegen. "stdio.h" ist ein C-Header, <cstdio> ein Kompatibilitätsheader unter C++. "Echte" C++ Header haben kein c vorne angestellt.

    Didi2010 schrieb:

    Letztens hat er von STL Containern (vorwiegend über Vektoren) gesprochen, doch diese Unterrichtseinheit mit einem Satz wie "... aber das ist zur Laufzeit unglaublich langsam, bläht das Programm unnötig auf und bietet dafür nur marginale Vorteile. Gute Programmierer verzichten deshalb auf die Verwendung." beendet.

    Dein Lehrer ist unqualifiziert. In der Anfangszeit war die Standardbibliothek wirklich nicht schnell, aber sie ist inzwischen mit wenigen Ausnahmen mit C vergleichbar (teilweise sogar C überlegen). Templates blähen den Code zwar tatsächlich zu einen gewissen Grad auf, dies hat aber erstmal nichts mit der Performance zu tun (Durch die dadurch gewonnene Typsicherheit kann es sogar ganz anders aussehen)...

    Didi2010 schrieb:

    Fragen dazu:
    1. Was sind die Alternativen zu STL Containern?
    2. Sind diese Alternativen wirklich "schneller"?
    3. Warum blähen STL Container Programme auf?

    1. Lehrer wechseln (und dies mein ich durchaus ernst). Zumindest wenn es sich um C++ handelt.
    2. Nein, wobei je nach Anwendungsfall die Pointercontainer (wie von boost) ihre Vorzüge haben, oder die Hash-Container (die glaube ich mit tr1 kamen).
    3. Templates werden zur Compilezeit aufgelöst, Beispiel weiter unten. Dies erhöht die Programmgröße, nicht zwangsläufig (wegen Typsicherheit...) aber die Performance.

    template<typename T>
    struct A
    {
        T value;
    };
    
    int void()
    {
        A<int> a;
        A<double> b;
    }
    

    Hieraus macht der Compiler in etwa folgendes:

    struct A_int // Name nur zur Erklärung
    {
        int value;
    };
    
    struct A_double // Name nur zur Erklärung
    {
        double value;
    };
    
    int void()
    {
        A_int a;
        A_double b;
    }
    

    Sprich: Für jeden Typ mit dem ein template aufgelöst wird, wird ein eigener Datentyp angelegt.

    ABER: Templates werden nur soweit erzeugt, wie durch den Zugriff nötig ist (Sprich eine Funktion die niemals für einen bestimmten Typ aufgerufen wird, sollte auch nicht generiert werden - darauf basieren auch einige Templatetricks).

    ZUDEM: Dein Lehrer scheint auf einen sehr alten C++ Stand eingespielt zu sein, das er noch nicht einmal weiß, das Templates mehr als nur reine Typauflösungen sein können. Es gibt Templatetechniken um z.B. Funktionen mit den optimalsten Übergabetypen zu versehen (z.B. By Value oder By Const Reference je nach Typ) usw. Sprich mittels Templates lassen sich auch Optimierungen durchführen. Zudem kann man für einzelne Typargumente eine alternative Umsetzung vornehmen, wenn man weiß, das für diesen Typ eine andere Variante besser ist.



  • Mitleid schrieb:

    Die Aussagen deines Lehrer sind bezogen auf C++ indiskutabel. Ich bin ja sonst nicht für "Lehrerschelte", aber wenn er das tatsächlich so gesagt hat, dann kann man ihm getrost mangelndes Wissen attestieren.

    Spiel nach seinen Regelen um bessere Zensuren zu bekommen, aber wenn du tatsächlich an c++ interessiert bist, glaub ihm kein Wort. 😉

    Ohh, es gibt durchaus Mittel einen Lehrer zu ersetzen. Da spielen Eltern und Schüler eine recht große Rolle bei, wenn der Direktor auf einmal Beschwerden bekommt. Der Haken ist nur: dazu müssen die Eltern/Schüler erst einmal von deren Unfaigkeit wissen (Ich kenne einen Fall, wenn auch nicht im Informatikbereich, wo ein Lehrer auf Druck der Eltern weichen musste).



  • Didi2010 schrieb:

    ...

    Nachtrag: Schau dir mal in der C++ FAQ Lite den Punkt 35.10 an, ich glaube der beantwortet auch einiges.



  • Hi,

    ganz ehrlich, ich dachte mir gleich, dass er sich (wenn überhaupt) nur schlecht in Sachen C++ auskennt. Das war bis jetzt nicht mehr als ein Gefühl, da ich mich damit ja selbst nicht auskenne. Nach dem zu urteilen, was ihr so schreibt, weiß ich es nun. Nur werde ich das jetzt nicht einmal meinen Mitschülern erzählen können, da sie von den Fähigkeiten dieses Mannes so unglaublich beeindruckt sind, dass ich nachher noch als Ketzer abgestempelt werde.

    Von einem guten Freund habe ich nun "C++ Für Schnelleinsteiger" von Franzis ausgeliehen bekommen, darin steht einiges... ich kann ja nicht für jede meiner Anfängerfragen hier ein neues Thread eröffnen.

    Vielen Dank noch einmal 😃


Anmelden zum Antworten