Hallo, ich habe mal eine generelle Frage, ich habe einen Codeschnipsel gefunden.
Lese ich das richtig, dass das eine Kurzschreibweise für eine If-Bedingung ist und wenn die Werte identisch sind, das bool True zurückgegeben wird ?
Ich möchte mir gerne sicher sein, nicht dass ich da etwas falsch lerne, versuche gerade mein Wissen zu fundieren
Das ist eigentlich nur eine logische Verknüpfung - das Ergebnis ist bool, also true oder false.
Hier müssen alle 4 Bytes (wegen der Bezeichnung) mit Denen im Sketch (sesam[] ) übereinstimmen, dann gibt die Funktion ein true zurück.
dann habe ich es richtig hergeleitet, Kurzschreibweisen und Abkürzungen, sind zum Lernen gut, aber machen es auch manchmal schwerer als nötig, wenn es nicht eindeutig beschrieben ist.
Aber dafür, gibt es Gott sei Dank Profis wie euch, die man Fragen kann
Ich verstehe das wie Du, finde es aber reichlich hässlich, weil ich finde, dass es schlecht lesbar ist - man muss es erst Stück für Stück auseinandernehmen/sich genau anschauen, um es als eine if-Missgestalt zu erkennen.
Wenn man eine „Art“ if() meint, sollte man das auch so schreiben. Auf die Nanosekunden, die die Missgestalt vielleicht schneller ausgeführt wird, ist geschi**en.
Benjamin_jerchel:
Lese ich das richtig, dass das eine Kurzschreibweise für eine If-Bedingung ist und wenn die Werte identisch sind, das bool True zurückgegeben wird ?
Ein "if" ist keine Bedinung, die steht in den Klammern dahinter.
Der Codeschnipsel enthält einen Ausdruck (expression), dein ein boolesches Ergebnis liefert, das die Funktion zurückgibt.
gregorss:
um es als eine if-Missgestalt zu erkennen.
Wie schon geschrieben, hat das mit if erstmal überhaupt nichts zu tun. Man kann den zurückgebenen Wert zwar in einem if verwenden, man kann aber auch vieles andere damit machen. Das würde sich erst aus dem gesamten Zusammenhang ergeben (Auch wenn es sehr wahrscheinlich in einem if verwendet wird ).
Für solche Aufgaben gibt es übrigens auch memcmp().
MicroBahner:
Wie schon geschrieben, hat das mit if erstmal überhaupt nichts zu tun. Man kann den zurückgebenen Wert zwar in einem if verwenden, man kann aber auch vieles andere damit machen. Das würde sich erst aus dem gesamten Zusammenhang ergeben (Auch wenn es sehr wahrscheinlich in einem if verwendet wird ).
In natürlicher Sprache würde man sagen: „Gib true zurück, wenn ...“
Also wenn mir das mal kein deutliches if ist ...
Aber je nachdem, wie intensiv man mit Computern/Compilern/C++ zu tun hat, kann man das wahrscheinlich auch anders sehen.
Ich sehe das auch so: Es ist keine Kurzschreibweise.
Wobei man das allerdings auch länger bauen kann, z.B. durch eine if Kaskade.
Aber das wäre voll unnötig, und damit aus meinem Blickwinkel, sogar falsch.
Lerntipp: "Short Circuit Evaluation"
Ein IF ist eine bedingte Verzweigung - DAS sehe ich hier nicht.
Hier wird zwar auch 'geprüft', aber das Ergebnis (müsste das Zero-Flag sein) nur ver-UND-et.
Wenn ALLE Vier wahr sind, braucht diese Verknüpfung am Längsten, da dann Alle ausgewertet werden.
Sobald eines der Statements falsch ist, wird abgebrochen - spart Zeit.
Dann erst wird der Wert als Returnwert zurück gegeben.
in diesem Codeausschnitt gibt es kein if bzw. wenn ...
Es werden nur Daten logisch ver-undet und das Ergebnis davon wird als bool zurückgegeben.
Es findet keine Entscheidung mit dem boolschen Ergebnis statt, es ist nur eine logische Verknüpfung.
Erst der Aufrufer dieser Funktion kann den Rückgabewert auswerteten und damit irgendwas entscheiden mittels if bzw. wenn ...
Ansonsten könnte der Nächste hinter return irgendeine Kette von Additionen setzen und irgendjemand behauptet das wäre ein if. Was natürlich falsch ist. Da nur das Ergebnis der Addition zurückgegeben wird und wieder nur der Aufrufer mit dem Ergebnis irgendwas machen kann.
Stell dir verknüpfte UND Gatter vor mit offen Ausgang. Was mit dem Wert vom Ausgang passiert weiß niemand.
Der Blick liegt auf dem Ausgang, nicht auf den Zwischenergebnissen der UND Gatter.
Ich bin mit meiner if-Ansicht wohl in der Minderheit.
Offensichtlich kann man das unterschiedlich sehen. In meinen Augen wird hier sehr wohl eine Entscheidung getroffen - es soll eben geguckt werden, was eine logische Verknüpfung ergibt. Die Rückgabe soll wahr sein, wenn die Verknüpfung der Ausdrücke wahr ist.
Ob man diese Rückgabe tatsächlich für eine Verzweigung des Programmablaufs verwendet oder nicht, ist meiner Meinung nach unerheblich.
@OP: Wo und wie wird diese Funktion denn verwendet? Wenn der Code nicht zu lang ist, poste ihn bitte in Code-Tags
(-Knopf im Editor) oder als Anhang.
Gruß
Gregor
PS: Da mir einfiel, dass die Herkunft des Codes genannt wurde, habe ich ihn mal kopiert:
//////////////////////////////////////////////////
//
// Demo für RFID-Tags
// auf Basis von MFRC422-Reader
// (c) Michael Stal, 2016
//
//////////////////////////////////////////////////
#include <SPI.h> // Import SPI-Bibiothek
#include <MFRC522.h> // Import RFID-Bibiothek
#include <Servo.h> // Import Servo Bibliothek
///////// Variablen MFRC522 //////////////////////
const int SDAPIN = 53; // Uno => Pin 10
const int RSTPIN = 9; // Uno => Pin 9
MFRC522 rfidReader(SDAPIN, RSTPIN); // RFID-Empfänger
///////// Aktoren: LEDs, Servo ///////////////////
const int REDLED = 13; // Uno -> Pin 8
const int GREENLED = 12; // Uno -> Pin 7
const int SERVOPIN = 11; // Uno -> Pin 6
Servo door; // Türverschluss (Servo)
//////// ID des richtigen RFID-Tags //////////////
byte sesam[] = {0x26, 0xA7, 0xFB, 0x48};
//////////////////////////////////////////////////
//
// setup()
// Initialisieren von SPI,
// seriellem Monitor,
// RFID-Leser
//
//////////////////////////////////////////////////
void setup()
{
door.attach(SERVOPIN);
pinMode(REDLED, OUTPUT);
pinMode(GREENLED, OUTPUT);
pinMode(SERVOPIN, OUTPUT);
Serial.begin(9600); // Serielle Verbindung
SPI.begin(); // SPI-Verbindung aufbauen
rfidReader.PCD_Init(); // Initial. RFID-Leser
Serial.println("Tuerkontrolle aktiviert");
}
//////////////////////////////////////////////////
//
// acceptedRFID()
// Stimmt gelesene RFID
// mit der voreingestellten ID überein?
//
//////////////////////////////////////////////////
bool acceptedRFID(byte uid[4]) {
return
(rfidReader.uid.uidByte[0] == sesam[0]) &&
(rfidReader.uid.uidByte[1] == sesam[1]) &&
(rfidReader.uid.uidByte[2] == sesam[2]) &&
(rfidReader.uid.uidByte[3] == sesam[3]);
}
//////////////////////////////////////////////////
//
// openDoor()
// Servo um 180° in Richtung drehen
//
//////////////////////////////////////////////////
void openDoor() {
for (int pos = 0; pos <= 180; pos++) {
door.write(pos);
delay(20);
}
}
//////////////////////////////////////////////////
//
// closeDoor()
// Servo um 180° in Gegenrichtung drehen
//
//////////////////////////////////////////////////
void closeDoor() {
for (int pos = 180; pos >= 0; pos--) {
door.write(pos);
delay(20);
}
}
//////////////////////////////////////////////////
//
// signalDoorLocked()
// Zugang versperrt =>
// rote LED leuchtet,
// gruene nicht
//
//////////////////////////////////////////////////
void signalDoorLocked() {
digitalWrite(REDLED, HIGH);
digitalWrite(GREENLED, LOW);
}
//////////////////////////////////////////////////
//
// signalAccessGranted()
// Zugang gewährt =>
// gruene LED leuchtet,
// rote nicht
//
//////////////////////////////////////////////////
void signalAccessGranted() {
digitalWrite(REDLED, LOW);
digitalWrite(GREENLED, HIGH);
}
//////////////////////////////////////////////////
//
// signalAccessRefused()
// Zugang verweigert =>
// rote LED blinkt 5x
//
//////////////////////////////////////////////////
void signalAccessRefused() {
for (int i = 0; i < 5; i++) {
digitalWrite(REDLED, HIGH);
delay(250);
digitalWrite(REDLED, LOW);
delay(250);
}
}
//////////////////////////////////////////////////
//
// loop()
// Warten auf RFID-Erkennung
// Reaktion abhaengig vom ID-Vergleich
//
//////////////////////////////////////////////////
void loop()
{
// Rotes Signal
signalDoorLocked();
// Karte erkannt und gelesen
if (rfidReader.PICC_IsNewCardPresent() && rfidReader.PICC_ReadCardSerial()) {
Serial.print("Erkanntes RFID-TAG ist => ");
// Bytes der ID lesen und ausgeben
Serial.print("/");
for (byte i = 0; i < rfidReader.uid.size; i++) {
Serial.print(rfidReader.uid.uidByte[i], HEX);
Serial.print("/");
}
Serial.println();
// Check ob Karte mit Variable sesam übereinstimmt
if (acceptedRFID(rfidReader.uid.uidByte)) { // ja =>
// Erlaubten Zugriff signalisieren
signalAccessGranted();
Serial.println("Zugriff erlaubt => Tuer oeffnen");
// Oeffnen der Tuere
openDoor();
Serial.println("Tuer 3 Sekunden offen lassen");
// 3 Sekunden Pause
delay(3000);
Serial.println("Tuer schliessen");
// Tuere wieder schliessen
closeDoor();
}
else // nein =>
{
Serial.println("Zugriff verweigert");
// Rote LED blinkt als Warnung
signalAccessRefused();
}
}
}
Ja. Und IMO ein Beispiel für sehr schlechten Programmierstil.
Wo man beim Erklären einer Funktion/eines Codeschnipsels in natürlicher Sprache „wenn“ sagt, sollte auch ein if verwendet werden. Code sollte auch einem „Nicht-Programmierer“ (Chef) leicht zu erklären sein. Normale Chefs haben die Erklärung der Funktionsweise Deines Code-Schnipselchens bereits vergessen wenn es um die nächste Zeile geht.
Ganz ehrlich - Für mich ja.
ABER: Ich wäre nie auf die Idee gekommen, das so zu schreiben.
Und zum nachbauen - Angaben in IDE 1.8.12
int a, b;
bool c;
void setup() {
// put your setup code here, to run once:
/*
if (a == b) {
c = true;
}
else
{
c = false;
}
*/
/*
c=a==b;
*/
// Jede Variante verwendet 444/9 bytes kompiliert für einen ARDUINO UNO
}
void loop() {
// put your main code here, to run repeatedly:
}
gregorss:
Wo man beim Erklären einer Funktion/eines Codeschnipsels in natürlicher Sprache „wenn“ sagt, sollte auch ein if verwendet werden.
Der Meinung schliesse ich mich nur bedingt an.
Ich habe es mittlerweile sehr gut geschaft am Ende der Zeile, spätestens aber innerhalb des Block, einen aussagekräftigen Kommentar zu hinterlegen.
Ja, manchmal gehört dann auch eine Leerzeile rein, nur um den Kommentar zu vervollständigen.
Im obigen Beispiel würde mein Kommentar lauten:
// wenn b und c gleich, dann a=true sonst a=false