www.mikrocontroller.net

Forum: Compiler & IDEs Zuweisung und unterschiedsprüfung in einem if


Autor: LukasW (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!
Ich hätte mal eine Frage bzgl. C:
Ich habe eine recht aufwendige Berechnung für einen Wert in meinem 
System, bei dessen Änderung einmalig ein bestimmter Code ausgeführt 
werden soll.
Dazu habe ich mir folgenden Code überlegt:
void irgendeinefunktion()
{
   static unsigned char ucLastValue;

   if(ucLastValue != (ucLastValue = aufwendigeBerechnung()))
   {
      // Verarbeitung "wert geändert"
   }
}
Das scheint leider nicht richtig zu funktionieren, die Bedingung ist 
immer '0'. Nicht das ich keine Alternative wüsste, aber warum geht das 
nicht?

Autor: x-beliebig (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
x != x ist immer 0

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
LukasW schrieb:

> Das scheint leider nicht richtig zu funktionieren, die Bedingung ist
> immer '0'. Nicht das ich keine Alternative wüsste, aber warum geht das
> nicht?

Weil in C nicht definiert ist, ob bei einem Vergleich zuerst die linke 
Seite und dann die rechte Seite oder umgekehrt ausgewertet wird. Der 
Compiler darf sich das aussuchen.

Du hast darauf spekuliert, dass zuerst die linke Seite ausgewertet wird, 
der Wert irgendwo temporär zwischengespeichert wird und erst dann der 
Funktionsaufruf erfolgt, der einen neuen Wert bringt welche gleichzeitig 
in ucLastValue gespeichert wird und mit dem alten Wert aus dem 
Zwischenspeicher verglichen wird.

Du hast mit Zitronen gehandelt.

Die einzigen paar Fälle in denen du in C von einer definierten 
Auswerte-Reihenfolge ausgehen kannst, sind &&, || und , (der 
Kommaoperator, nicht zu verwechseln mit dem Komma in Argumentlisten)

Ausdrücke mit diesen Operationen werden immer von links nach rechts 
ausgewertet. Aber abgesehen von diesen Operatoren solltest du in C 
niemals von einer in irgendeiner Art und Weise definierten 
Auswertereihenfolge ausgehen. Der Compiler hat in C ziemlich viele 
Freiheiten und darf sich die Reihenfolgen aussuchen wie sie ihm in den 
Kram passen.

Autor: Der Micha (steinadler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie muss man denn die Denkweise verstehen?

Also ich würde das, wenn, dann so machen:
static unsigned char ucNewValue;

ucNewValue = aufwendigeBerechnung();

if(ucLastValue != ucNewValue)
{
   // Verarbeitung "wert geändert"
}

ucLastValue = ucNewValue;

Ich weiß, dass du keine Lösungsvorschläge haben willst, aber wie kommt 
man auf so ein merkwürdiges Konstrukt?

Ich finde, Zuweisungen in if-Abfragen sollte man sich eh abgewöhnen.
Habe vor kurzer Zeit verzweifelt nach einem Bug gesucht, bis ich gesehen 
hab, dass ich statt == nur ein = geschrieben hatte.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist ein typisches Beispiel, wie man Code schreibt, der aus völlig 
unverständlichen Gründen unsinnig trickreich und nicht selbsterklärend 
ist (und in diesem Fall auch noch nicht funktioniert).

Du möchtest den neuberechneten Wert mit dem aus dem vorherigen Zustand 
vergleichen,und den der Variablen ucLastValue zuweisen. Warum dann nicht 
einfach genau das hinschreiben, Zeile für Zeile, mit einer zusätzlichen 
lokalen Variablen, die den alten Wert von ucLastValue vor der 
Neuberechnung zwischenspeichert?
Denn wenn dein Ansatz funktioniert hätte, hätte der Compiler die auch 
anlegen müssen. Du sparst also mit deiner Trickserei weder Speicherplatz 
noch Rechenzeit.

Aber vielleicht ist das ja eine Übung für den obfuscated C contest.

Olvier

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.