Staind
28.01.2018, 20:04
Hallo,
bei meinem Projekt (https://www.roboternetz.de/community/threads/69561-Mein-neues-Projekt-Die-kleine-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
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
#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
...
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é
bei meinem Projekt (https://www.roboternetz.de/community/threads/69561-Mein-neues-Projekt-Die-kleine-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
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
#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
...
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é