Idealer- und ästhetischerweise nutzt man dafür einen bool, dann ist das
automatisch gegeben.
Nö, ist es AFAIK nicht - und kann einem bei -Os oder -O3 auf die Füße fallen.
Der Optimizer darf das in einem ganzen Register belassen, damit sind auch Werte <0 oder >1 möglich.
digitalWrite(3,ledOn); aus der Arduino-Bibliothek.
Aber das setzt nicht das Datenrichtungsregister DDRD sondern das Ausgaberegister PORTD, und es nutzt nicht die Eingangspinbitnummer PIND3, sondern PD3.
Die Frage ist also, was du eigentlich wolltest und warum das alles.
Aber wirklich eleganter ist das auch nicht. Ich habe früher zu viele solcher Makros verwendet. Sie verschleiern, was wirklich passiert. Dadurch provozieren sie falsche Verwendung und machen Fehlermeldungen schwerer verständlich.
Eine ganz normale C Funktion ist gut lesbar und produziert in der Regel genau den gleichen Maschinencode, ist also nicht ineffizient:
1
voidsetze_status_led(boolein)
2
{
3
if(ein)
4
{
5
DDRD|=(1<<PIND3);
6
}
7
else
8
{
9
DDRD&=~(1<<PIND3);
10
}
11
}
12
13
setze_status_led(ledOn);
Wobei man auch aufpassen muss, wie man die Variable nennt. "ledOn" kann die LED nämlich auch aus schalten. Gute passende Namen sind wichtig, falls es kein Wegwerf-Projekt ist.
Idealer- und ästhetischerweise nutzt man dafür einen bool, dann ist das
automatisch gegeben.
Nö, ist es AFAIK nicht - und kann einem bei -Os oder -O3 auf die Füße
fallen.
Nein.
Der Optimizer darf das in einem ganzen Register belassen, damit sind
auch Werte <0 oder >1 möglich.
Der interne Wert, den der Compiler für einen bool nutzt, kann dir aber egal sein. Wenn man ihn in einen Integer konvertiert, kommt immer 0 für false und 1 für true raus. Das garantiert der Standard.
Die Frage ist also, was du eigentlich wolltest und warum das alles.
Das Problem ist doch gerade, jeder Programmiere wählt die Lösung, die ihm persönlich am besten gefällt.
Dominiks ursprüngliches Beispiel ergibt ewig langen Programmcode. Nach dem runter scrollen hat man schon wieder vergessen, was oben stand.
Arduinos digitalWrite() ist zwar kompakt, hat sich aber außerhalb der Arduino Welt nicht durchgesetzt.
Jeder bastelt da irgend etwas anderes. Der Code lässt sich nicht wiederverwenden. Nachvollziehen, was die Macros, Wrapper und Frameworks machen, wird aufwendiger als komplett neu entwickeln.
Nimm als Beispiel die Normen aus Maschinenbau oder Bauwesen. Alle Ingenieure benutzen die selben Symbole und die selben Bezeichnungen. Jeder sieht auf den ersten Blick, was der Kollege konstruiert hat.
Wieso können wir uns nicht auf einen einheitlichen Weg einigen?
Das der Compiler so etwas gut optimieren kann, brauchst du nicht zu beweisen. Das Thema hatten wir schon oft genug. Auch eine ganz normale Funktion erzeugt in der Regel den selben optimalen Maschinencode.
Die Frage nach der "Ästhetik" finde ich viel wichtiger.
Arduinos digitalWrite() ist zwar kompakt, hat sich aber außerhalb der
Arduino Welt nicht durchgesetzt.
Der Maschinencode der dabei heraus kommt ist aber alles andere als Kompakt. Wenn man sich mal den Quelltext der Funktion anschaut, wundert mich das auch nicht. Da passiert ja noch einiges mehr, als nur den einzelnen PIN auf HIGH oder LOW zu setzen. Womit wir wieder beim "verschleiern" sind. Die Funktion macht mehr, als ihr Name suggeriert, was ich nicht gut finde. Andererseits ist sie trotz der Verschleierung halbwegs deppensicher, das muss man auch mal würdigen.
guten abend,
ich habe ein kleines logisches Problem.
Ich möchte den Pin (AVR) anhand einer variable setzen.
Dies habe ich bisher mittels einer if-Bedingung
1
>if(1==ledOn)
2
>{
3
>DDRD|=(1<<PIND3);
4
>}
5
>else
6
>{
7
>DDRD&=~(1<<PIND3);
8
>}
9
>
gibt es da auch einen eleganteren weg, wo ich direkt den wert der
Variable benutzen kann?
DDRD setzt aber nur die Datenrichtung des angegebenen Pins, nicht seinen logischen Zustand. Was du wohl eher möchtest ist
1
if(1==ledOn)
2
{
3
PORTD|=(1<<PD3);
4
}
5
else
6
{
7
PORT&=~(1<<PD3);
8
}
Wenn ledOn nur den Zustand 0 oder 1 annehmen kann, dann kann man das verkürzt schreiben mit:
1
PORTD=PORTD&~(1<<PD3)|(ledOn<<PD3);
Das ist aber IMHO etwas schwerer zu lesen, die If-Bedingung ist meiner Ansicht nach für den Menschen übersichtlicher/einfacher zu lesen/verstehen und der Compiler wirds eh passend optimieren.
Das ist egal, LED verlangt ein Bool, da Bitvariable. Bei Bedarf erfolgt
eine automatische Umwandlung.
Nicht ganz, aber mein Durchblick bei sbit.h ist nicht so der Renner 😀.
Im Simulator sieht es zumindest so aus, als ob der Wert nur mit der Maske 0x01 behandelt wird. Heißt:
LED = 1; // on
LED = 2; // off
LED = 3; // on - und so weiter.
Das ist für mich keine automatische Umwandlung in Bool, denn es ist nicht das selbe wie: alles, was ungleich 0 (false) ist, ist dann 1 (true).
Jeder bastelt da irgend etwas anderes. Der Code lässt sich nicht
wiederverwenden. Nachvollziehen, was die Macros, Wrapper und Frameworks
machen, wird aufwendiger als komplett neu entwickeln.
Nimm als Beispiel die Normen aus Maschinenbau oder Bauwesen. Alle
Ingenieure benutzen die selben Symbole und die selben Bezeichnungen.
Jeder sieht auf den ersten Blick, was der Kollege konstruiert hat.
Wieso können wir uns nicht auf einen einheitlichen Weg einigen?
Als Mädchen mit entsprechenden Erfahrungen sage ich es so: Jeder will den Größten haben...
Einheitlicher Weg würde ja bedeuten, dass niemand mehr "Java ist besser!", "Nein C ist besser!", "Nein Rust ist besser!" sagen dürfte, sondern dass sich alle einigen müssten auf ein gemeinsames Ziel. Aber das geht doch nicht! Nicht unter Jungs jedenfalls ^^
Wieso können wir uns nicht auf einen einheitlichen Weg einigen?
Ich nochmal... Mir kommt das so vor als ob es darum geht, ob Programmieren Kunst oder Handwerk ist. Manche wollen Geld damit verdienen, und manche wollen Applaus ^^
guten abend,
ich habe ein kleines logisches Problem.
Ich möchte den Pin (AVR) anhand einer variable setzen.
Dies habe ich bisher mittels einer if-Bedingung
1
>if(1==ledOn)
2
>{
3
>DDRD|=(1<<PIND3);
4
>}
5
>else
6
>{
7
>DDRD&=~(1<<PIND3);
8
>}
9
>
gibt es da auch einen eleganteren weg, wo ich direkt den wert der
Variable benutzen kann?
Der Code ist grundsätzlich scheiße.
Warum? Weil ihn niemand versteht, der nicht C-Experte ist so wie du.
Wenn ledOn bool ist, dann ist die if-clause schon falsch. Und zweitens gehört (1 << PIND3) in eine eigene Funktion verpackt, weil "don't repeat yourself".
Das ist egal, LED verlangt ein Bool, da Bitvariable. Bei Bedarf erfolgt
eine automatische Umwandlung.
Nicht ganz, aber mein Durchblick bei sbit.h ist nicht so der Renner 😀.
Im Simulator sieht es zumindest so aus, als ob der Wert nur mit der
Maske 0x01 behandelt wird. Heißt:
LED = 1; // on
LED = 2; // off
LED = 3; // on - und so weiter.
Das ist für mich keine automatische Umwandlung in Bool,
Anders herum wird ein Schuh draus. Auf der rechten Seite der Zuweisung muss ein bool stehen, und dann kommt in LED eine 0 an, wenn der false ist und eine 1, wenn er true ist. Eine 2 oder 3 gibt es dann gar nicht. Es ging doch darum:
Anders herum wird ein Schuh draus. Auf der rechten Seite der Zuweisung
muss ein bool stehen, und dann kommt in LED eine 0 an, wenn der false
ist und eine 1, wenn er true ist. Eine 2 oder 3 gibt es dann gar nicht.
Ja, richtig! Welcher Typ die Variable 'ledOn' beim TO jedoch hatte, ist unbekannt. Deshalb schrieb ich dazu:
also auf den boolschen Zahlenraum beschränkt ist.
Du hast sinnvollerweise ergänzt, dass man für ledOn gleich eine Boolvariable nehmen sollte. Zumindest wäre einen Cast auf bool nötigt.