Go Down

Topic: #define für ganze "Statements"? (Read 862 times) previous topic - next topic

XIII_fly

Hallo liebe Community,

ich bin derzeit dabei mir ein Programm für einen Arduino Mega mit Touchscreen und Relaismodul zum Bierbrauen zusammenzubasteln. Der Aufbau ist total simpel, gleicht ja einem einfachen Thermostat.

Was mir aber einiges an Nerven abverlangt ist die Programmierarbeit der Touchscreenoberfläche/-bedienung.

Hier die Frage:
Gibt es die Möglichkeit, ein ganzes Statement "zu definen"?

Als Beispiel:
Ein roter Button befindet sich auf den x-Koordinaten von 0 bis 30 und y-Koordinaten von 0 bis 30.
Wenn ich diesen mit einer Funktion belegen möchte, würde das ja nun über ein if-Statement wie
if (x >= 0 && x <= 30 && y >= 0 && y <= 30) {do this and that;}
funktionieren.
Ich hätte aber gerne, zur besseren Leserlichkeit und um Zeit zu sparen, dass es so aussieht:
if (red) {do this and that;}

Wie kriege ich das hin? Also dass der Compiler beispielsweise die Bedingungen "x >= 0 && x <= 30 && y >= 0 && y <= 30" durch das Keyword "rot" abruft?
Über #define geht es ja , dass die IDE/der Compiler meine "Schlüsselwörter" mit dem definierten Wert austauscht.
Gibt es diese Option auch für ganze Statements?
Ich habe in der Reference gesucht und gegoogelt, leider nichts gefunden.
Vermutlich, weil ich auch nicht weiß, wonach ich wirklich suchen muss, ich bin kompletter Neuling. Aber das habt ihr wahrscheinlich bereits an den falsch benutzten Fachausdrücken bemerkt ;) .

Schon mal danke und liebe Grüße
XIII

ElEspanol

#1
Apr 23, 2017, 09:43 am Last Edit: Apr 23, 2017, 09:43 am by ElEspanol
Mach die ganzen if Abfragen in einer Funktion und rufe die im loop auf. Die Resultate speicherst du in globalen bool.
Oder eine Funktion und das Resultat als Rückgabewert.

Das ganze in einen anderen tab, damit alles schön aufgeräumt ist.

combie

#2
Apr 23, 2017, 10:36 am Last Edit: Apr 23, 2017, 10:38 am by combie
Quote
Was mir aber einiges an Nerven abverlangt ist die Programmierarbeit der Touchscreenoberfläche/-bedienung.
Das glaube ich!

Nicht ohne Grund wurden grafische Benutzeroberflächen recht spät erfunden.
Und "teuer", im Sinne von Ressourcenverbrauch sind sie auch.


Das mit dem #define ist eine Schnapsidee.
Sofort wieder vergessen!


Jedes Grafische Element muss seine Ausdehnung und Ort kennen.
Alle grafischen Elemente werden in einer Liste/Baum organisiert.

Bei einem Ereignis, kann man die Liste entlang laufen und jedes einzelne Element
fragen: "Liegt der Punkt in deinem Hüllrechteck?"

Tipp:
Da wir ja Funktionen und Objekte, mit ihren Methoden, haben und auch nutzen können, reicht es, die If Abfrage, die dich ja so stört, nur an einer einzigen Stelle im gesamten Programm zu machen.


Es ist offensichtlich, dass uns die Umstände alleine nicht glücklich oder unglücklich machen.
Es ist die Art unserer Reaktion darauf, die unsere Gefühle bestimmt.

jurs

Hallo liebe Community,

ich bin derzeit dabei mir ein Programm für einen Arduino Mega mit Touchscreen und Relaismodul zum Bierbrauen zusammenzubasteln. Der Aufbau ist total simpel, gleicht ja einem einfachen Thermostat.

Was mir aber einiges an Nerven abverlangt ist die Programmierarbeit der Touchscreenoberfläche/-bedienung.

Hier die Frage:
Gibt es die Möglichkeit, ein ganzes Statement "zu definen"?
Ja, es gibt auch funktionsähnliche Makros mit Parametern, die der Präprozessor verarbeiten kann.

Du mußt Dir aber immer darüber im klaren sein, dass die Expansion von Präprozessor-Makros VOR dem eigentlichen Kompiliervorgang stattfindet und nicht erst im laufenden Programm. Daher sind die Makro-Funktionen keine "echten" Funktionen, Du kannst also beispielsweise keine Typen für die Parameter vorgeben, sondern das Makro arbeitet mit den Parametertypen, mit denen Du das Makro aufrufst.

Nimm zum Beispiel das min() Makro, um den kleineren von zwei Werten zu erhalten:

#define min(X, Y)  ((X) < (Y) ? (X) : (Y))

Wenn Du das Makro im Code zusammen mit 'int' Parametern verwendest, erzeugt der Compiler Code für den Vergleich von int Werten und liefert ein int zurück.

Und wenn Du dasselbe Makro im Code zusammen mit 'float' Parametern verwendest, erzeugt der Compiler Code für den Vergleich von float Werten und liefert ein float zurück.

DrDiettrich

Ein roter Button befindet sich auf den x-Koordinaten von 0 bis 30 und y-Koordinaten von 0 bis 30.
Wenn ich diesen mit einer Funktion belegen möchte, würde das ja nun über ein if-Statement wie
if (x >= 0 && x <= 30 && y >= 0 && y <= 30) {do this and that;}
funktionieren.
Ich hätte aber gerne, zur besseren Leserlichkeit und um Zeit zu sparen, dass es so aussieht:
if (red) {do this and that;}
Dafür kannst Du einfach definieren
Code: [Select]
#define red x >= 0 && x <= 30 && y >= 0 && y <= 30

Wenn Du so eine Abfrage für mehrere Buttons schreiben möchtest, dann empfiehlt sich ein #define oder eine Funktion, mit der sich die Eckpunkte der Buttons angeben lassen. Noch besser wären Button-Objekte, die ihre Koordinaten kennen, und die sich dann abfragen lassen wie z.B.
  if redButton.pressed() {...}

Da gibt es beliebig viele Varianten, wie man so ein GUI übersichtlich programmieren kann. Je nach Deinen Vorkenntnissen und Wissensdurst kannst Du mit der einfachen #define Variante anfangen, und Dich dann zu den Klassen, Methoden und Ereignissen weiterarbeiten.

XIII_fly

Danke für die Antworten!

Mach die ganzen if Abfragen in einer Funktion und rufe die im loop auf. Die Resultate speicherst du in globalen bool.
Oder eine Funktion und das Resultat als Rückgabewert.
So ähnlich hatte ich mir das jetzt auch gedacht: Ich schreibe eine Funktion mit vielen If-Statements (welche die Koordinaten zuordnen) und jedes Statement gibt für jede Box einen bestimmten Wert aus, welche ich dann im Hauptprogramm wieder in verschiedene "If-Bäume" unterbringe.

Die If-Bäume wären natürlich auch besser lesbar, wenn ich nicht mit den abstrakten Koordinaten arbeiten müsste.


Das mit dem #define ist eine Schnapsidee.
Sofort wieder vergessen!


Jedes Grafische Element muss seine Ausdehnung und Ort kennen.
Alle grafischen Elemente werden in einer Liste/Baum organisiert.

Bei einem Ereignis, kann man die Liste entlang laufen und jedes einzelne Element
fragen: "Liegt der Punkt in deinem Hüllrechteck?"

Tipp:
Da wir ja Funktionen und Objekte, mit ihren Methoden, haben und auch nutzen können, reicht es, die If Abfrage, die dich ja so stört, nur an einer einzigen Stelle im gesamten Programm zu machen.
Nun ja, da ich ja auch während eines while-Loops, der beim Brauen auch mal längere Zeit läuft den Touchscreen verwenden möchte und ich auch vor habe einen Setup Mode zu integrieren, der es ermöglich die einzelnen Buttonfunktionen ohne PC zu konfigurieren muss dies schon öfters abgefragt werden.
Aber ihr habt mich auf jeden Fall schon mal zum umdenken gebracht, vielleicht klappt es ja doch über eine Funktion.

Ja, es gibt auch funktionsähnliche Makros mit Parametern, die der Präprozessor verarbeiten kann.

Du mußt Dir aber immer darüber im klaren sein, dass die Expansion von Präprozessor-Makros VOR dem eigentlichen Kompiliervorgang stattfindet und nicht erst im laufenden Programm. Daher sind die Makro-Funktionen keine "echten" Funktionen, Du kannst also beispielsweise keine Typen für die Parameter vorgeben, sondern das Makro arbeitet mit den Parametertypen, mit denen Du das Makro aufrufst.
Ja genau, so etwas meine ich.

Es soll einfach ein Schlagwort im Code durch etwas von mir Vorgegebenem ersetzt werden.
Das Einzusetzende ist nicht variabel, es wäre konstant.
Nur leider ist mir nicht klar, mit welchem Datentyp, oder wie auch immer ich die IDE beispielsweise dazu bewegen kann beim Kompilieren, das Schlagwort "Button03Coordinates" durch "touchX >= 30 && touchX <= 60 && touchY >= 50 && touchY <= 80" zu ersetzen.

Hätte ich einen einfach Wert zum Einsetzen, würde ich das einfach mit #define bzw. const machen, aber ich hab ein Argument.

Theoretisch könnte ich das natürlich auch per Hand vor dem Kompilieren über die Finden/Ersetzen Funktion der IDE machen.
Oder einfach hardcoden, aber gibt es eben für so, ich nenne es jetzt mal "Autoersetzen" keine einfache Möglichkeit in C (bzw. vielmehr der Arduino IDE)?

Aber echt schon mal danke für die Antworten, lösen kann ich es jetzt auf jeden Fall schon mal. :)

MicroBahner

#6
Apr 23, 2017, 08:02 pm Last Edit: Apr 23, 2017, 08:08 pm by MicroBahner
Dafür kannst Du einfach definieren
Code: [Select]
#define red x >= 0 && x <= 30 && y >= 0 && y <= 30

Dann sollte man das aber auf jeden Fall in Klammern setzen, damit es immer eine Einheit bleibt:
Code: [Select]
#define red (x >= 0 && x <= 30 && y >= 0 && y <= 30)
Da das ja eine reine Textersetzung ist, könnte es u.U. üble Nebenwirkungen geben wenn man dann mal sowas wie
Code: [Select]
if ( red || blue )
programmiert.

Gruß, Franz-Peter

XIII_fly

Dafür kannst Du einfach definieren
Code: [Select]
#define red x >= 0 && x <= 30 && y >= 0 && y <= 30

Wenn Du so eine Abfrage für mehrere Buttons schreiben möchtest, dann empfiehlt sich ein #define oder eine Funktion, mit der sich die Eckpunkte der Buttons angeben lassen. Noch besser wären Button-Objekte, die ihre Koordinaten kennen, und die sich dann abfragen lassen wie z.B.
  if redButton.pressed() {...}

Da gibt es beliebig viele Varianten, wie man so ein GUI übersichtlich programmieren kann. Je nach Deinen Vorkenntnissen und Wissensdurst kannst Du mit der einfachen #define Variante anfangen, und Dich dann zu den Klassen, Methoden und Ereignissen weiterarbeiten.
Oh.Mein.Gott!!!!!!
Das geht wirklich? Das war jetzt das erste, was ich probiert hatte! Hahah, hab mich sicher dann vertippt, oder sowas! :DDD

Danke, danke!!!

Oh ja, werde mich wirklich auch weiter einlesen und über eine Funktion die Buttons abrufen, das ist schon einmal wesentlich eleganter!

Nochmal danke für eure Hilfe!

Go Up