Forum: Mikrocontroller und Digitale Elektronik Arduino Programm: Erklärung Ausrufezeichen


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Erhard S. (Gast)


Lesenswert?

Hallo,

ich muß mich in ein Arduinoprogramm einarbeiten.
Dabei bin ich auf Befehle gestoßen, die ein Ausrufezeichen vorangestellt 
haben.
Hier ein Auszug als Beispiel:

//Eingänge einlesen
  bool button_red_state = !digitalRead(BUTTON_RED);
  bool button_yellow_state = !digitalRead(BUTTON_YELLOW);
  bool button_green_state = !digitalRead(BUTTON_GREEN);
  bool button_blue_state = analogRead(BUTTON_BLUE) > 100 ? false : true; 
//Eingänge sind Analog-only
  bool button_white_state = analogRead(BUTTON_WHITE) > 100 ? false : 
true;
  bool button_state = !digitalRead(BUTTON);
  bool endswitch_state = !digitalRead(ENDSWITCH);

Was hat das Ausrufezeichen für eine Funktion?

Hier die Quelle des Programms:

http://crlf.eu/2017/01/siemens-s7-mit-arduino-ueber-modbus-tcp/

von Beni (Gast)


Lesenswert?


von Erhard S. (Gast)


Lesenswert?

Danke,

an den naheliegensten Ort zum suchen habe ich nicht gedacht.

von Wolfgang (Gast)


Lesenswert?

Erhard S. schrieb:
> an den naheliegensten Ort zum suchen habe ich nicht gedacht.

Jedes C Grundlagenbuch im Abschnitt "Operator" hätte dir auch geholfen. 
Das hat mit Arduino speziell gar nichts zu tun.
https://de.wikibooks.org/wiki/C-Programmierung:_Liste_der_Operatoren_nach_Priorit%C3%A4t

von Jemand (Gast)


Lesenswert?

Hallo

meine Empfehlung:

Mach nicht den gleichen Fehler wie ich ihn auch gemacht habe:

Als Anfänger sich "einfach" ein umfangreiches und trickreiches Programm 
anschauen und verstehen zu wollen zu dieses Funktioniert - das ist der 
schwere und oft verwirrende Weg Programmieren zu erlernen, auch wenn 
natürlich "echte" Anwendungen mit Tiefgang interessanter sind als eine 
Blinkschaltung oder einen Ausgang setzen und abschalten.

Nein fange bei Adam und Eva an, auch wenn es oft erstmal nervig und 
scheinbar trivial ist, überspringe nicht langweilige Teilkapitel oder 
Sachen von den du meinst du du sie nie brauchen wirst.

Ich musste das selber erfahren, es geht leider nichts an den 
beschwerlichen Lernweg von Null aus vorbei auch wenn dabei einen 
manchmal die Lust vergeht oder der Sinn von bestimmten Lerninhalten erst 
mal verborgen bleibt.
Letztendlich braucht man alles später doch einmal, und sei es "nur" um 
ein Programm nach zu vollziehen.

Jemand

von Thomas L. (thomas_l359)


Lesenswert?

Nur was macht das "!" vor digitalRead() wenn der Eingang der ausgelesen 
werden soll "1" oder "0" ist? ! bedeutet Logisches NICHT und wie 
weiter????

von Horst V. (hoschti)


Lesenswert?

Du must die Zeile bis zum abschließenden Semikolon betrachten. Das ist 
eine Zuweisung an "button_red_state". Dieser Variablen wird der negierte 
(ausgedrückt durch dss Ausrufezeichen) Rückgabewert der Funktion 
"digitalRead(...)" zugewiesen.

Der Zeilenumbruch in der Anzeige hier im Forum verwirrt zugegebenermaßen 
ein wenig.

: Bearbeitet durch User
von Rainer W. (rawi)


Lesenswert?

Thomas L. schrieb:
> ! bedeutet Logisches NICHT und wie weiter????

Lies dich in die Grundlagen von C ein, insbesondere über die Darstellung 
boolscher Werte.

von Re (r42)


Lesenswert?

Thomas L. schrieb:
> Nur was macht das "!" vor digitalRead() wenn der Eingang der ausgelesen
> werden soll "1" oder "0" ist?

Dasselbe:
Aus     "0" (false) wird true
und aus "1" (true) wird false.

In C/C++ gibt es native "bool" nur erst seit wenigen Jahrzehnten, vorher 
wurden dazu simple integers benutzt und aus Abwärtskompatibilität werden 
alle int, die 0 sind, generell als "false" gewertet und alle anderen als 
"true".

Warum digitalRead() für die Rückgabe eines "bool" einen "int32_t" 
bemüht, der auf einem 8-Bit-AVR auch noch unnötig teuer ist, erschließt 
sich mir auch nicht. Arduino eben...


HTH (re)

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

Naja, den ternären Operator kann man zwar verwenden, es wird allgemein 
dazu aber abgeraten. Ein if() ist lesbarer, auch wenn es mehr 
Schreibarbeit ist.
1
 
2
bool button_blue_state = analogRead(BUTTON_BLUE) > 100 ? false : true; 
3
4
// identisch mit 
5
6
if (analogRead(BUTTON_BLUE) > 100) blue_button = false; else blue_button = true;
7
8
// oder so mit eingerückter Formatierung
9
10
if (analogRead(BUTTON_BLUE) > 100) {
11
    blue_button = false;
12
} else {
13
    blue_button = true;
14
}

: Bearbeitet durch User
von Thomas L. (thomas_l359)


Lesenswert?

Das bedeutet der Wert von (button_red_state) wird negiert, bedeutet ist 
er HIGH wird daraus LOW und umgekehrt. Richtig?

von Jörg K. (joergk)


Lesenswert?

Thomas L. schrieb:
> Das bedeutet der Wert von (button_red_state) wird negiert, bedeutet ist
> er HIGH wird daraus LOW und umgekehrt. Richtig?

!Falsch :-)

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Falk B. schrieb:
> Naja, den ternären Operator kann man zwar verwenden, es wird allgemein
> dazu aber abgeraten. Ein if() ist lesbarer, auch wenn es mehr
> Schreibarbeit ist.

Falsche Begründung!
Ganz falsch.

Der ternäre Operator ist ganz klar ein Daten bezogener Operator. Er 
manipuliert den Datenfluss.

If ist ein den Programmfluss veränderndes Statement.

Verwendet man beide für ihren jeweils vorgesehenen Zweck, ist alles ok.

Es gibt keine guten oder bösen Sprachmittel.
Nur eine falsche Verwendung.

von Alexander (alecxs)


Lesenswert?

Ich fühl mich grad LOW Wenn ich jetzt negativ werde, bin ich dann HIGH?

von Falk B. (falk)


Lesenswert?

Arduino F. schrieb:
> Falsche Begründung!
> Ganz falsch.

Hast ja Recht. Ich halt nur ein Hardwerker ;-)

von Bradward B. (Firma: Starfleet) (ltjg_boimler)


Lesenswert?

>> Naja, den ternären Operator kann man zwar verwenden, es wird allgemein
>> dazu aber abgeraten. Ein if() ist lesbarer, auch wenn es mehr
>> Schreibarbeit ist.

> Der ternäre Operator ist ganz klar ein Daten bezogener Operator. Er
> manipuliert den Datenfluss.
>
> If ist ein den Programmfluss veränderndes Statement.

Eine atomare Register-Transfer Anweisung ist kein (Daten-) Fluß, dagegen 
verursacht das automatische Ticken des ProgrammCounters schon einen 
(Control/Programm-)Fluß.

Oder man schaut sich das Resultat des Compilerdurchlaufes an.
Wenn für "if then else" der selbe oder äquivalenter Coder wie für "?:" 
erzeugt wird, ist die Wahl der Notation tatsächlich funktional gleich 
und man entscheidet sich dem der natürlichen Sprache näher Gestellten 
(bessere Lesbarkeit).

Der generierte Code für die jeweilige Variante "kann" bei bestimmten 
CPU-Architekturen unterschiedlich ausfallen. In einem FPGA/ASIC kann man 
tatsächlich einen umschaltbaren Datenpfad (Multiplexor) implementieren.

Im Fall Arduino (Load/Store Maschine) dürfte für beide Notationen der 
selbe Code generiert werden.

https://de.wikipedia.org/wiki/Load/Store-Architektur

: Bearbeitet durch User
von Yalu X. (yalu) (Moderator)


Lesenswert?

Falk B. schrieb:
> Naja, den ternären Operator kann man zwar verwenden, es wird allgemein
> dazu aber abgeraten. Ein if() ist lesbarer, auch wenn es mehr
> Schreibarbeit ist.

Im konkreten Fall
1
bool button_blue_state = analogRead(BUTTON_BLUE) > 100 ? false : true;

würde ich keinen ternären Operator und erst recht kein if-else
verwenden, sonder ganz einfach schreiben:
1
bool button_blue_state = analogRead(BUTTON_BLUE) <= 100;

von Bruno V. (bruno_v)


Lesenswert?

Yalu X. schrieb:
> sondern ganz einfach schreiben:
> bool button_blue_state = analogRead(BUTTON_BLUE) <= 100;

Das wäre mir eine Nummer zu riskant: Bei if, while, for oder ? erwarte 
ich einen Vergleich. Wenn er entfällt (z.B. : "if(a) ..."), ist auch das 
relativ schnell klar.

Dein Beispiel ist eher wie "while(a=b) ...": Man fragt sich 
unwillkürlich: gewollt oder Tippfehler? Und das behindert den Lesefluss.

von Falk B. (falk)


Lesenswert?

Yalu X. schrieb:
> würde ich keinen ternären Operator und erst recht kein if-else
> verwenden, sonder ganz einfach schreiben:
> bool button_blue_state = analogRead(BUTTON_BLUE) <= 100;

Das ist zwar korrekt, aber leider auch wieder arg in Richtung 
Hackermist. Würde ich nicht empfehlen. Denn der Sinn er Anweisung ist 
eine Auswahl. if else. Dann sollte man das auch so hinschreiben.

WORM. Write once, read many (times).

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Falk B. schrieb:
> Das ist zwar korrekt, aber leider auch wieder arg in Richtung
> Hackermist. Würde ich nicht empfehlen. Denn der Sinn er Anweisung ist
> eine Auswahl. if else. Dann sollte man das auch so hinschreiben

Wow!

Falk B. schrieb:
> Ich halt nur ein Hardwerker

Bruno V. schrieb:
> Das wäre mir eine Nummer zu riskant:
Ich sehe da nichts riskantes!

: Bearbeitet durch User
von Rolf (rolf22)


Lesenswert?

Falk B. schrieb:
> Denn der Sinn er Anweisung ist eine Auswahl. if else. Dann sollte
> man das auch so hinschreiben.

Richtig. Ich nenne das "defensives Codieren".

Der Compiler optimiert das ohnehin, man spart da also nichts.

von Alexander (alecxs)


Lesenswert?

Ich freue mich nur über das Datum des Threads.

von Rainer W. (rawi)


Lesenswert?

Alexander schrieb:
> Ich freue mich nur über das Datum des Threads.

Warum?
Das Problem ist so alt wie diese Sprache.
Sie stammt aus den Hochzeiten der Assemblerprogrammierung und gibt einem 
Freiheiten, die eigentlich keiner (mehr) haben möchte. Deshalb gibt es 
je nach Schule, einen Haufen Regeln, wie man irgendetwas zu formulieren 
hat.

: Bearbeitet durch User
von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Rainer W. schrieb:
> Deshalb gibt es
> je nach Schule, einen Haufen Regeln, wie man irgendetwas zu formulieren
> hat.

Philosophie?

Leitmotiv:
> 1. Jedes vermeidbare IF ist ein böses IF
> 2. Jedes Vermiedene IF ist ein gutes IF
Das IF an der Stelle, kann durch jedes andere Statement/Pattern ersetzt 
werden

Übrigens:
Zwischen den beiden Merksätzen findet sich eine kleine, aber feine 
Hysterese. Und genau in dieser Hysterese steckt idealer Weise im 
Abschluss das fertige Programm. Erwachsen aus der Summe der gemachten 
Kompromisse.

von Bradward B. (Firma: Starfleet) (ltjg_boimler)


Lesenswert?

>> Deshalb gibt es
>> je nach Schule, einen Haufen Regeln, wie man irgendetwas zu formulieren
>> hat.
>
> Philosophie?

Neh. Primitiver. StyleGuide.

https://de.wikipedia.org/wiki/Gestaltungsrichtlinie

: Bearbeitet durch User
von Sherlock 🕵🏽‍♂️ (rubbel-die-katz)


Lesenswert?

Arduino F. schrieb:
> Jedes vermeidbare IF ist ein böses IF

So ein Blödsinn.
1
if ( belastung()>100 && dauer()>KURZ ) {
2
    leistung_herunter_fahren();
3
}

Nun spare ich das if:
1
belastung()>100 && dauer()>KURZ && leistung_herunter_fahren();

Ist das etwa besser?

Das kann man noch wesentlich komplexer verschachteln, wenn man will. Zum 
Beispiel:
1
if ( belastung()>100 ) {
2
    if (dauer()>KURZ) {
3
        leistung_herunter_fahren();
4
    }
5
    else {
6
        warnung_anzeigen();
7
    }
8
}

Nun spare ich das if:
1
belastung()>100 && (dauer()>KURZ && leistung_herunter_fahren()) || warnung_anzeigen();

Ich wette, da erkennen 80% der Leser nicht auf Anhieb, ob das überhaupt 
korrekt ist. Womit das Problem an "Jedes vermeidbare IF ist ein böses 
IF" bestätigt wäre.

Aber so weit muss man gar nicht gehen. Genau so schlecht finde ich 
ellenlange verschachtelte Bedingungen hinter einem if. Eine Aufsplittung 
in mehrere if-Anweiungen macht den Code oft deutlich besser lesbar.

: Bearbeitet durch User
von Yalu X. (yalu) (Moderator)


Lesenswert?

Falk B. schrieb:
> Yalu X. schrieb:
>> würde ich keinen ternären Operator und erst recht kein if-else
>> verwenden, sonder ganz einfach schreiben:
>> bool button_blue_state = analogRead(BUTTON_BLUE) <= 100;
>
> Das ist zwar korrekt, aber leider auch wieder arg in Richtung
> Hackermist.

Nein, das ist überhaupt kein Hackermist.

In
1
  bool button_blue_state = analogRead(BUTTON_BLUE) > 100 ? false : true;

ist
1
  analogRead(BUTTON_BLUE) > 100

ein boolescher Ausdruck, die Ergebnisvariable ist ebenfalls boolesch.
Allerdings die der Ausdruck nicht direkt der Variable zugewiesen werden,
da die Anwendung des ternären Operators eine Negation bewirkt. C/C++ hat
aber bereits einen Negationsoperator (nämlich "!"), weswegen man ihn
nicht neu erfinden muss. Also wird aus der obigen Anweisung zunächst
1
  bool button_blue_state = !(analogRead(BUTTON_BLUE) > 100);

Die Negation einer größer-Operation ist die entsprechende
kleiner-gleich-Operation. Auch den kleiner-gleich-Operator muss man
nicht neu erfinden (C/C++ kennt auch "<="). Also kann die Anweisung
weiter vereinfacht werden zu
1
  bool button_blue_state = analogRead(BUTTON_BLUE) <= 100;

(Wer will, darf den Ausdruck auf der rechten Seite des "=" gerne auch
klammern)

Aussagenlogisch betrachtet ist button_blue_state nichts anderes als
ein Name für die Aussage "Der Analogwert am Pin BUTTON_BLUE ist maximal
100". Diese Erklärung wird sogar ein Nichtprogrammierer sofort
verstehen.

Was soll daran also Hackermist sein?

Durch die Verschwurbelung mittels des ternären Operators oder gar eines
if-else-Konstrukts wird der an sich sehr einfache Sachverhalt nur
künstlich aufgebläht.

Führte man diese Verschwurbelung konsequent für andere als den
"<"-Operator fort, bspw. für den "+"-Operator, würde eine einfache
Integer-Addition so aussehen:
1
  unsigned int a, b, c;
2
  ...
3
  if (a + b == 0)
4
    c = 0;
5
  else if (a + b == 1)
6
    c = 1;
7
  else if (a + b == 2)
8
    c = 2;
9
  else if (a + b == 3)
10
    c = 3;
11
  ...

Das ist zwar durchaus korrekt, aber man könnte die lange if-else-Kette
auch einfach ersetzen durch
1
  c = a + b;

Ist diese Verkürzung deiner Ansicht nach ebenfalls Hackermist?

von Sherlock 🕵🏽‍♂️ (rubbel-die-katz)


Lesenswert?

Yalu X. schrieb:
> Was soll daran also Hackermist sein?

Nichts. Ich würde nur den unpassenden Namen der Variable kritisieren.

button_blue_state kann true oder false sein. Was bedeuten diese Werte? 
blue_button_is_pressed oder blue_button_is_released wären viel 
aussagekräftiger.

: Bearbeitet durch User
von Alexander (alecxs)


Lesenswert?

Sherlock 🕵🏽‍♂️ schrieb:
> Ich wette, da erkennen 80% der Leser nicht auf Anhieb, ob das überhaupt
> korrekt ist.

Ich erkenne dass Du die Klammer falsch gesetzt hast.

von Thomas L. (thomas_l359)


Lesenswert?

OK Danke verstanden.

von Bruno V. (bruno_v)


Lesenswert?

Sherlock 🕵🏽‍♂️ schrieb:
> belastung()>100 && (dauer()>KURZ && leistung_herunter_fahren()) ||
> warnung_anzeigen();

Alexander schrieb:
> Ich erkenne dass Du die Klammer falsch gesetzt hast.

M.E. fehlt auch ein "Abbruch" hinter "leistung_herunter_fahren()", falls 
die Funktion 0 zurückliefert.

Hier ohne Klammern (dann können sie zumindest nicht falsch sein ;-)
1
belastung()<=100 || dauer()>KURZ && leistung_herunter_fahren() && 1 || warnung_anzeigen();

von Yalu X. (yalu) (Moderator)


Lesenswert?

Bruno V. schrieb:
> Hier ohne Klammern (dann können sie zumindest nicht falsch sein ;-)
>
> belastung()<=100 || dauer()>KURZ && leistung_herunter_fahren() && 1 || 
warnung_anzeigen();

Sie können aber fehlen ;-)

Außerdem bewirkt das "&& 1" überhaupt nichts. Da sollte wohl ein "||"
stehen.

Richtiger ist dieses hier:
1
  belastung() <= 100
2
  || dauer() > KURZ
3
     && (leistung_herunter_fahren() || true)
4
     || warnung_anzeigen();

oder, um näher an der Struktur von Sherlocks Beispiel zu bleiben:
1
  belastung() > 100
2
  && ( dauer() > KURZ
3
       && (leistung_herunter_fahren() or true)
4
       || warnung_anzeigen() )

Aber auch das funktioniert nur dann, wenn die Rückgabewerte von
leistung_herunter_fahren() und warnung_anzeigen() legale Operandentypen
für && und || sind. Ohne benutzerdefinierte Konvertierungsfunktionen
und/oder Überladungen von && und || ist dies für Funktionen mit
Rückgabetyp void, struct und class nicht der Fall.

Dass es offensichtlich nicht ganz leicht ist, den korrekten logischen
Ausdruck als Ersatz für die if-if-else-Anweisung zu finden, zeigt, dass
hier die if-if-else-Schreibweise die bessere Wahl ist.

Die vom Arduino Fanboy aufgestellten Regelsätze

Arduino F. schrieb:
> Der ternäre Operator ist ganz klar ein Daten bezogener Operator. Er
> manipuliert den Datenfluss.
>
> If ist ein den Programmfluss veränderndes Statement.

und

Arduino F. schrieb:
> Leitmotiv:
>> 1. Jedes vermeidbare IF ist ein böses IF
>> 2. Jedes Vermiedene IF ist ein gutes IF

widersprechen sich teilweise, so auch in Sherlocks Beispiel. Wenn man
als weitere Regel hinzufügt, dass im Fall eines Widerspruchs der erste
Regelsatz anzuwenden ist, dann passt alles, und sie sind kein

Sherlock 🕵🏽‍♂️ schrieb:
> Blödsinn

: Bearbeitet durch Moderator
von Falk B. (falk)


Lesenswert?

Yalu X. schrieb:
>> Das ist zwar korrekt, aber leider auch wieder arg in Richtung
>> Hackermist.
>
> Nein, das ist überhaupt kein Hackermist.
>
> In
>   bool button_blue_state = analogRead(BUTTON_BLUE) > 100 ? false : true;
>
> ist
>   analogRead(BUTTON_BLUE) > 100
>
> ein boolescher Ausdruck, die Ergebnisvariable ist ebenfalls boolesch.

Keine Sorge, die Syntax verstehe ich schon.

> Was soll daran also Hackermist sein?

Anstatt einen einfachen, klaren Lesefluße zu erlauben, wird mit den C 
inherenten logischen Ausdrücken hantiert. Das spart ein wenig 
Schreibarbeit, verschlechtert aber die (flüssige) Lesbarkeit.

> Durch die Verschwurbelung mittels des ternären Operators oder gar eines
> if-else-Konstrukts wird der an sich sehr einfache Sachverhalt nur
> künstlich aufgebläht.

An if-else ist rein gar nichts verschwurbelt! Du betreibst gerade 
Propaganda!
Es gibt nicht umsonst den C obfuscation Contest! Dein Logikausdruck ist 
der erste, wenn auch kleine Schritt dahin.
Es gibt Style Guides, die empfehlen die möglichst leicht lesbare und am 
wenigsten missverständlichste Variante eines Konstrukts hinzuschreiben. 
Das muss nicht immer die kürzeste sein.

> Führte man diese Verschwurbelung konsequent für andere als den
> "<"-Operator fort, bspw. für den "+"-Operator, würde eine einfache
> Integer-Addition so aussehen:

Hör auf solchen Käse zu erzählen. Du übertreibst massiv. Polemik 
beherrschen wir alle gut genug.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Falk B. schrieb:
> Naja, den ternären Operator kann man zwar verwenden, es wird allgemein
> dazu aber abgeraten.

Unsinn. Es wird nicht "allgemein" davon abgeraten.

Aber wenn man ein sinnvolles Konstrukt nie verwendet oder die Syntax 
nicht kennt, kann man natürlich Vermeidungs"taktik" betreiben.  Oder 
vertraut damit werden.
1
bool button_blue_state = analogRead(BUTTON_BLUE) <= 100;

von Yalu X. (yalu) (Moderator)


Angehängte Dateien:

Lesenswert?

Jeder darf natürlich seine eigene Meinung haben. So auch Falk und auch
die KI.

Ich habe die Fragestellung mal spaßeshalber (etwas vereinfacht) in
ChatGPT eingegeben:
1
The following three C++ code snippets do the same thing:
2
3
Snippet A:
4
5
bool c;
6
if (x > 1)
7
  c = true;
8
else
9
  c = false;
10
11
Snippet B:
12
13
bool c = x > 1 ? true : false;
14
15
Snippet C:
16
17
bool c = x > 1;
18
19
Which one should be preferred in terms of readability?

Antwort siehe Anhang.

Aber wie gesagt: Auch das ist nur eine (wenn auch IMHO recht gut
begründete) Meinung.

von Falk B. (falk)


Lesenswert?

Yalu X. schrieb:
> Aber wie gesagt: Auch das ist nur eine (wenn auch IMHO recht gut
> begründete) Meinung.

Naja, sachlich spricht wenig gegen die Begründungen von Chat GPT. Und 
kompakte Schreibweisen sind an sich oft schon günstig(er). Aber es 
bleibt die Frage wie weit man damit gehen will oder sollte.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Falk B. schrieb:
> Aber es bleibt die Frage wie weit man damit gehen will

Der ternäre Operator hat noch einen weitere Vorteil:

Er macht klar, dass ein Wert gesetzt wird, und er kann in einer 
Initialisierung z.B. einer const Variable verwendet werden:
1
const int var = bedingung ? wert1 : wert2;
Wenn hingegen zwei Werte zu setzen sind, oder nur ein Zweig den Wert 
setzt, dann if-else:
1
if (bedingung)
2
  var = wert1;
3
else
4
  var2 = wert1;

Falls der Ternary länglich wird, kann er auch umgebrochen werden.  Gute 
Editoren unterstützen entsprechende Einrückungen. Beispiel:
1
var = bedingung
2
      ? wert1
3
      : Wert2;

von Yalu X. (yalu) (Moderator)


Lesenswert?

Falk B. schrieb:
> Aber es bleibt die Frage wie weit man damit gehen will oder sollte.

Natürlich nur so weit, wie es Vorteile bringt :)

Wenn man sich schon etwas länger mit einer Programmiersprache
beschäftigt und immer wieder einmal schaut, wie andere es machen¹,
bekommt man allmählich ein ganz gutes Gefühl dafür, wo die Verschlankung
von Quellcode noch zur Übersichtlichkeit beiträgt, und ab wann der Code
kryptisch zu werden droht.

─────────────
¹) In diesem Zusammenhang spielen auch Idiome eine wichtige Rolle,
   s. https://de.wikipedia.org/wiki/Idiom_(Softwaretechnik)

von Joachim B. (jar)


Lesenswert?

Yalu X. schrieb:
> bool c;
> if (x > 1)
>   c = true;
> else
>   c = false;

ist das immer so richtig?

Ich kenne
1
false = 0;
2
true = !false;

denn x > 1 schließt ja -1 aus und da -1 auch != 0 ist müßte es true sein

von Yalu X. (yalu) (Moderator)


Lesenswert?

Joachim B. schrieb:
> ist das immer so richtig?
> ...
> denn x > 1 schließt ja -1 aus und da -1 auch != 0 ist müßte es true sein

Du musst unterscheiden zwischen der Variable x (die kann irgendeinen
beliebigen Wert annehmen) und dem gesamten Bedingungsausdruck (x>1), der
nur die Werte true und false (true für x>1 und false für x≤1) annehmen
kann.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Johann L. schrieb:
> Der ternäre Operator hat noch einen weitere Vorteil:
> ...

Der ternäre Operator ist auch dann sehr praktisch, wenn die linke Seite
der Zuweisung ein etwas länglicher Ausdruck ist:
1
etwas[einindex].teildavon[einandererindex] = bedingung ? wert1 : wert2;

In if-else-Schreibweise sieht das so aus:
1
if (bedingung)
2
  etwas[einindex].teildavon[einandererindex] = wert1;
3
else
4
  etwas[einindex].teildavon[einandererindex] = wert2;

Der Leser ist hier also erst einmal damit beschäftigt nachzuprüfen, ob
die Zuweisung im if- und im else-Zweig tatsächlich an das gleiche
Struktur-/Array-Element erfolgt.

Nicht umsonst wurde in Python immer wieder das Fehlen des ternären
Operators kritisiert. Irgendwann hatte Guido dann ein Einsehen und hat
ihn implementiert (wenn auch mit einer anderen Syntax als in C), und
alle (oder zumindest die meisten) haben sich gefreut wie an Weihnachten
:)

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Falk B. schrieb:
> Anstatt einen einfachen, klaren Lesefluße zu erlauben,

Wenn dein Lesefluss von dem ternären Operator gestört wird, dann kann 
man das wohl deiner Übung zurechnen. bzw. der mangelnden Übung, Evtl. 
Verursacht durch Ablehnung und Vermeidungsstrategien.
Also eher dein Innenwelt Problem, als eine Eigenschaft des Operators.

Weder der ternäre Operator, if und auch goto sind die ideale Losung für 
jede beliebige Problemstellung.
Aber in einigen Fällen durchaus nützlich.

Grundsätzlich:
Die Idee irgendwelche Sprachkonstrukte zu tabuisieren halte ich für 
(suchs dir selber aus).
Vorschlag: z.B. Für irregeleiteten Dogmatismus.

von Falk B. (falk)


Lesenswert?

Johann L. schrieb:
>> Aber es bleibt die Frage wie weit man damit gehen will
>
> Der ternäre Operator hat noch einen weitere Vorteil:
>
> Er macht klar, dass ein Wert gesetzt wird, und er kann in einer
> Initialisierung z.B. einer const Variable verwendet werden:
> const int var = bedingung ? wert1 : wert2;

Ich hab mal gelesen, daß man den ternären Operator im "normalen" 
Programmfluß eher sparsam einsetzen sollte und sich auf Makros oder eben 
die obige Zuweise bechränken sollte. OK, bei längerem Nachdenken ist die 
Zuweisung
1
bool button_blue_state = analogRead(BUTTON_BLUE) <= 100;

an sich auch "normal", denn in if() nutzen man ja auch die gleichen 
Ausdrücke, nur daß der logische Wert nicht zugewiesen wird. Hmmm.

von Falk B. (falk)


Lesenswert?

Arduino F. schrieb:
> Falk B. schrieb:
>> Anstatt einen einfachen, klaren Lesefluße zu erlauben,
>
> Wenn dein Lesefluss von dem ternären Operator gestört wird,

Wird er nicht wesentlich, ich habe das aber mehrfach in Style Guides 
gelesen.

> Grundsätzlich:
> Die Idee irgendwelche Sprachkonstrukte zu tabuisieren halte ich für
> (suchs dir selber aus).
> Vorschlag: z.B. Für irregeleiteten Dogmatismus.

Ohhh, Vorsicht! Das setzt eine ideale Sprache voraus! Wenn man JEDEN 
Blödsinn im realen Leben macht, der mit technisch C möglich ist, kommt 
man beim obfuscation contest raus! Es gibt schon VIELE gute Gründe, 
warum es Style Guides oder im Extremfall solche Geschichten wie MISRA 
oder LINT gibt!

von Bruno V. (bruno_v)


Lesenswert?

Joachim B. schrieb:
> ist das immer so richtig?

Das Beispiel ist mit "1" leicht irreführend. Es wäre mit "x>33" oder 
"x==7" klarer, dass es um eine beliebige Bedingung geht, nicht darum, 
was true oder false repräsentieren.

von Joachim B. (jar)


Lesenswert?

Bruno V. schrieb:
> Das Beispiel ist mit "1" leicht irreführend.

das kam aber nicht von mir

Yalu X. schrieb:
> if (x > 1)
>   c = true;
> else
>   c = false;

damit wäre ja alles < 1 false

ich lernte aber das 0 = false und true != false damit lege ich mich auf 
keine Zahl fest für true

zumal ja bool schon vorgegeben ist

Yalu X. schrieb:
> bool c;

also was soll dieser Einwand mit >1 und <-1 ?

für mich bleibt klar false 0 und true !false

von Roland F. (rhf)


Lesenswert?

Hallo,
Joachim B. schrieb:
> ich lernte aber das 0 = false und true != false damit lege ich mich auf
> keine Zahl fest für true

Das ist ja auch richtig, aber du verwechselst offenbar die 1 aus "x > 1" 
mit dem Wahrheitswert für true. 1 ist aber in diesem Fall einfach nur 
ein Zahlenwert, der mit dem Wert für x verglichen wird.

rhf

von Joachim B. (jar)


Lesenswert?

offensichtlich, ist ja auch schon spät, Knoten im Kopf

ich bleibe lieber beim für mich leichteren Verständnis

Joachim B. schrieb:
> bool c;
> false = 0;
> true = !false;

: Bearbeitet durch User
von Bruno V. (bruno_v)


Lesenswert?

Joachim B. schrieb:
> offensichtlich, ist ja auch schon spät, Knoten im Kopf
kein Ding. Einfach in ein paar Tagen in Ruhe nochmal lesen.



> ich bleibe lieber beim für mich leichteren Verständnis
>
> Joachim B. schrieb:
>> bool c;
>> false = 0;
>> true = !false;
Wir wissen, was Du sagen willst. Und das (was Du sagen willst) ist auch 
richtig. false ist 0 in C und true ist !false.

Aber: die Repräsentation von true und false hat nichts (!) mit dem 
Beispiel von Yalu zu tun.

Denke Dir sein Beispiel als

Joachim B. schrieb:
> Yalu X. schrieb:
>> if (x > 37)
>>   c = true;
>> else
>>   c = false;

: Bearbeitet durch User
von Rainer W. (rawi)


Lesenswert?

Alexander schrieb:
> Ich erkenne dass Du die Klammer falsch gesetzt hast.

Ich erkenne, dass du nicht mit Steinen schmeißen solltest, solange du im 
Glashaus sitzt. ;-)

von Roland F. (rhf)


Lesenswert?

Hallo,
Bruno V. schrieb:
> Denke Dir sein Beispiel als
>
> Joachim B. schrieb:
>> Yalu X. schrieb:
>>> if (x > 37)
>>>   c = true;
>>> else
>>>   c = false;

Vielleicht hilft es wenn man den Vergleich C-untypisch 'geschwätziger' 
formuliert:

if ((x > 37) == true)

rhf

von Joachim B. (jar)


Lesenswert?

Bruno V. schrieb:
> Denke Dir sein Beispiel als
>
> Joachim B. schrieb:
>> Yalu X. schrieb:
>>> if (x > 37)
>>>   c = true;
>>> else
>>>   c = false;

ich kapiere es nicht, wenn x == 36 ist wäre c = false, sieht für mich 
nicht richtig aus und wenn es richtig ist, ist es nur undurchsichtig!

wenn schon denn:

if x
 c = true;
else
 c = false;

von Falk B. (falk)


Lesenswert?

Joachim B. schrieb:

>wenn x == 36 ist wäre c = false, sieht für mich
> nicht richtig aus und wenn es richtig ist, ist es nur undurchsichtig!
>
> wenn schon denn:
>
> if x
>  c = true;
> else
>  c = false;

Unsinn. x > 1 ist in C ein (logischer) Ausdruck (expression) , der auf 
seinen logischen Wahrheitsgehalt geprüft wird. Das Ergebnis dieser 
Prüfung kann wahr (true) oder falsch (false) sein und wird hier der 
boolschen Variable c zugewiesen. Es kann aber auch in einem komplexeren 
Ausdruck weiter verwendet werden.
1
int x = 36;
2
bool c = x > 1,

https://www.simplilearn.com/tutorials/c-tutorial/guide-on-expressions-in-c

"Relational Expressions:

Relational operators >, <, ==,!= etc are used to compare 2 operands. 
Relational expressions consisting of operands, variables, operators, and 
the result after evaluation would be either true or false."

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Joachim B. schrieb:
> wenn schon denn:
>
> if x
>  c = true;
> else
>  c = false;
Was ist das für eine lustige Sprache.

Du verwirrst mich!
Manchmal sprichst du über den Datentype bool.
Manchmal über die automatischen Konvertierungen.
Manchmal C,
Manchmal C++(zumindest ist das hier ein Arduino Thread)

1
bool c;
2
int x=42;
3
c=x;

von Joachim B. (jar)


Lesenswert?

Arduino F. schrieb:
> Du verwirrst mich!

bin ja selber verwirrt

Falk B. schrieb:
> x > 1 ist in C ein (logischer) Ausdruck (expression)

ach [/LORIOT]

nur wenn X == -1 ist gilt

Falk B. schrieb:
> int x = 36;
> bool c = x > 1,

ja nicht (allerdings ist ja c = x > 1 ja eine Zuweisung mit c = 
vermutlich verwirrt mich dieses)

Man kann alles bei #C beliebig kompliziert oder verworren darstellen und 
ich wüßte nicht warum man dies tun sollte.

: Bearbeitet durch User
von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Joachim B. schrieb:
> bei #C

Die vierte Sprache.......

Bitte konzentriere dich!

von Falk B. (falk)


Lesenswert?

Arduino F. schrieb:
>> bei #C
>
> Die vierte Sprache.......

Die so gar nicht heißt. Es ist C#!

https://de.wikipedia.org/wiki/C-Sharp

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Falk B. schrieb:
> Es ist C#!

Mir egal!
Ihm schreibt #C, ohne zu sagen was ihm damit meint.

von Bruno V. (bruno_v)


Lesenswert?

Joachim B. schrieb:
> ich kapiere es nicht, wenn x == 36 ist wäre c = false, sieht für mich
> nicht richtig aus und wenn es richtig ist, ist es nur undurchsichtig!

Das sind Beispiele.

X ist eine beliebige variable, z.B. die Anzahl von Gummibärchen in 
meiner Hand.

c ist einfach nur eine Variable, die angibt, ob ich genug habe. Und in 
diesem Beispiel ist c = true, wenn x == 39 ist, aber false wenn x == 
36 ist.

In Deinen Beispielen scheinen x und c irgendwie das gleich aussagen zu 
wollen.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Re schrieb:
> Warum digitalRead() für die Rückgabe eines "bool" einen "int32_t"
> bemüht, der auf einem 8-Bit-AVR auch noch unnötig teuer ist, erschließt
> sich mir auch nicht. Arduino eben..

Unwissen, oder absichtliches Arduino Bashing?
Es wird int verwendet, nicht uint32_t
Siehe: 
https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/wiring_digital.c#L165

Jetzt kann man sagen: 16Bit ist immer noch zuviel.
Andererseits stammt Arduino aus der Processing Ecke.
bzw. hat das Processing als Vorlage für viele Arduino Funktionen gedient
https://processing.org/reference/libraries/io/GPIO_digitalRead_.html
Und dort ist es eben ein int als Rückgabewert.

Auch gab es noch kein natives/gemeinsames bool in C bzw. C++ als Arduino 
erfunden wurde.

Ansonsten gilt, wie immer:
Wenn einem digitalRead() nicht gefällt, dann baut man sich ein eigenes.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.