-         
Ergebnis 1 bis 3 von 3

Thema: C++: Zeiger Programmierung und Strukturen

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    27.05.2011
    Ort
    NRW
    Alter
    30
    Beiträge
    138

    C++: Zeiger Programmierung und Strukturen

    Anzeige

    Hallo,

    bei meinem Projekt (https://www.roboternetz.de/community...eine-Mischerei) geht es langsam aber sicher in die Programmierphase...
    Beruflich programmiere ich viel in der SPS Welt hauptsächlich in AWL. In der Techniker Schule habe ich C# kennengelernt und dort bin ich auch relativ fit drin.
    Naja C++ ist zwar sehr ähnlich aber das sind die Programmiersprachen ja alle irgendwie. Nun geht es um die Zeigerprogrammierung. Dort hoffe ich das ganze verstanden zu haben, sicher bin ich aber nicht.
    Daher wollte ich mal fragen ob ich das ganze so programmieren kann. Das Programm wird nachher auf ein Arduino laufen.
    Ich habe auch schon viel im Internet gelesen, aber spezielle Fragen habe ich immer noch. Das Programm lässt sich auf jeden fall so kompilieren wie ich das jetzt hier im ersten Beispiel vorstelle.
    Mir geht es darum ob ich das ganze so realisieren kann, oder ob es da zu Datenverlust kommen kann.

    Fall 1:
    Klasse.h
    Code:
    class Sortierer
    {
        
        ////////////////////////////////////////
        // Strukturen
        public: 
        struct strKoordinate
        {
            byte x;
            byte y;
        };
    
    
        struct strGrenzen
        {
            byte minimum;
            byte maximum;
        };
    
    
        struct strFarbGrenzen
        {
            strGrenzen rot;
            strGrenzen gruen;
            strGrenzen blau;
        };
        
        struct strStellung
        {
            strKoordinate koordinate;
            strFarbGrenzen farbe;
        };
        
        ////////////////////////////////////////
        // Variablen
        private:  
        strStellung adressenStellung[SO_STELLUNGEN];
        strStellung stellung[SO_STELLUNGEN];
    
        ////////////////////////////////////////
        // Konstruktoren
        public: 
        Sortierer(struct strStellung padressenStellung[SO_STELLUNGEN]);
    
    
        ////////////////////////////////////////
        // Methoden
        void setFarbGrenzen(byte pStellung, struct strFarbGrenzen *pFarbe);
        struct strFarbGrenzen     getFarbGrenzen(byte pStellung);
    
    };
    #endif // SORTIERER_H
    Meine Frage zu diesem Teil. Kann ich die Strukturen so realisieren, also eine Struktur in eine Struktur und noch tiefer schachteln?

    Klasse.cpp
    Code:
    #include "Sortierer.h"
    #include <EEPROM.h>
    
    
    ////////////////////////////////////////
    // Konstruktoren
    Sortierer::Sortierer(struct Sortierer::strStellung padressenStellung[SO_STELLUNGEN])
    {
        for(int i = 0; i < SO_STELLUNGEN; ++i)
        {
            adressenStellung[i].koordinate = padressenStellung[i].koordinate; 
            adressenStellung[i].farbe = padressenStellung[i].farbe; 
        }
    }
    
    
    ////////////////////////////////////////
    // Methoden    
    void Sortierer::setFarbGrenzen(byte pStellung, struct Sortierer::strFarbGrenzen *pFarbe)
    {
        EEPROM.update(adressenStellung[pStellung].farbe.rot.minimum, pFarbe -> rot.minimum);
        EEPROM.update(adressenStellung[pStellung].farbe.rot.maximum, pFarbe -> rot.maximum);
        EEPROM.update(adressenStellung[pStellung].farbe.gruen.minimum, pFarbe -> gruen.minimum);
        EEPROM.update(adressenStellung[pStellung].farbe.gruen.maximum, pFarbe -> gruen.maximum);
        EEPROM.update(adressenStellung[pStellung].farbe.blau.minimum, pFarbe -> blau.minimum);
        EEPROM.update(adressenStellung[pStellung].farbe.blau.maximum, pFarbe -> blau.maximum);
        stellung[pStellung].farbe.rot = pFarbe -> rot;
        stellung[pStellung].farbe.gruen = pFarbe -> gruen;
        stellung[pStellung].farbe.blau = pFarbe -> blau;
    }
    
    struct Sortierer::strFarbGrenzen Sortierer::getFarbGrenzen(byte pStellung)
    {
        struct Sortierer::strFarbGrenzen pFarbe;
        pFarbe = stellung[pStellung].farbe;
        return pFarbe;
    }
    Hier die frage zum Zeiger. Der Übergabewert der Methode setFarbGrenzen ist ja ein Byte, und ein Zeiger der Struktur strFarbGrenzen.
    In der Methode will ich ja die Werte von dem Zeiger abgreifen was ich ja mit pFarbe -> rot mache. Momentan kann ich so aber nur die Elemente der Struktur übergeben aber nicht die ganze Struktur.
    Ist es möglich die ganze struktur zu übergeben. Also quasi:

    stellung[pStellung].farbe = pFarbe;

    pFarbe ist ja im diesen Fall die Zeigeradresse weswegen das so ja nicht geht. Gibt es irgendein Befehl um von der Zeigeradresse die ganze Struktur zu übergeben?

    also so in der Art:

    stellung[pStellung].farbe = pFarbe -> pFarbe;

    oder kann ich nur die Strukturelemente einzeln übergeben wie in der Methode geschrieben:

    stellung[pStellung].farbe.rot = pFarbe -> rot;
    stellung[pStellung].farbe.gruen = pFarbe -> gruen;
    stellung[pStellung].farbe.blau = pFarbe -> blau;

    Dann noch eine Frage zu den Methoden einer Klasse:

    Ist so etwas möglich?

    struct Sortierer::strFarbGrenzen *Sortierer::getFarbGrenzen(byte pStellung)
    {
    struct Sortierer::strFarbGrenzen pFarbe;
    pFarbe = stellung[pStellung].farbe;
    return &pFarbe;
    }

    Also ich gebe ein Zeiger zurück von einer Variable / Struktur die in einer Methode erzeugt wird.
    Wahrscheinlich nicht da die Variable nach dem Return nicht mehr existiert und der Zeiger somit ins leere zeigt.

    Ich müsste wahrscheinlich die Variable in der Klasse.h erzeugen damit dieses funktioniert also quasi so:

    struct Sortierer::strFarbGrenzen *Sortierer::getFarbGrenzen(byte pStellung)
    {
    farbe = stellung[pStellung].farbe; // farbe wird als private Variable in der Klasse erzeugt
    return &farbe;
    }

    Hauptprogramm

    Code:
    ...
    Sortierer::strStellung fs_adressen[7] = {{1,2,3,4,5,6,7,8},  // EEPROM Adressen
                                            {9,10,11,12,13,14,15,16},
                                            {17,18,19,20,21,22,23,24},
                                            {25,26,27,28,29,30,31,32},
                                            {33,34,35,36,37,38,39,40},
                                            {41,42,43,44,45,46,47,48},
                                            {49,50,51,52,53,54,55,56}};
    
    
    Sortierer fs_sortierer(fs_adressen); //Objekt erstellen
    ...
    void loop() {
    ...
    Sortierer::strFarbGrenzen fs_Grenzen =  fs_sortierer.getFarbGrenzen(0);  //Grenzen von Stellung 0
    ...
    }
    So und jetzt die Fragen was ist möglich in der Loopschleife.

    Ich denke dieses hier sollte kein Problem sein:

    Sortierer::strFarbGrenzen fs_Grenzen = fs_sortierer.getFarbGrenzen(0);

    also der Rückgabewert (Struktur) der Methode wird nicht als Zeiger sondern als Struktur zurückgegeben.

    Ich denke so etwas geht nicht oder:

    Funktion(&fs_sortierer.getFarbGrenzen(0));

    Also der Übergabewert der Funktion ist ein Zeiger auf den Rückgabewert der Methode.
    Dies wird wahrscheinlich nicht Funktionieren, weil der Rückgabewert (die Struktur) nicht mehr bei dem Funktionsaufruf existiert und der Zeiger somit ins leere zeigt.
    Ist dieses richtig?

    Das Ganze müsste ich dann wahrscheinlich so lösen oder?

    Sortierer::strFarbGrenzen fs_Grenzen = fs_sortierer.getFarbGrenzen(0);

    Funktion(&fs_Grenzen);

    Ich hoffe der Code ist nicht zu schwer zu lesen und ich weiß auch das es schwierig ist / Zeit braucht fremden Code zu verstehen.
    Ich hoffe trotzdem das der ein oder andere sich Zeit nimmt und sich ein wenig rein denkt.
    Schon einmal vielen Dank für die Antworten.

    Gruß André
    Geändert von Staind (28.01.2018 um 22:12 Uhr)

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    606
    Hallo,

    ich beantworte mal einen Teil, im Moment habe ich wenig Zeit

    Zitat Zitat von Staind Beitrag anzeigen
    Meine Frage zu diesem Teil. Kann ich die Strukturen so realisieren, also eine Struktur in eine Struktur und noch tiefer schachteln?
    Kann man. Ist eigentlich nur eine Stilfrage. In C# wären verschachtelte Klassen schlechter Stil, in C++ ist Verschachteln etwas üblicher.

    Zitat Zitat von Staind Beitrag anzeigen
    Ist es möglich die ganze struktur zu übergeben. Also quasi:

    stellung[pStellung].farbe = pFarbe;
    du meinst sicher
    Code:
    stellung[pStellung].farbe = *pFarbe;
    Aber eigentlich ist die Verwendung von Zeigern dort falsch. Da würde man eher eine Referenz nehmen, das entspräche in etwa dem "ref" in C# bei Werttypen.
    Code:
    void Sortierer::setFarbGrenzen(byte stellung, strFarbGrenzen &farbe)
    oder, wenn man das übergebene gar nicht verändern will, als konstante Referenz
    Code:
    void Sortierer::setFarbGrenzen(byte stellung, const strFarbGrenzen &farbe)
    mit
    Code:
    stellung[pStellung].farbe = farbe;
    Die Benennung deiner Parameter finde ich ziemlich fragwürdig
    Code:
    getFarbGrenzen(byte pStellung)
    Mit p beginnende Parameternamen benutzt man sehr häufig um zu kennzeichnen, dass es sich um Zeigervariablen handelt (p wie Pointer), dass das jetzt hier anscheinend im Sinne von Parameter gebraucht wird, ist ziemlich verwirrend.

    Außerdem sind die ganzen "struct" in den Funktionsparameterlisten absolut überflüssig.
    Geändert von Mxt (29.01.2018 um 13:26 Uhr)

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    606
    Ok, nächstes Stück

    Zitat Zitat von Staind Beitrag anzeigen
    Ist so etwas möglich?

    struct Sortierer::strFarbGrenzen *Sortierer::getFarbGrenzen(byte pStellung)
    {
    struct Sortierer::strFarbGrenzen pFarbe;
    pFarbe = stellung[pStellung].farbe;
    return &pFarbe;
    }
    Abgesehen von den vielen falschen struct, kommt es darauf an, was du haben willst.

    Eine Kopie von stellung[pStellung].farbe wäre
    Code:
    Sortierer::strFarbGrenzen Sortierer::getFarbGrenzen(byte pStellung)
    {
        return stellung[pStellung].farbe;
    }
    Aber wahrscheinlich meinst du auch hier eher eine Referenz, über die du den Wert ändern willst
    Code:
    Sortierer::strFarbGrenzen& Sortierer::getFarbGrenzen(byte pStellung)
    {
        return stellung[pStellung].farbe;
    }
    Und wenn es wirklich ein Zeiger sein muss, wäre es

    Code:
    Sortierer::strFarbGrenzen* Sortierer::getFarbGrenzen(byte pStellung)
    {
        return &(stellung[pStellung].farbe);
    }
    Alle Beispiele haben das Problem, dass sie nicht prüfen ob pStellung einen gültigen Wert hat.
    Geändert von Mxt (29.01.2018 um 13:44 Uhr)

Ähnliche Themen

  1. [ERLEDIGT] strukturen, ein- und ausstieg
    Von inka im Forum Robby RP6
    Antworten: 42
    Letzter Beitrag: 06.10.2013, 15:21
  2. Probleme feine Strukturen zu drucken für Platine
    Von Hellmut im Forum Konstruktion/CAD/Sketchup und Platinenlayout Eagle & Fritzing u.a.
    Antworten: 12
    Letzter Beitrag: 20.12.2010, 13:35
  3. Zeiger und Felder
    Von Knipser-14 im Forum C - Programmierung (GCC u.a.)
    Antworten: 7
    Letzter Beitrag: 14.03.2010, 14:19
  4. Probleme bei Strukturen (Projekt Funkuhr)
    Von Wasserkäfer im Forum C - Programmierung (GCC u.a.)
    Antworten: 9
    Letzter Beitrag: 19.07.2008, 15:10
  5. Warum Zeiger???
    Von jay1982 im Forum C - Programmierung (GCC u.a.)
    Antworten: 8
    Letzter Beitrag: 27.10.2007, 13:55

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •