mikrocontroller.net

Forum: Compiler & IDEs Zuweisung in while-Bedingung


Autor: Alois (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

wie wird folgender Ausdruck ausgewertet:
while (test=GetUartChar())

Wird die while-Schleife solange ausgeführt, bis test=0 ist, oder müßte 
man in diesem Fall
do
   test=GetUartChar();
while (test);

schreiben?

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

Bewertung
0 lesenswert
nicht lesenswert
Alois wrote:
> Hallo,
>
> wie wird folgender Ausdruck ausgewertet:
>
>
> while (test=GetUartChar())
> 
>

So wie jede andere Zuweisung auch.
Eine Zuweisung hat als Ergebnis den Wert der zugewiesen wurde.
Dies ermöglicht Dinge wie
   a = b = c = 5;

d.h. die Zuweisung wird ausgeführt und danach der an test
zugewiesene Wert geholt und, da es sich um eine logische
Abfrage handelt, wie jeder andere numerische Wert behandelt:
0 ist logisch falsch
alles ungleich 0 wird als logisch wahr behandelt.


> Wird die while-Schleife solange ausgeführt, bis test=0 ist

Yep

>, oder müßte
> man in diesem Fall
>
>
> do
>    test=GetUartChar();
> while (test);
> 
>
> schreiben?

Nein. Ist absolut equivalent.

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
;) ja

Gruß Hagen

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gehupst wie gesprungen.

Autor: Alois (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und was ist mit:
while(test=GetUartChar() != '\0')

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

Bewertung
0 lesenswert
nicht lesenswert
Alois wrote:
> Und was ist mit:
>
>
> while(test=GetUartChar() != '\0')
> 

Das ist gemein :-)
Denn das macht nicht das was du denkst. (*)

Das Problem:
Der Vergleich hat eine höhere Operatoren Priorität
als die Zuweisung. Der Compiler sieht das also als:

  test = ( GetUartChar() != '\0' )

Das Ergebnis von GetUartChar() wird mit '\0' verglichen.
Ist es ein '\0' Zeichen, dann wird test zu 1, ansonsten
(und das dürfte meistens der Fall sein), zu 0.

da damit aber eine 0 zugewiesen wurde, ist auch das
Ergebnis des kompletten Ausdrucks

  test = ( GetUartChar() != '\0' )

gleich 0 und damit hast du

  while( 0 )

und so eine while Schleife bricht dann sofort ab (weil 0
ja logisch falsch darstellt)

(*) das entnehme ich der Art wie du die Leerzeichen gesetzt hast

Autor: Alois (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Läßt sich da mit Klammern was machen?

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

Bewertung
0 lesenswert
nicht lesenswert
Natürlich.
Mit Klammern lässt sich immer was machen, wenn die 'natürliche'
Operatorenreihenfolge nicht stimmt. Du musst dich von der
Vorstellung lösen, dass in C eine Zuweisung etwas spezielles
ist. Eine Zuweisung ist auch nur eine Operation wie Addition
oder Division, die ein Eregbnis liefert. OK, als Nebeneffekt
wird in der linken Seite der Zuweisung etwas gespeichert, aber
prinzipiell ist eine Zuweisung auch nur ein arithmetischer Ausdruck
der ein Ergebnis liefert.
  while( ( test = GetUartChar() ) != '\0' )



Autor: Stefan Kleinwort (_sk_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich würde in beiden Fällen klammern und einen expliziten Vergleich 
hinschreiben:

Bei
  while (test=GetUartChar())

wird jeder erstmal einen Fehler vermuten. Auch ein automatisches 
Fehlererkennungstool wird hier eine Warnung ausgeben.
Bei
  while ( (test=GetUartChar()) != 0 )

ist dagegen sofort klar, dass das "=" kein fehlerhaftes "==" darstellt.


Gruß, Stefan

Autor: FBI (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

dazu brauchts nicht mal ein "automatisches Fehlererkennungstool", da 
reicht schon der GCC. Normalerweise schmeißt der bei der ersten Variante 
wenigstens eine Warnung und will entweder die zweite Variante oder 
sowas:
while((test=GetUartChar()))
(man beachte die zusätzliche Klammern)

CU

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.