Woran machst du fest, was "uneffizienter code" ist? Am Schreibaufwand?
Am vermuteten erzeugten Code? An der Lesbarkeit?
Es wird am Ende derselbe Maschinencode herauskommen :-)
>Es wird am Ende derselbe Maschinencode herauskommen :-)
Das ist nicht richtig.
Wenn LOW = 0 und HIGH = 1 wird ledState 0 oder 1.
Im zweiten Beispiel wird ledState 0 oder 0xFF wenn ledState uint8_t ist.
holger schrieb:> Das ist nicht richtig.> Wenn LOW = 0 und HIGH = 1 wird ledState 0 oder 1.> Im zweiten Beispiel wird ledState 0 oder 0xFF wenn ledState uint8_t ist.
Wohl kaum, mal in einem C-Buch den Unterschied zwischen logischer und
Bit-Negierung nachlesen.
Die "Verbesserung" funktioniert nur identisch, wenn LOW 0 ist und HIGH 1
oder umgekehrt. Bei allen anderen Werten (evtl gibt es ja OFF, LOW,
MEDIUM, HIGH?) klappt das "!" nicht.
Der Sinn und Zweck von benamten Konstanten ist es ja, dass einem der
konkrete Wert nicht interessiert. Durch das "!" machst du genau das
Gegenteil, du verlässt dich auf konkrete Werte.
Bei numerischem LOW/HIGH (und nur die beiden) ginge:
1
ledState=LOW+HIGH-ledState;
2
// oder
3
ledState^=LOW^HIGH;
Ob das aber, insbesondere für Anfänger, lesbarer wäre?
Karli schrieb:> Wäre es nicht sinnvoll, diesen durch ledState = !ledstate;> zu ersetzen?
Die Frage ist eher, was der bezweckte Sinn ist. Ist es, möglichst
"effizienten" Code zu schreiben, oder Anfängern die Sprache
beizubringen?
googoo schrieb:> wie wär's mit led = led ^ 1 ? :)> oder auch led ^=1
Ich würde bit-weise invertieren, dann kann man die anderen PortPin's
noch für andere Zwecke verwenden.
1
#define PP0 = 0x01;
2
#define PP1 = 0x02;
3
#define PP2 = 0x04;
4
#define PP3 = 0x08;
5
#define PP4 = 0x10;
6
#define PP5 = 0x20;
7
#define PP6 = 0x04,;
8
#define PP7 = 0x08;
9
10
port~=PP5;// für PortPin 5
Durch Addition, z.B. (PP3+PP5+PP7), können mehrere PortPin's
angesteuert werden.
The Mule schrieb:> #define in dem Zusammenhang ist Rückschritt.
Dient nur zur Erklärung. Man kann natürlich auch eine Konstante
definieren.
Reine Geschmackssache!
GEKU schrieb:> port ~= PP5; // für PortPin 5
was soll das tun?
das wäre ja ausgeschrieben
1
port=port~0x20;->
2
port=port0xDF;
Ich würde sowas wie missing operator erwarten. Oder ist ~ in CPP anders
definiert?
--- Probieren ---
GCC (C) sagt:
error: expected ';' before '~' token
Andre schrieb:> Karli schrieb:>> Wäre es nicht sinnvoll,>> Komplett auf die Variable zu verzichten und das Bit im Ausgangsregister> zu toggeln?
Oder noch effizienter: Die LED direkt an einen Timer-PWM hängen, dann
blinkt die sogar ohne Code (und der TO lernt, wie man einen Timer
aufsetzt)
VG
Roland
GEKU schrieb:> Ich würde bit-weise invertierenGEKU schrieb:> port ~= PP5; // für PortPin 5
Was du meinst ist XOR, ^
Die Tilde die du verwendest ist Bitweise-Invertieren und ein unärer
Operator, dh. er erwartet EINEN Operanden
zB
~ 00 ergibt FF
~ 88 ergibt 77 usw
Theoretisch müsste "port~=;" funktionieren ;) kann das aber grad nicht
testen;)
Philipp_K59 schrieb:> wäre nach dem Beispiel gekürzt:>> digitalWrite(ledPin, (!ledState?HIGH:LOW));
Eher so.. bin da nicht so der Short-If Profi.
digitalWrite(ledPin, (ledState=!ledState?HIGH:LOW));
Irgendwie komme ich mit dem Hingucken einfach nicht nach!
Ich assoziiere "Blink" mit etwas, was man sehen kann.
Die Code-Fragmente flackern mir zu schnell.
Der Ansatz: "Ohne Delay" ist ein Witz, wenn dieses einfach, ersatzlos
weggelassen wird.
Sebastian S. schrieb:> Der Ansatz: "Ohne Delay" ist ein Witz, wenn dieses einfach, ersatzlos> weggelassen wird.
Die Idee dahinter ist, den Code für´s Bit-Toggeln so ineffizient langsam
zu machen, daß ein extra Delay unnötig wird :P
Mark B. schrieb:> Der generierte Maschinencode wird genau der gleiche sein.
Es geht grundsätzlich um eine Designentscheidung:
Kurz-und-knapp-mathematisch oder eher in Prosaform.
Spätestens wenn man ein Programm mit sagen wir 300 Zeilen durcharbeiten
(zB Bugs finden) muss, macht es nen Unterschied ob es 300 oder 1500
Zeilen sind
(sprich 3000, 30000 Zeilen usw obwohl das dann schon pervers ist)
gurgl schrieb:> Mark B. schrieb:>> Der generierte Maschinencode wird genau der gleiche sein.>> Es geht grundsätzlich um eine Designentscheidung:> Kurz-und-knapp-mathematisch oder eher in Prosaform.>> Spätestens wenn man ein Programm mit sagen wir 300 Zeilen durcharbeiten> (zB Bugs finden) muss, macht es nen Unterschied ob es 300 oder 1500> Zeilen sind
Wenn die einzelnen Funktionen kurz und übersichtlich sind, weil man
vernünftig programmiert hat, ist es relativ egal ob die gesamte Software
nun aus 300 oder 3.000 Zeilen Code besteht.
Code wird jedenfalls nicht automatisch besser, wenn man mehr davon in
eine Zeile packt. In dem Beispiel oben mag es okay sein, aber oft genug
führt "Zeilenquetscherei" eher zu schlechter lesbarem und wartbarem
Code.
Philipp_K59 schrieb:> Oder ganz easy..>> ledState = !ledState?HIGH:LOW;
? ?
ledState = !(ledState?HIGH:LOW);
ledState = (!ledState)?HIGH:LOW;
ledState = ledState?LOW:HIGH);
ledState = !ledState;
Naja, ob der Trenäre Operator in einem "Blink without delay" gut
aufgehoben ist, möchte ich bezweifeln.
Arduino Fanboy D. schrieb:> Trenäre Operator
ledState = (ledState == HIGH) ? LOW : HIGH ;
da müsste ich jetzt auch 2 mal hinsehen, schön isses nicht aber wenn
schon so dann so.
vodoo schrieb:> (ledState == HIGH)vodoo schrieb:> aber wenn schon so dann so.
Da bin ich gegen...
Ein Vergleich mit HIGH ist unsinnig, wenn die Variable sowieso nur HIGH
und LOW werden kann.
(ledState == HIGH)
Würde zu
(HIGH == HIGH)
oder
(LOW == HIGH)
Einfach nur (ledState) ist an der Stelle völlig ausreichend
(Die Klammern sind auch noch über)
Arduino Fanboy D. schrieb:> (Die Klammern sind auch noch über)
klammern waren ja wegen dem vergleich und an dem würde ich unbedingt
festhalten da sich ja high, low verändern könnten in anderen
arduinoversionen, so ist dat sicher!
Nehmt den Arduino, er ist sehr gut!
vodoo schrieb:> so ist dat sicher!
Ob du hier
ledState = (ledState == HIGH) ? LOW : HIGH ;
oder
ledState = ledState == HIGH ? LOW : HIGH ;
oder
ledState = ledState ? LOW : HIGH ;
oder
ledState = not ledState;
schreibst ist völlig irrelvant.
Komme was wolle
Karl Max schrieb im Beitrag #5865771:
> und/oder in der Variablendeklaration
Wenn das auf meinen Mist gewachsen wäre, würde sicherlich sowas da
stehen:
> bool ledState;
Karli schrieb:> Wäre es nicht sinnvoll, diesen durch ledState = !ledstate;> zu ersetzen?
Am besten kuckt man Assembler-Code von beiden übersetzten Varianten.
Ich denke, deine Variante erzeugt mehr Code, da zuerst Pin-Zustand
gelesen sein muß, danach invertiert und wieder in Port geschrieben.
Etwa so:
1
in r16, PORTB
2
ldi r17, BITMASK
3
eor r16, r17
4
out PORTB, r16
insgesamt 4 Word 4 Cycles
Wenn einfach auf 0 oder 1 setzen, dann wird für die meisten ATMega-Ports
kürzere Behehl von Compiler gewählt. Z.B.
1
clr PORTB, PB5
oder
1
setb PORTB, PB5
Jeweils 1 Word 2 Cycles.
Das ist immer so: wenn zu Compilieren-Zeit alle Daten bekannt sind,
bekommt man kürzere Maschinencode als mit Variablen.
Maxim B. schrieb:> Ich denke, deine Variante erzeugt mehr Code, da zuerst Pin-Zustand> gelesen sein muß, danach invertiert und wieder in Port geschrieben.
Da ist nix mit Port!
Eine einfache Variable, es ist.
Ist ledState eine Variable in RAM, die nichts außen macht?
Wenn man damit LED ansteuern will, dann ist das bestimmt Portpin.
Es ist besser, keine Variablen dort zu benutzen, wo es um im voraus
bekannte Ports geht. So wird Programm schneller und kürzer.
Sonst bekommen wir 2000 Worte in Code, wo auch 5 genügt.
Arduino Fanboy D. schrieb:> Natürlich kann die Ausgabe durch direkte Registerzugriffe deutlich> beschleunigt werden.>> PORTB = _BV(PB5); // toggelt den Pin in einem Takt
Möp. Dazu musst du das PINB Register beschreiben. Aber erkläre das mal
einem Prinzipienreiter (wenn man einen Output machen will, soll das auch
so heissen ...).
Stefanus F. schrieb:> Möp. Dazu musst du das PINB Register beschreiben.
Da hast du wahr!
Arduino Fanboy D. schrieb:>> PORTB = _BV(PB5); // toggelt den Pin in einem Takt
PINB = _BV(PB5); // toggelt den Pin in einem Takt
Muss es heißen.
Wenn ich beim Arduino schnell nen einfachen Blinker brauche, nehm ich
folgende Zeile:
digitalWrite(LED_BUILTIN, millis() & 0x80); // Blinken mit 4Hz Takt
Hummelfan schrieb:> Wenn ich beim Arduino schnell nen einfachen Blinker brauche, nehm ich> folgende Zeile:> digitalWrite(LED_BUILTIN, millis() & 0x80); // Blinken mit 4Hz Takt
Das erinnert mich an den "Blink-Merker" bei der S7 ;-)
Hummelfan schrieb:> Wenn ich beim Arduino schnell nen einfachen Blinker brauche, nehm ich> folgende Zeile:> digitalWrite(LED_BUILTIN, millis() & 0x80); // Blinken mit 4Hz Takt
Klar: man kann auch mit einem Mikroskop statt Hammer die Nägel
einschlagen...
Mark B. schrieb:> Wenn die einzelnen Funktionen kurz und übersichtlich sind, weil man> vernünftig programmiert hat, ist es relativ egal ob die gesamte Software> nun aus 300 oder 3.000 Zeilen Code besteht.
Das sehe ich genauso. Auch 30.000 Zeilen kann man noch nach Lehrbuch
coden, so mit McCabe einstellig und nur eine Bildschirm-Seite. Skalieren
tut es aber (leider) nicht.