Forum: PC-Programmierung Pointer Problematik


von Max (Gast)


Lesenswert?

Hallo zusammmen,
meine C Pointerkenntnisse sind leider etwas eingerostet, daher habe ich 
folgende Frage.

Ich habe eine Funktion x welche einen Pointer auf eine Int Variable 
übergeben bekommt.

In dieser Funktion habe ich aus Gründen der Übersichtlichkeit einen Teil 
in eine weitere Funktion y ausgegliedert. Die Funktion y muss dabei aber 
auch Zugriff auf die Int Variable haben die auf die Funktion x übergeben 
wurde :)


hier mal mein Vorhaben in gekürzter Variante:)

void x (int *var_x) //Funktion1
{
 .....
 y(var);

}

void y (int *var_y) //Unterfunktion
{
 *var_y = 42;
}

main ()
{
 int var;
 x(var);
 printf("%d",var); (soll dann 42 ausgeben)
}

Ist dies so korrekt? Oder muss ich bei der zweiten Funktion einen 
Pointer auf einen Pointer verwenden. Bin da gerade etwas verwirrt.

von Maik M. (myco)


Lesenswert?

der Aufruf von x müsste so ausschauen:
1
x(&var);

Da x einen int-Pointer als Parameter will, und var nur als int definiert 
ist (nicht als pointer zu einem int).

von Klaus W. (mfgkw)


Lesenswert?

nein, nicht ganz.
1
void x (int *var_x) //Funktion1
2
{
3
 .....
4
 y( /* hier -> */ var_x); // nicht var, sondern var_x
5
6
}
7
8
void y (int *var_y) //Unterfunktion
9
{
10
 *var_y = 42;
11
}
12
13
main ()
14
{
15
 int var;
16
 x( /* hier -> */ &var );   // Adresse der Variablke ist der Pointer darauf
17
 printf("%d",var); (soll dann 42 ausgeben)
18
}

von Klaus W. (mfgkw)


Lesenswert?

Abgesehen davon: es hat sich bewährt, Zeigervariablen mit einem p 
beginnen zu lassen (und Zeiger auf Zeiger mit pp...).

Dann kann man leichter auseinanderhalten, was ein Wert ist und was ein 
Zeiger darauf.

von Max (Gast)


Lesenswert?

Sorry ich habe einen Fehler gemacht.
Meine Main sieht so aus:

main ()
{

 int var;
 int *ptr;
 ptr = &var;

 x(ptr);
 printf("%d",var); (soll dann 42 ausgeben)
}

von Zeiger (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> Abgesehen davon: es hat sich bewährt,

Quatsch

von Klaus W. (mfgkw)


Lesenswert?

Zeiger schrieb:
> Quatsch

Glückwunsch für deinen ersten qualifizierten Beitrag.
Und dann noch orthografisch ohne Mängel!

von isidor (Gast)


Lesenswert?

Zeiger schrieb:
> Quatsch

Das zeigt nur dass du dich noch nie in einem professionellen
Prograsmmier-Umfeld bewegt bzw betätigt hast.

von Zeiger (Gast)


Lesenswert?

Ungarische Notation ist so ziemlich das dümmste, was es gibt.
Der Typ einer Variable ist bei deren Definition nachlesbar. Das braucht 
man nicht jedes Mal bei jeder Verwendung nochmal.

von Dennis S. (eltio)


Lesenswert?

Zeiger schrieb:
> Ungarische Notation ist so ziemlich das dümmste, was es gibt.
> Der Typ einer Variable ist bei deren Definition nachlesbar. Das braucht
> man nicht jedes Mal bei jeder Verwendung nochmal.

Warum sollte man extra etwas nachschauen wollen / müssen, wenn es auch 
auf einem Blick ersichtlich sein kann?

Gruß
Dennis

von isidor (Gast)


Lesenswert?

Damit bestätigst du nochmal den Grad deiner Professionalität.

von isidor (Gast)


Lesenswert?

Dennis S. schrieb:
> Warum sollte man extra etwas nachschauen wollen / müssen,

Er hat eben nur 3 Pointer, und deren Typ kann er sich grad
noch so merken, da braucht er nicht nachschauen. Eben
ein Profi !

von Klaus W. (mfgkw)


Lesenswert?

Zeiger schrieb:
> Ungarische Notation ist so ziemlich das dümmste, was es gibt.

Da gebe ich dir recht.
Das war damals schon dämlich, als es propagiert wurde, und ist es gerade 
bei OO-Sprachen, wo es fast mehr Typen als Objekte gibt.

Aber: ein Variablenname soll sprechend sein und klarmachen, um was es 
sich handelt. Ich weiß nicht, ob wir da einer Meinung sind, aber das ist 
mir egal.
Und ein Name wie "iterator" oder "Zaehler" oder "Summe" ist grundfalsch, 
wenn es sich nicht um einen Iterator, einen Zähler oder eine Summe 
handelt, sondern um einen Zeiger auf soetwas.

Im OP steht etwas von var_x, obwohl es ein Zeiger auf etwas ist, was man 
vielleicht als var_x oder x bezeichnen könnte. Also ist var_x für den 
Zeiger ein mißverständlicher Name und damit einfach schlecht.

Ob man das jetzt verbessert, indem man den Zeiger zeiger_auf_x oder 
ptr_to_x oder p_x nennt, ist natürlich Geschmackssache und das will ich 
auch niemandem vorschreiben.
Aber etwas in dieser Art ist sicher angebracht bei einem Zeiger, und die 
weitaus üblichste Methode ist nunmal, das zumindest mit einem p zu 
kennzeichnen.

Natürlich gibt es viele Stile, aber das ist einer der gängigeren und er 
hat sich bewährt.

Wer Programme schreibt und darin Zeiger nicht deutlich als solche 
benennt, den nehme ich nicht wirklich ernst. Und schon gar nicht, wenn 
er sowas pauschal als Quatsch abtut und nicht sagen kann, warum.

von Zeiger (Gast)


Lesenswert?

>Aber: ein Variablenname soll sprechend sein und klarmachen,

Da stimme ich dir voll und ganz zu.
Man erreicht dies aber nicht durch dümmliche Regeln, die besagen, dass 
man Variablennamen immer mit diesem oder jenem Prefix versehen muss.

von Karl H. (kbuchegg)


Lesenswert?

Zeiger schrieb:
>>Aber: ein Variablenname soll sprechend sein und klarmachen,
>
> Da stimme ich dir voll und ganz zu.
> Man erreicht dies aber nicht durch dümmliche Regeln, die besagen, dass
> man Variablennamen immer mit diesem oder jenem Prefix versehen muss.

Trotzdem hat es sich bewährt, einem Zeiger Datentyp eine Kennzeichnung 
zu verpassen.
Das hat mit ungarischer Notation nur sehr am Rande zu tun, die (die 
ungarische Notation) im übrigen sowieso meist falsch verstanden wird. 
Die Idee bei der ungarischen war es nie, den eigentlichen Datentyp da 
mit reinzuschustern, sondern eine Kennzeichnung über den logischen Typ 
einer Variablen dafür vorzusehen, damit man ohne ständiges Nachsehen und 
Scrollen im Code die Korrektheit leicht verifizieren kann.

In der Computergrafik ist es zb unumgänglich zwischen absoluten und 
relativen Koordinaten zu unterscheiden. Das kann man zb mit einem Präfix 
oder einem Postfix im Variablennamen machen. Sehe ich eine Anweisung
1
    pointAbs = Object.transformToAbs( pointRel + offsetAbs );
dann weiss ich, das das nicht stimmen kann. Denn eine relative Position 
mit einem im absoluten Korrdinatensystem definierten Offset zu versehen, 
macht keinen Sinn. Das müsste sehr wahrscheinlich
1
    pointAbs = Object.transformToAbs( pointRel ) + offsetAbs;
lauten.


Und auch bei Pointern ist eine derartige Kennung hilfreich. Bei einem
1
  ppPtr->Object
hab ich nunmal einen Pointer auf einen Pointer. Und das ist was anderes 
als ein einfacher Pointer pPtr. Was wiederrum etwas anderes ist, als ein 
Pointer auf ein Array.

Natürlich kann man sich diese kleinen Hilfen auch sparen. Insbesondere 
in modernen IDEs, in denen dauernd irgendwo ein Tooltip aufgeht, der 
einem dann den Datentyp einer Variablen anzeigt. Nur da muss ich dann 
dauernd mit der Maus spazieren fahren, bis die über der Variablen steht 
und mir anzeigt, was die für einen Typ hat. Markiere ich mir den Pointer 
im Namen, dann kostet mir das beim Tippen nichts und es gibt keine 
Unklarheiten, wo ich bei wievielen Dereferenzierungen landen werde und 
ob ich dann eine -> Operation oder eine . Operation benötige, bzw. wie 
bei komplexeren Operationen die Klammern sitzen müssen. Ganz abgesehen 
davon, dass ich in Ruhe und überlegt meinen Code schreiben möchte, ohne 
das dauernd irgendwo ein Tooltip-Fenster aufpappt.

: Bearbeitet durch User
von Zeiger (Gast)


Lesenswert?

>hab ich nunmal einen Pointer auf einen Pointer. Und das ist was anderes
als ein einfacher Pointer pPtr.

Solche trivialen Fehler werden umgehend von jedem Compiler entlarvt.

>    pointAbs = Object.transformToAbs( pointRel ) + offsetAbs;

Was soll denn ein absoluter Offset sein?
Was kommt denn bei der Addition zweier absoluter Werte raus?

von Karl H. (kbuchegg)


Lesenswert?

Zeiger schrieb:
>>hab ich nunmal einen Pointer auf einen Pointer. Und das ist was anderes
> als ein einfacher Pointer pPtr.
>
> Solche trivialen Fehler werden umgehend von jedem Compiler entlarvt.
>
>>    pointAbs = Object.transformToAbs( pointRel ) + offsetAbs;
>
> Was soll denn ein absoluter Offset sein?
> Was kommt denn bei der Addition zweier absoluter Werte raus?

wieder ein absoluter Wert.
Das ganze hat ein bischen was von der "Kontrollrechnung" in der Physik, 
in der man nicht mit Zahlenwerten sondern anhand der Einheiten 
überprüft, ob ein Formelergebnis überhaupt plausibel ist.

von Dr. Sommer (Gast)


Lesenswert?

In C++ könnte man sich eigene Typen für absolute und relative Werte 
definieren, und die Operatoren derart überladen, dass man nur 
zusammenpassende Werte addieren kann. Dann spart man sich die Präfixe 
weil der Compiler dann alle Fehler findet...

von Udo S. (urschmitt)


Lesenswert?

Zeiger schrieb:
> Solche trivialen Fehler werden umgehend von jedem Compiler entlarvt.

Du hast wohl noch nie größere Projekte fremden Codes lesen müssen.
Da nützt dir auch kein Compiler was, du willst schnell verstehen wie und 
warum jemand das Programm genau so geschrieben hat.
Und dabei hilft es immens direkt beim Lesen zu erkennen was für ein Typ 
die Variablen sind.
Sklavische Prefixe bis zum xten Subtyp helfen nicht, aber clever benutzt 
machen sie Code deutlich lesbarer.

von Karl H. (kbuchegg)


Lesenswert?

Udo Schmitt schrieb:

> Und dabei hilft es immens direkt beim Lesen zu erkennen was für ein Typ
> die Variablen sind.

Wobei, und das sollte man herausstreichen, mit 'Typ' hier ursprünglich 
nicht unbedingt der konkrete Datentyp der Variablen gemeint war, sondern 
mehr von welcher Art eine Variable ist. Anhand des Namens soll man zb. 
erkennen können, ob man es mit einem echten Pointer zu tun hat, oder ob 
es sich um einen Handle handelt, der zwar auch irgendein anderes Objekt 
referenziert, dessen Inhalt aber eben nicht die konkrete Speicheradresse 
ist, sondern irgendein anderes Merkmal. Die Handles, die man von der 
Windows-API kriegt, sind eben keine Pointer, die man dereferenzieren 
kann. Trotzdem identifizieren sie den Pen, den man in den 
Ausgabefunktionen benutzt. Den Handle krieg ich von der Windows-API, 
wenn ich einen Pen erzeugen lass und ich gebe ihn ihr auch zurück und 
benutze ihn in den Ausgabefunktionen. Und genau das ist es, was mir das 
'h' in 'hCurrentPen' sagt: es handelt sich um einen Handle und nicht wie 
in 'pCurrentPen' um einen Pointer zu einem Pen Objekt, wohingegen ein 
'CurrentPen' das Pen Objekt selber ist. Und das ganz ohne, dass ich beim 
Entwickeln des Codes dauernd die Datentypen raussuchen muss.

Sicher, bei kleinen einfachen Programmen sind das alles Kinkerlitzchen. 
Wenn die Anzahl der Codezeilen aber in die Hundertausende geht, ist man 
über jede Vereinfachung froh, die einem das Leben mit wenig Aufwand 
leichter macht.

Das Microsoft das nicht verstanden hat, dass die Intention der 
ungarischen Notation nicht darin bestand, dass man an 'dwIndex' anlesen 
kann, dass es sich um ein Double Word handelt, dafür kann die ungarische 
nix. Darum ist es in der ursprünglichen ungarischen überhaupt nie 
gegangen.

: Bearbeitet durch User
von Zeiger (Gast)


Lesenswert?

>aber clever benutzt machen sie Code deutlich lesbarer.

Ja. clever benutzt. Aber durch eine Regel wie "immer alles schön 
Prefixen" kommt genau das Gegenteil heraus.

Was soll mir denn ein p-Präfix an Lesbarkeit beingen?

> currentValue = values->value;

versus:

> currentValue = pValues->value;

Das bringt absolut Null Mehrwert. Ganz im Gegenteil. Es obfuskiert den 
Namen.

Selbst wenn danach ein values++ kommt (Pointerarithmetik), wird aus dem 
Kontext sofort klar, dass values ein Pointer ist. Da braucht es keinen 
p-Präfix.

>Du hast wohl noch nie größere Projekte fremden Codes lesen müssen.

Achje. Ab wieviel Millionen Zeilen ist für dich ein Projekt groß?

von Zeiger (Gast)


Lesenswert?

Karl Heinz schrieb:
> Und genau das ist es, was mir das 'h' in 'hCurrentPen'

Warum sollte das denn überhaupt eine Rolle spielen?
Wenn ich currentPen lese, dann weiß ich, dass dieses Objekt in 
irgendeiner Weise den Pen identifiziert. Wie es das macht ist mir doch 
egal. Sobald ich damit arbeiten will muss ich aber in_ _jedem_ _Fall 
die Dokumentation der Funktion lesen, der ich currentPen übergebe.

Es bleibt nur, dass das 'h' ein zusätzliches Rauschen im Lesefluss ist.

von Klaus W. (mfgkw)


Lesenswert?

Weißt du, was das schöne an einer Empfehlung ist?
Du kannst sie ignorieren, wenn du keinen Sinn drin siehst.

von Zeiger (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> Du kannst sie ignorieren, wenn du keinen Sinn drin siehst.

Und deshalb darf man sie nicht grundsätzlich hinterfragen?

von Klaus W. (mfgkw)


Lesenswert?

"Quatsch" würde ich anders nennen.

von Karl H. (kbuchegg)


Lesenswert?

Zeiger schrieb:
> Klaus Wachtler schrieb:
>> Du kannst sie ignorieren, wenn du keinen Sinn drin siehst.
>
> Und deshalb darf man sie nicht grundsätzlich hinterfragen?

Darfst du.
Andere haben das auch getan, und das als für sie gut befunden.

Was nicht heisst, dass ich die ungarische in ihrer vollen Ausprägung, 
vor allen in der MS-Version, gut finde. Aber den Pointer p hab ich mir 
auch angewöhnt und finde ihn gut.

: Bearbeitet durch User
von Rainer V. (rudi994)


Lesenswert?

Das Pointer-p war auch in TPascal üblich und nach meiner Erinnerung 
teils vorgeschrieben, z.B. um Fenster vom abstrakten Typ TObject bzw. 
TWindow abzuleiten: PWindow zeigt auf Objekt vom Typ TWindow

Von den vielen, für mich neuen (Standard-)Prefixen in C/Cpp war ich 
anfangs nicht begeistert, finde aber diverse Prefixe nützlich, um 
Bezeichner näher zu beschreiben und Dinge der gleichen Kategorie durch 
ein gleiches Prefix vor verschiedenen Namen oder durch den gleichen 
Namen hinter verschiedenen Prefixen zu gruppieren. Mich stört aber, daß 
laut einigen Quellen der Unterstrich zu vermeiden ist. Wozu soll das gut 
sein? Woher kommen die vielen Typen wie uint8_t, size_t, wchar_t, usw.?

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Rainer V. schrieb:
> Mich stört aber, daß laut einigen Quellen der Unterstrich zu vermeiden
> ist.

Nun, "einige Quellen" sind erstmal nicht normativ. Und waren vielleicht 
führende Unterstriche gemeint? Die sind tastächlich zu vermeiden, weil 
sie eine Sonderrolle haben.

von Klaus W. (mfgkw)


Lesenswert?

Rolf Magnus schrieb:
> Nun, "einige Quellen" sind erstmal nicht normativ. Und waren vielleicht
> führende Unterstriche gemeint? Die sind tastächlich zu vermeiden, weil
> sie eine Sonderrolle haben.

Zu vermeidne sind nur die führenden, damit sie nicht mit Dingen aus den 
Headerdateien kolliedieren.

Die _ innerhalb von Namen sind im Prinzip zulässig.
Allerdings macht es Sinn, Namen nach einem halbwegs einheitlichen Schema 
zu vergeben.
Und da war es in C gängig (wenn auch nicht verbindlich) etwa so zu 
benamsen:
anteil_dummer_teilnehmer_am_ganzen_forum für Variablen bzw. anzahl_t für 
einen passenden Datentyp.
In C++ ist es eher gängig (wenn auch wieder nicht zwingend, nicht _ zum 
Trennen der einzelnen Wörter in einem Namen, sondern stattdessen 
Groß-/Kleinschreibung (camel case), wobei Objekte mit einem kleinen 
Buchstaben angfangen, Typen dagegen mit einem Großbuchstaben, also 
anteilDummerTeilnehmerImForum vom Typ Anzahl.

von Rainer V. (rudi994)


Lesenswert?

Zu Unterstrichen in C/Cpp siehe Wiki "Ungarische Notation", hinter dem 
Inhaltsverzeichnis in Abschnitt "Apps Hungarian" und ca. in der Mitte im 
Abschnitt "Bezeichner": http://de.wikipedia.org/wiki/Ungarische_Notation

Das war in TPascal auch so: idButton=123 und nicht id_Button=123
Anders im Ressourcenscript: ids_Name="Blaise", idc_PushButton=123

In meinen Büchern steht nichts zu den Prefixen. Da ist nur zu lesen, daß 
führende Unterstriche eher eine Frage des Schreibstils sind und daß es 
da keine festen Regeln gibt. Über reservierte, führende/nachfolgende 
Unterstriche war im Web etwas zu lesen. Es ging um Symbole zur bedingten 
Compilierung, damit ein Header nicht mehrmals eingebunden wird, oder um 
Assemblersyntax in den Formaten Intel oder AT&T.

von Rolf M. (rmagnus)


Lesenswert?

Klaus Wachtler schrieb:
> Und da war es in C gängig (wenn auch nicht verbindlich) etwa so zu
> benamsen:
> anteil_dummer_teilnehmer_am_ganzen_forum für Variablen bzw. anzahl_t für
> einen passenden Datentyp.
> In C++ ist es eher gängig (wenn auch wieder nicht zwingend, nicht _ zum
> Trennen der einzelnen Wörter in einem Namen, sondern stattdessen
> Groß-/Kleinschreibung (camel case),

Lustigerweise, obwohl die Sprache selbst (sowohl die Standardbibliothek, 
als auch fest in der Sprache eingebaute Namen wie static_cast) 
durchgängig die Variante mit Kleinbuchstaben und Unterstrichen nutzen.

: Bearbeitet durch User
von Klaus W. (mfgkw)


Lesenswert?

Rolf Magnus schrieb:
> Lustigerweise, obwohl die Sprache selbst (sowohl die Standardbibliothek,
> als auch fest in der Sprache eingebaute Namen wie static_cast)
> durchgängig die Variante mit Kleinbuchstaben und Unterstrichen nutzen.

... was ich aber eigentlich ganz gut finde.
Man erkennt dann an der Schreibweise, was vorgegebener Standard ist und 
was selbst gebraut wurde. Also eine Art inoffizieller namespace :-)

von Rainer V. (rudi994)


Lesenswert?

Klaus Wachtler schrieb:
> was vorgegebener Standard ist und was selbst gebraut wurde

wie etwa bei lecker_koelsch_aus_colonia und altbierausduesseldorf.

Aber was ist z.B. mit Funktion localtime_r? Soll laut diesem Tutorial
http://www.cplusplus.com/reference/ctime/localtime/?kw=localtime
eine Alternative zu localtime aus <time.h> bzw. <ctime> sein, ist jedoch 
nicht zwingend in jeder Bibliothek vorhanden, daher auch nicht portabel. 
Einen Unterstrich hat es aber.

von B. S. (bestucki)


Lesenswert?

Rolf Magnus schrieb:
> Lustigerweise, obwohl die Sprache selbst (sowohl die Standardbibliothek,
> als auch fest in der Sprache eingebaute Namen wie static_cast)
> durchgängig die Variante mit Kleinbuchstaben und Unterstrichen nutzen.

Nur wenn man bei FILE beide Augen fest zudrückt... Keine Ahnung was sich 
die Herren dabei überlegt haben. Auch einige Makros wie EOF, BUFSIZ oder 
FOPEN_MAX sind gross geschrieben, das ist aber auch gut so, sind ja 
schliesslich Makros.

Ich frage mich eher, warum man für einige Standardfunktionen kryptische 
Namen wie z.B. strpbrk wählen musste. Aussagekräftige Namen sehen anders 
aus. Auch das BUFSIZ hätte man wenigstens BUFSIZE, oder gleich 
STDIO_BUFFER_SIZE taufen können.

Aber ich muss Klaus zustimmen, der inoffizielle namespace ist zu 
gebrauchen :)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

be stucki schrieb:
> Ich frage mich eher, warum man für einige Standardfunktionen kryptische
> Namen wie z.B. strpbrk wählen musste.

Das ist historisch gewachsen. Es gab wohl mal eine Zeit, in der 
Funktionsnamen so kurz wie irgend möglich sein mussten; ähnliches kennt 
man von unixoiden Betriebssystemen, bei denen viele 
Programme/Kommandozeilenbefehle auch möglichst kurze Namen haben müssen.

Das ist dann "mächtig".

von Rolf M. (rmagnus)


Lesenswert?

be stucki schrieb:
> Rolf Magnus schrieb:
>> Lustigerweise, obwohl die Sprache selbst (sowohl die Standardbibliothek,
>> als auch fest in der Sprache eingebaute Namen wie static_cast)
>> durchgängig die Variante mit Kleinbuchstaben und Unterstrichen nutzen.
>
> Nur wenn man bei FILE beide Augen fest zudrückt... Keine Ahnung was sich
> die Herren dabei überlegt haben. Auch einige Makros wie EOF, BUFSIZ oder
> FOPEN_MAX sind gross geschrieben, das ist aber auch gut so, sind ja
> schliesslich Makros.

Ja, Makros sind nochmal was eigenes. FILE war meines Wissens früher auch 
mal ein Makro.

Rufus Τ. Firefly schrieb:
> Das ist historisch gewachsen. Es gab wohl mal eine Zeit, in der
> Funktionsnamen so kurz wie irgend möglich sein mussten;

Nicht unbedingt so kurz wie möglich. Es gab allerdings in der Urzeit von 
C bei manchen Linkern Beschränkungen bei den Längen von Bezeichnern. 
Teilweise waren meines Wissens nur bis zu 6 Zeichen möglich.

> ähnliches kennt man von unixoiden Betriebssystemen, bei denen viele
> Programme/Kommandozeilenbefehle auch möglichst kurze Namen haben müssen.

Die müssen diese nicht haben, aber wenn man manche davon im Alltag 
hundert mal an einem Tag eintippen muss, ist man froh, wenn der Name 
kurz ist. Lernen muss man die Kommandos eh, und wen man sie oft benutzt 
(was damals halt der Normalfall war), dann ist einem eigentlich die 
konkrete Buchstabenfolge relativ egal, solange sie möglichst kurz ist.

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.