Grundlagenfrage Programmieren

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 :wink:

Ich habe dieses Beispiel aus :

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]);}

Vielen Dank schonmal !

Hi

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.

MfG

Hey Danke,

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 :wink:

Benjamin_jerchel:
...

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]);}

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.

Gruß

Gregor

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.

Welche Form wäre Dir denn lieber gewesen?

Hallo,

in dem Code ist keine Kurzschreibweise enthalten.
Kurzschreibweise wäre zum Bsp. statt

a = a + b;
dann
a += b;

oder statt
c = c + 1;
dann
c++;
bzw.
++c;

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.

Gruß

Gregor

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"

Hi

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.

MfG

Hallo,

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();
        }
   }
 }

Minderheit

Mach dir nix draus.
Auch tausend Fliegen können irren.
(oder so ähnlich)

Für mich ist es normal, dass Funktionen einen Bool Wert zurückgeben.
Und auch, dass er auf diese Weise generiert wird.

gregorss:
Ich bin mit meiner if-Ansicht wohl in der Minderheit.

Dann wäre das hier

a = b==c;

für dich auch schon ein if?

Für mich ist da ein 'if' drin, wo auch 'if' draufsteht :wink:

Das andere sind logische Operatoren und Zuweisungen.

MicroBahner:
Dann wäre das hier

a = b==c;

für dich auch schon ein if?

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.

Glücklich ist, wer einen guten Chef hat :slight_smile:

Gruß

Gregor

Und IMO ein Beispiel für sehr schlechten Programmierstil.

Dann bin ich ein schlechter Programmierer.
Und auch böse, denn auch gotos kommen mal vor.

Auch bin ich ein ausgeformter if Verächter.

Mein Mantra:

ein vermeidbares if, ist ein böses if
ein vermiedenes if, ist ein gutes if

Ich find den Codeschnipsel genial.

MicroBahner:
Dann wäre das hier

a = b==c;

für dich auch schon ein if?

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

Und ich vermute auch ein Chef sieht das so :wink:

my_xy_projekt:
Im obigen Beispiel würde mein Kommentar lauten:

Allgemeinverständlichen Code muss man nicht kommentieren. Tippfaulheit rulez g

Gruß

Gregor

Wie lang wird denn der Code ganz ohne beide Versionen?