Forum: Mikrocontroller und Digitale Elektronik while-Schleife verlassen (C)


von TMG (Gast)


Lesenswert?

Hallo,

kann man in C eine while-Schleife auch mit "return" verlassen?

Falls wichtig für die Frage, ich programmiere AVRs mit GCC/AVR-Studio.

von Peter II (Gast)


Lesenswert?

TMG schrieb:
> kann man in C eine while-Schleife auch mit "return" verlassen?

ja, nur wird dabei nicht nur die schleife sondern auch die Funktion 
verlassen.

von Fred R. (Firma: www.ramser-elektro.at/shop) (fred_ram)


Lesenswert?

While
Goto Outside
Do

Outside:

von break (Gast)


Lesenswert?

Wie wäre es mit "break"?

von Chris K. (Gast)


Lesenswert?

Wieso sollte man das tun wollen? Man kann doch auch einer while Schleife 
eine Abbruchbedingung mitgeben.

von Peter II (Gast)


Lesenswert?

Chris K. schrieb:
> Wieso sollte man das tun wollen? Man kann doch auch einer while Schleife
> eine Abbruchbedingung mitgeben.

Fehlerbeandlung?
1
while( Bedingung ) {
2
3
    if ( fehler ) {
4
       return -1;
5
    }
6
}

von Lars Schmitt (Gast)


Lesenswert?

Aus dem C-Standard:
1
6.8.6.3 The break statement
2
Constraints
3
1 A break statement shall appear only in or as a switch body or loop body.
4
Semantics
5
2 A break statement terminates execution of the smallest enclosing switch or iteration statement.
6
7
6.8.6.4 The return statement
8
Constraints
9
1 A return statement with an expression shall not appear in a function whose return type is void. A return statement without an expression shall only appear in a function whose return type is void.
10
Semantics
11
2 A return statement terminates execution of the current function and returns control to its caller. A function may have any number of return statements.

Wie aber schon richtig gesagt wurde, eine while-Schleife hat eine 
Abbruchbedingung. Sonst überleg dir ein anderes Konstrukt.

von foobar (Gast)


Lesenswert?

Chris K. schrieb:
> Wieso sollte man das tun wollen? Man kann doch auch einer while Schleife
> eine Abbruchbedingung mitgeben.

Weil diese Abbruchbedingung zum Start des Schleifendurchgang noch nicht 
vorliegt?

von Peter II (Gast)


Lesenswert?

Lars Schmitt schrieb:
> Sonst überleg dir ein anderes Konstrukt.

warum sollte er da machen? return ist durchaus sinnvoll zu 
Fehlerbehandlung!

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

foobar schrieb:
> Weil diese Abbruchbedingung zum Start des Schleifendurchgang noch nicht
> vorliegt?

Dann wäre wohl eine do-while-Schleife angebrachter.

von Lars Schmitt (Gast)


Lesenswert?

Peter II schrieb:
> warum sollte er da machen? return ist durchaus sinnvoll zu
> Fehlerbehandlung!

Na klar. Aber wir sollen wir durch unsere Glaskugeln überhaupt wissen 
was er möchte. Grundsätzlich lautet die Antwort auf die Frage:

> kann man in C eine while-Schleife auch mit "return" verlassen?

ein einfaches "ja".

von Der Andere (Gast)


Lesenswert?

Fred R. schrieb:
> While
> Goto Outside
> Do
>
> Outside:

WÜRG. Bitte ganz schnell vergessen, oder Assembler programmieren.

@TMG: Dir fehlt ein gutes C Buch, das du auch lesen musst. Das sind die 
absoluten Basics.

Um Schleifen zu beenden oder in den nächsten Durchlauf zu springen gibt 
es zwei Schlüsselwörter:
"break" und "continue".

Die müssen sitzen.

Ja und in einer Funktion kann man auch mit return aus einer Schleife. 
Das beendet aber nicht nur die Schleife, sondern die ganze Funktion.

von Der Andere (Gast)


Lesenswert?

Frank M. schrieb:
> Dann wäre wohl eine do-while-Schleife angebrachter.

Vieleicht war es ja auch eine for Schleife.
Manchmal ist die Welt auch grau und nicht nur schwarz und weiß :-)

von Peter D. (peda)


Lesenswert?

Peter II schrieb:
> return ist durchaus sinnvoll zu
> Fehlerbehandlung!

Oder um ein eine Schleife per Switch verlassen zu können.
Oder verschachtelte Schleifen.

von TMG (Gast)


Lesenswert?

Danke für die vielen Antworten!

Der Andere schrieb:
> "break" und "continue".
>
> Die müssen sitzen.
>
> Ja und in einer Funktion kann man auch mit return aus einer Schleife.
> Das beendet aber nicht nur die Schleife, sondern die ganze Funktion.

Danke, das beantwortet meine Frage!

von Kaj (Gast)


Lesenswert?

Chris K. schrieb:
> while Schleife
> eine Abbruchbedingung mitgeben.
Nein, kann man nicht! Schleifen in C/C++ haben (per se)
keine Abbruchbedingung! Es sind immer Laufbedingungen!

Bei Schleifen (in C/C++) heisst es immer : Laufe solange wie...
Und nicht: Breche ab wenn...

Das ist ein wesentlicher Unterschied. Auch wenn jeder hier vermutlich 
weiss was gemeint ist, so bleibt es trotzdem falsch.

Eine Abbruchbedinung hat man z.B. bei einer do-until-Schleife wie es sie 
in VBA gibt.

Eine Abbruchbedingung kann man nur kuenstlich erzeugen durch
ein if(...) break;

von THOR (Gast)


Lesenswert?

Kaj schrieb:
> Chris K. schrieb:
>> while Schleife
>> eine Abbruchbedingung mitgeben.
> Nein, kann man nicht! Schleifen in C/C++ haben (per se)
> keine Abbruchbedingung! Es sind immer Laufbedingungen!
>
> Bei Schleifen (in C/C++) heisst es immer : Laufe solange wie...
> Und nicht: Breche ab wenn...

Und diese Haarspalterei hilft niemandem, der einzige Unterschied ist 
nämlich die Negierung.

von Martin (Gast)


Lesenswert?

Ich bin jetzt kein C Entwickler, aber in anderen Sprachen gibt es das 
auch das man aus einem while frühzeitig raus will. Am einfachsten ist 
das wohl so zu lösen:
1
    int i = 0;
2
    int cancel = 0;
3
4
    while (i < 100 && cancel == 0)
5
    {
6
        printf("%i ", i);
7
        i++;
8
        
9
        if (i == 50)
10
            cancel = 1;
11
    }

von Peter II (Gast)


Lesenswert?

Martin schrieb:
> Am einfachsten ist
> das wohl so zu lösen:

ganz bestimmt nicht. Einfach ist ein break.
1
  int i = 0;
2
  while (i < 100 )
3
  {
4
      printf("%i ", i);
5
      i++;
6
        
7
      if (i == 50)
8
         break;
9
    }

von Der Andere (Gast)


Lesenswert?

Peter II schrieb:
> ganz bestimmt nicht. Einfach ist ein break.

Eben, ausserdem ist Martins "cancel" Beispiel auch noch beliebig falsch, 
da der Schleifenkörper nicht an dem Punkt abgebrochen wird, sondern bis 
zum Anfang des nächsten Durchlaufs weiterläuft.
Das kann je nachdem was hinter dem "cancel = 1" noch an Code steht 
beliebig falsch sein.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Der Andere schrieb:
> Das kann je nachdem was hinter dem "cancel = 1" noch an Code steht
> beliebig falsch sein.

Naja, wenn aber der Rest der Schleife doch noch durchlaufen werden 
soll, kann man das mit der Cancel-Variablen so machen. Einfacher wäre 
jedoch dann ein "i = 100;" gewesen ;-)

: Bearbeitet durch Moderator
von Richard H. (richard_h27)


Lesenswert?

Aus so einer while-Schleife kommt man nur raus, wenn man fristgerecht 
kündigt, sonst bleibt man ein weiteres Jahr drin.

von Jobst Q. (joquis)


Lesenswert?

TMG schrieb:
> kann man in C eine while-Schleife auch mit "return" verlassen?

Ja, wird so gemacht, wenn der Code nach der Schleife nicht mehr 
gebraucht wird. ZB bei strchr:


char* strchr(char *s,char c){
while(*s){
  if (*s==c)return s;
  s++;
  }
return NULL;
}

von Lu (Gast)


Lesenswert?

Fred R. schrieb:
> While
> Goto Outside
> Do
>
> Outside:

Persönlich finde ich das die schlimmste Methode.
Sehr unübersichtlich wenn der Code größer wird und vor allem glaube ich 
wird bei dieser Methode nicht aufgeräumt, richtig?

Also würden die innerhalb der Schleife angelegten temporären Variablen 
nicht nicht wieder gelöscht und für ehwig im Speicher verweilen. Oder 
täusche ich mich da jetzt?

von Peter II (Gast)


Lesenswert?

Lu schrieb:
> Also würden die innerhalb der Schleife angelegten temporären Variablen
> nicht nicht wieder gelöscht und für ehwig im Speicher verweilen. Oder
> täusche ich mich da jetzt?

ja, du täuscht dich.

Aufgeräumt wird immer.

von Dirk B. (dirkb2)


Lesenswert?

Peter II schrieb:
> Aufgeräumt wird immer.

Eher zur weiteren Nutzung frei gegeben.

von Rolf Magnus (Gast)


Lesenswert?

Kaj schrieb:
> Chris K. schrieb:
>> while Schleife
>> eine Abbruchbedingung mitgeben.
> Nein, kann man nicht! Schleifen in C/C++ haben (per se)
> keine Abbruchbedingung! Es sind immer Laufbedingungen!

Korinthen kacken kann ich auch: Deine Aussage ist Unsinn, da es gar 
keine Sprache namens "C/C++" gibt. Es gibt aber die Sprache C und die 
Sprache C++, für die das gesagte gleichermaßen gilt. Ich sag ja auch 
nicht "Eine Kuh/Katze hat vier Beine".

> Eine Abbruchbedingung kann man nur kuenstlich erzeugen durch
> ein if(...) break;

Was verstehst du unter "künstlich erzeugt"? Es ist doch praktisch die 
wörtliche Entsprechung von:

> Breche ab wenn...

von Martin (Gast)


Lesenswert?

Der Andere schrieb:
> Eben, ausserdem ist Martins "cancel" Beispiel auch noch beliebig falsch,
> da der Schleifenkörper nicht an dem Punkt abgebrochen wird, sondern bis
> zum Anfang des nächsten Durchlaufs weiterläuft.
> Das kann je nachdem was hinter dem "cancel = 1" noch an Code steht
> beliebig falsch sein.

Ein bisschen Kreativität muss da jeder schon noch selber mitbringen. War 
ja original kein Code vorgeben.

Peter II schrieb:
> ganz bestimmt nicht. Einfach ist ein break.
ja in Sprachen in es dieses Feature gibt schon

Frank M. schrieb:
> Einfacher wäre
> jedoch dann ein "i = 100;" gewesen ;-)

Einfacher ja, aber zumindest etwas was ich bei einem Review so nicht 
durchlassen würde (weder maintainable noch intuitiv)

von Rüdiger (Gast)


Lesenswert?

Auch wenn sie in Einzelfällen ihre Berechtigung haben, sind 
Programmsprünge mit break, continue oder goto in der Regel schlechter 
Programmierstil.

von Peter II (Gast)


Lesenswert?

Rüdiger schrieb:
> Auch wenn sie in Einzelfällen ihre Berechtigung haben, sind
> Programmsprünge mit break, continue oder goto in der Regel schlechter
> Programmierstil.

das ist doch Unsinn. bei goto kann man sich ja noch streiten aber break 
und continue sind üblich und werden auch ständig gebraucht.

von Jobst Q. (joquis)


Lesenswert?

Rüdiger schrieb:
> Auch wenn sie in Einzelfällen ihre Berechtigung haben, sind
> Programmsprünge mit break, continue oder goto in der Regel schlechter
> Programmierstil.

break und continue sind genau dafür da, Schleifen zu verlassen oder 
abzukürzen. Was nimmt 'guter Programmierstil' stattdessen?

von Kurt (Gast)


Lesenswert?

Ich würde es mal so formulieren: Wenn man ohnehin schon den 
Bad-Style-Fail gemacht hat einen Schleifenrumpf auf mehrere 
Bildschirmseiten Code auszudehnen, dann haut man mit continues und 
breaks dem Fass den Boden endgültig weg. Da blickt dann niemand mehr 
durch, wann und wo die Schleife durchlaufen oder abgebrochen wird.

Bei einem übersichtlich kompakten Rumpf hingegen gewinnt man nichts an 
Lesbarkeit, wenn man syntaktische Verrenkungen macht nur um 
Teufel-komm-raus contiues oder breaks zu vermeiden. Da ist ein break 
jederzeit besser als zusätzliche Abbruchvariablen oder -bedingungen.

von Joachim B. (jar)


Lesenswert?

TMG schrieb:
> kann man in C eine while-Schleife auch mit "return" verlassen?

ja aber sollte man nicht, wie gesagt wurde break;

TMG schrieb:
> ich programmiere AVRs mit GCC/AVR-Studio.

echt? oder nur C & P? break sollte man aber schon kennen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Vielleicht hilft dem TO das Stichwort "Schleifentransformation"?

von Peter II (Gast)


Lesenswert?

Joachim B. schrieb:
> TMG schrieb:
>> kann man in C eine while-Schleife auch mit "return" verlassen?
>
> ja aber sollte man nicht, wie gesagt wurde break;

und wie schon oft gesagt, warum sollte man das nicht? Ich habe oben 
schon ein Beispiel gebracht das es zur Fehlerbehandlung sehr sinnvoll 
ist.

von PittyJ (Gast)


Lesenswert?

Hm, ich merke gerade, dass ich zu wenig gotos verwende. Ich hätte auch 
mit break und return geantwortet.
Aber das goto ist ja richtig klasse: Retro-Style, wie damals in den 
80ern.
Zu NDW und Space Invaders gehört auch ein richtigen goto.

von Lars Schmitt (Gast)


Lesenswert?

Bei goto muss ich immer schmunzeln:

https://xkcd.com/292/

von René H. (Gast)


Lesenswert?

Rüdiger schrieb:
> Auch wenn sie in Einzelfällen ihre Berechtigung haben, sind
> Programmsprünge mit break, continue oder goto in der Regel schlechter
> Programmierstil.

Dann wünsche ich viel Spass bei der Suche nach dem Bug, weil jemand bei 
einer switch/case Anweisung das break vergessen hat. Sowas hat mich 
schon Tage gekostet.

break ist genau dafür gedacht, um eine Schleife vorzeitig zu verlasse 
(wenn die Abbruchbedingung noch nicht erfüllt ist). Das hat weder mit 
schlechtem Stil noch mit Unwissenheit zu tun.

Grüsse,
René

von A. S. (Gast)


Lesenswert?

Kurt schrieb:
> ... einen Schleifenrumpf auf mehrere
> Bildschirmseiten Code auszudehnen, dann haut man mit continues und
> breaks dem Fass den Boden endgültig weg. Da blickt dann niemand mehr
> durch, wann und wo die Schleife durchlaufen oder abgebrochen wird.


Das kann nur jemand schreiben, der niemals mit größeren Code-Basen zutun 
hatte. Allen Lehrbuch-, Misra- oder SIL-Regeln zum Trotz kann man 
komplexe Aufgaben (in C), die z.B. 1Mio Codezeilen erfordern, nicht 
sinnvoll so auf LIBs, Files und Funktionen verteilen, dass McCabe-Zahlen 
ein-oder zweistellig bleiben.

> Bei einem übersichtlich kompakten Rumpf hingegen gewinnt man nichts an
> Lesbarkeit, wenn man syntaktische Verrenkungen macht nur um
> Teufel-komm-raus contiues oder breaks zu vermeiden. Da ist ein break
> jederzeit besser als zusätzliche Abbruchvariablen oder -bedingungen.

Wenn das schon bei kleinem Code stimmt... umso wichtiger ist es bei 
großem Code, d.h. ein einheitlicher Einsatz dieser (und anderer) 
Sprachmittel. Man darf (und sollte) also break oder return in 
10.000-Zeilen-Funktionen ruhig verwenden, nur nicht in "unüblicher" 
Weise. Wenn 1000 aufeinanderfolgende case: mit break enden, sollte kein 
unerwartetes return darunter sein und vice versa.

Nochwas zu großem Code: Die Anzahl der Zeilen ist natürlich kein 
hinreichendes Kriterium. 1000 unabhängige Teilprozesse von je 1000 
Codezeilen sind natürlich so sauber zu programmieren wie ein Miniprojekt 
von 1000 Zeilen (also grob 10 C-Files a 10 Funktionen a 10 Zeilen wie im 
Lehrbuch)

von Jobst Q. (joquis)


Lesenswert?

Kurt schrieb:
> Ich würde es mal so formulieren: Wenn man ohnehin schon den
> Bad-Style-Fail gemacht hat einen Schleifenrumpf auf mehrere
> Bildschirmseiten Code auszudehnen, dann haut man mit continues und
> breaks dem Fass den Boden endgültig weg. Da blickt dann niemand mehr
> durch, wann und wo die Schleife durchlaufen oder abgebrochen wird.

Genau da, wo break bzw continue steht. Wo sonst?

Und die Funktion wird da beendet, wo return steht. Ein Problem?

von Jobst Q. (joquis)


Lesenswert?

Joachim B. schrieb:
> TMG schrieb:
>> kann man in C eine while-Schleife auch mit "return" verlassen?
>
> ja aber sollte man nicht, wie gesagt wurde break;

Warum sollte man nicht, wenn der Rest der Funktion nicht mehr gebraucht 
wird?

break ist kein Ersatz für return, break verlässt die Schleife, return 
die Funktion.

von Thomas S. (thomas55)


Lesenswert?


von Peter II (Gast)


Lesenswert?

Thomas S. schrieb:
> schau mal hier.
> http://www.peacesoftware.de/ckurs11.html

dort steht aber nicht von einem return? Was soll es ihn dann helfen?

von Thomas S. (thomas55)


Lesenswert?

Da steht wie man eine while-Schleife verlassen kann.

Andere Möglichkeiten gibt es glaube ich nicht.

von Peter II (Gast)


Lesenswert?

Thomas S. schrieb:
> Da steht wie man eine while-Schleife verlassen kann.
>
> Andere Möglichkeiten gibt es glaube ich nicht.

doch, nämlich return.

von Wilhelm M. (wimalopaan)


Lesenswert?


von Thomas S. (thomas55)


Lesenswert?

sorry, hab ich falsch verstanden. Ich dachte es soll die Schleife 
verlassen werden und nicht gleich die ganze die Funktion.

von Peter II (Gast)


Lesenswert?

Thomas S. schrieb:
> sorry, hab ich falsch verstanden. Ich dachte es soll die Schleife
> verlassen werden und nicht gleich die ganze die Funktion.

wenn die Funktion verlassen wird, wird auch die schleife verlassen.

von Thomas S. (thomas55)


Lesenswert?

natürlich. alles klar.

Dann kann man ja auch gleich das ganze Programm beenden. Da wird die 
Schleiffe auch verlassen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Thomas S. schrieb:
> schau mal hier.
> http://www.peacesoftware.de/ckurs11.html

Was ist das denn für ein schlechtes Tutorial?

von Thomas S. (thomas55)


Lesenswert?

@ Wilhelm M.
Also ich hatte keine Probleme mit diesem Tutorial-Ausschnitt.

Weiter hab ich nichts überprüft. Nicht meine Aufgabe.

von Wilhelm M. (wimalopaan)


Lesenswert?

Thomas S. schrieb:
> @ Wilhelm M.
> Also ich hatte keine Probleme mit diesem Tutorial-Ausschnitt.
>
> Weiter hab ich nichts überprüft. Nicht meine Aufgabe.

Folgendes fiel mir sofort auf:
1
int i, x = 55; // i ist uninitialsiert
2
double x;  // x ist schon als int deklariert , wird nicht initialisiert.
3
4
for(i = 100; i > -x; i--) // i besser innerhalb definieren, x ist nicht initialiert (s.o.)
5
{
6
// ...
7
}

Dann habe ich aufgehört zu lesen ...

: Bearbeitet durch User
von Thomas S. (thomas55)


Lesenswert?

Da hast Du recht.
Bei sowas nutzt kein break und auch kein return.

Aber ... wir sind alle nur menschen ...

Gruß aus Spandau

von Jobst Q. (joquis)


Lesenswert?

Wilhelm M. schrieb:
> Folgendes fiel mir sofort auf:
> int i, x = 55; // i ist uninitialsiert
> double x;  // x ist schon als int deklariert , wird nicht initialisiert.
>
> for(i = 100; i > -x; i--) // i besser innerhalb definieren, x ist nicht
> initialiert (s.o.)
> {
> // ...
> }

Die doppelte Verwendung von x ist Murks. Doch ist es Ansichtssache, wo 
man definiert und wo man initialisiert.

Ich bevorzuge alle Definitionen am Anfang einer Funktion und 
Initialisierung kurz vor Gebrauch.

von Wilhelm M. (wimalopaan)


Lesenswert?

Thomas S. schrieb:
> Da hast Du recht.
> Bei sowas nutzt kein break und auch kein return.
>
> Aber ... wir sind alle nur menschen ...
>
> Gruß aus Spandau

Noch ne andere Stelle daraus:

"Wie man sieht, wurde die Variable ' x' in der aurufenden Funktion 
verändert, die Adresse der Variablen x wird mit dem Kaufmannns-und in 
die Funktion
FunktionMitPointer(&x); hineingegeben und dort mit dem * Operator 
dereferenziert und verändert. Weil man hier nicht die Variable sondern 
die Referenz, die Adresse der Variablen, übergibt nennt sich das ganze 
Call By Reference."

Call-by-reference ist Quatsch!

Wenn solche Sachen durch solche schlechten Tutorials verbreitet werden, 
ist das wirklich schlecht.

von Thomas S. (thomas55)


Lesenswert?

ja, ja.

Aber Ausnahmen und Vorlieben ...

So, ich muss los. Tschüss

von Yalu X. (yalu) (Moderator)


Lesenswert?

Wilhelm M. schrieb:
> Noch ne andere Stelle daraus:
>
> "... in der aurufenden Funktion ..."

Ja, sogar die arme Funktion schreit vor Schmerzen ;-)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Wilhelm M. schrieb:
> Call-by-reference ist Quatsch!

Das ist es tatsächlich nicht, auch wenn es in C++ explizit das Konstrukt 
der Referenz gibt.

von Johnny B. (johnnyb)


Lesenswert?

Fred R. schrieb:
> While
> Goto Outside
> Do
>
> Outside:

Ein goto kann durchaus sehr übersichtlichen Code erlauben, wenn es 
gefühlte 100 Kriterien gibt und man alles an einer Stelle behandeln 
möchte. z.B. eine Fehlerausgabe oder so.
Aber ich würde es auch sparsam einsetzen, nur da, wo es wirklich sehr 
der Übersichtlichkeit dient oder den Code sehr vereinfacht.
Ansonsten würde ich in diesem Fall auch break verwenden um die Schleife 
zu verlassen oder return, wenn man auch gleich die Funktion verlassen 
will.

von Wilhelm M. (wimalopaan)


Lesenswert?

Rufus Τ. F. schrieb:
> Wilhelm M. schrieb:
>> Call-by-reference ist Quatsch!
>
> Das ist es tatsächlich nicht, auch wenn es in C++ explizit das Konstrukt
> der Referenz gibt.

Technisch gesehen ist das eine Parameterübergabe per-value, weil in 
Zeigerwert kopiert(!) wird.

von Peter II (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Technisch gesehen ist das eine Parameterübergabe per-value, weil in
> Zeigerwert kopiert(!) wird.

wenn es geinlined wird, muss gar nicht kopiert werden.

von Wilhelm M. (wimalopaan)


Lesenswert?

Peter II schrieb:
> Wilhelm M. schrieb:
>> Technisch gesehen ist das eine Parameterübergabe per-value, weil in
>> Zeigerwert kopiert(!) wird.
>
> wenn es geinlined wird, muss gar nicht kopiert werden.

Darum geht es doch gar nicht ...

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.