Forum: PC-Programmierung Größe von einem "struct Array" bestimmen?!


von Jan H. (janiiix3)


Lesenswert?

Moin Freunde,

bekomme Ich irgendwie die Anzahl der Einträge raus?
1
typedef struct
2
{
3
  char *Name;
4
  uint8_t numb;
5
}menue_t;
6
7
menue_t mainMenue[]=
8
{
9
  {"Uhrzeit stellen"  ,0},
10
  {"Datum stellen"  ,1},
11
  {"Bluetooth"    ,2},
12
  {"Neustart"      ,3},
13
  {"Exit"        ,4},      
14
};
15
16
void test(menue_t *m)
17
{
18
  printf("%d",sizeof(m) / sizeof(m[0]));  
19
}

: Verschoben durch Moderator
von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

Nein, in der Funktion nicht, denn da ist es kein Array mehr, sondern 
nur noch ein Zeiger. Wenn du die Groesse brauchst, musst du sie der 
Funktion als extra Parameter mit uebergeben. Die Groesse kannst du nur 
in dem Scope, in dem du das Array erstellt hast, ermitteln.

von Dirk B. (dirkb2)


Lesenswert?

Du kannst auch als letzten Eintrag im Array
{NULL        , 0xff}
nehmen

Andererseits ist es in C eigentlich immer gut, die Arraygröße mit an die 
Funktionen zu übergeben.

von Wilhelm M. (wimalopaan)


Lesenswert?

Dirk B. schrieb:
> Du kannst auch als letzten Eintrag im Array
> {NULL        , 0xff}
> nehmen
>
> Andererseits ist es in C eigentlich immer gut, die Arraygröße mit an die
> Funktionen zu übergeben.

Wie schon Bjarne sagen: "Rohe C/C++-Arrays sind so blöd, dass sie ihre 
eigene Länge nicht kennen".

von Nop (Gast)


Lesenswert?

Wilhelm M. schrieb:

> Wie schon Bjarne sagen: "Rohe C/C++-Arrays sind so blöd, dass sie ihre
> eigene Länge nicht kennen".

Müssen sie auch nicht. Wenn man das wirklich haben will, kann man sich 
ja problemlos ein struct typedefen, wo die Länge drinsteht. Dann muß man 
halt den Verwaltungs-Overhead mitbezahlen.

Zudem ist die Länge ja auch keineswegs immer eindeutig. Beispielsweise 
habe ich öfter den Fall, wo Funktionen Pointer akzeptieren nebst einer 
Länge. Das ist aber nicht etwa die physikalische Buffergröße des 
dahinterliegenden Arrays bzw. Heap-Bereiches, sondern die 
Nutzdatenlänge, welche im allgemeinen echt kleiner als die Buffergröße 
ist - und sich außerdem erst zur Laufzeit bestimmt.

Der verarbeitenden Funktion kann das aber egal sein. Natürlich hat man 
dann den Overhead, um sicherzustellen, daß die Nutzdaten nicht größer 
als der Buffer werden, aber das ist einmalig bei der Validierung der 
Fall, und danach bei der Verarbeitung entfällt jeder 
Verwaltungs-Overhead.

Genau das scheint der typische Fall zu sein, was auch der wesentliche 
Grund ist, wieso C das so handhabt und nicht etwa nach Art von 
Pascal-Strings die Länge irgendwo unter der Haube mit durchreicht.

von Wilhelm M. (wimalopaan)


Lesenswert?

Nop schrieb:
> Wilhelm M. schrieb:
>
>> Wie schon Bjarne sagen: "Rohe C/C++-Arrays sind so blöd, dass sie ihre
>> eigene Länge nicht kennen".

> Zudem ist die Länge ja auch keineswegs immer eindeutig.

Sollte sie aber sein ;-))

> Beispielsweise
> habe ich öfter den Fall, wo Funktionen Pointer akzeptieren nebst einer
> Länge. Das ist aber nicht etwa die physikalische Buffergröße des
> dahinterliegenden Arrays bzw. Heap-Bereiches, sondern die
> Nutzdatenlänge, welche im allgemeinen echt kleiner als die Buffergröße
> ist - und sich außerdem erst zur Laufzeit bestimmt.

Dann hast Du eben einen Buffer mit einer (Maximal)Größe, dass Du für 
eine dynamische Struktur wie etwa eine Queue, Stack, etc. verwendest.

Das Problem des TO ist, dass er erkennen muss, was das "Zerfallen" eines 
Array-Bezeichners zu einem Zeigertyp ist (decay of array designator).

von Nop (Gast)


Lesenswert?

Wilhelm M. schrieb:

> Dann hast Du eben einen Buffer mit einer (Maximal)Größe, dass Du für
> eine dynamische Struktur wie etwa eine Queue, Stack, etc. verwendest.

Eben, aber zur Verarbeitung ist die meistens kleinere Nutzgröße 
relevant, weil danach Datenmüll folgen kann. Würde damit gearbeitet, 
d.h. bis ans Ende der Buffergröße, dann wären funktionale Fehler die 
Folge.

Deswegen hat man kein Problem, wenn man beim Befüllen sicherstellt, daß 
die Nutzgröße kleiner gleich der Buffergröße ist, aber das ist eben nur 
an einem Punkt nötig und nicht überall danach. Dann aber entfällt auch 
die Notwendigkeit, die physikalische Arraygröße überhaupt 
weiterzureichen.

Ein Problem hat man dann nur, wenn man einen Buffer herumreicht, bei dem 
jeder noch seinen Senf zusätzlich anhängen kann (d.h. nicht an 
vordefinierte Stellen), das riecht dann mit rohen Arrays schnell nach 
Overflow. Das ist aber auch kein besonders glückliches Design und sollte 
nach Möglichkeit vermieden werden.

Abgesehen davon bin ich bei der Ausnutzung statischer Arraygrößen (via 
sizeof-Division) eh vorsichtig, weil einem sowas ganz schnell knallt, 
sobald man das dann z.B. im Mockup auf dem PC doch mal auf dynamisch 
allozierten Speicher umstellt. Dann lieber mit Größen-Defines, denen es 
egal ist, ob sie ein Array deklarieren oder als Futter für calloc 
dienen.

> Das Problem des TO ist, dass er erkennen muss, was das "Zerfallen" eines
> Array-Bezeichners zu einem Zeigertyp ist (decay of array designator).

Ja gut, das muß man einmal verstehen. In dem Fall wäre aber ohnehin die 
Technik mit einem Sentinel-Eintrag am Ende die einfachste, und die wurde 
ja auch schon vorgeschlagen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Nop schrieb:
> Wilhelm M. schrieb:
>
> Abgesehen davon bin ich bei der Ausnutzung statischer Arraygrößen (via
> sizeof-Division) eh vorsichtig, weil einem sowas ganz schnell knallt,
> sobald man das dann z.B. im Mockup auf dem PC doch mal auf dynamisch
> allozierten Speicher umstellt. Dann lieber mit Größen-Defines, denen es
> egal ist, ob sie ein Array deklarieren oder als Futter für calloc
> dienen.

Auch wenn ich mal sehr stark vermute, dass es sich hierbei um reinen 
C-Code handelt, so wäre die Lösung in C++ eben std::array für statische 
Arrays: dort ist die Größe Bestandteil des DT, und damit hat man kein 
Problem und keine Overhead.

Und wenn man es eh generisch schreibt, kann man auch std::array durch 
std::vector im Aufrufer austauschen, ohne eine weitere Zeile zu ändern 
...

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> bekomme Ich irgendwie die Anzahl der Einträge raus?

Ja. Mit einem simplen Macro:
1
typedef struct
2
{
3
  char *Name;
4
  uint8_t numb;
5
}menue_t;
6
7
menue_t mainMenue[]=
8
{
9
  {"Uhrzeit stellen"  ,0},
10
  {"Datum stellen"  ,1},
11
  {"Bluetooth"    ,2},
12
  {"Neustart"      ,3},
13
  {"Exit"        ,4},      
14
};
15
16
#define MENUEANZAHL ((sizeof mainMenue) / sizeof menue_t)

von Nop (Gast)


Lesenswert?

Wilhelm M. schrieb:

> so wäre die Lösung in C++ eben std::array für statische
> Arrays: dort ist die Größe Bestandteil des DT, und damit hat man kein
> Problem und keine Overhead.

Nein, das wäre keine Lösung. Siehe Vorposting, wo ich ausgeführt habe, 
daß nicht die Buffergröße entscheidend ist, sondern die Nutzdatengröße, 
welche kleiner gleich der Buffergröße ist.

> Und wenn man es eh generisch schreibt, kann man auch std::array durch
> std::vector im Aufrufer austauschen, ohne eine weitere Zeile zu ändern

Wenn man Arrays nimmt, dann macht man das, weil man keine dynamische 
Speicherverwaltung haben will. Auch nicht hinter dem Rücken des 
Programmierers. Daher ist auch das keine Lösung.

Dann müßte man sich schon Objekte basteln, die eine Art getter/setter 
haben, bei dem die Nutzdatenlänge reingepackt wird. Aber das kann man 
dann auch in C haben, wahlweise per struct oder per Parameter-Übergabe 
an die Funktion, die auch den Pointer bekommt (was das üblichere Idiom 
ist).

von Nop (Gast)


Lesenswert?

Rufus Τ. F. schrieb:

> Ja. Mit einem simplen Macro:

Für den Fall, daß es sich dabei um eine globale Variable handelt. Aber 
dann braucht man das auch nicht als Parameter an die Funktion zu 
übergeben, sondern kann das gleich mit Globals machen. Einen Pointer zu 
übergeben, aber die Größe als globales Define zu realisieren, ist nicht 
sonderlich wartungsfreundlich. Eigentlich sogar ein Codesmell, finde 
ich.

von J. F. (Firma: Père Lachaise) (rect)


Lesenswert?

Rufus Τ. F. schrieb:
> Ja. Mit einem simplen Macro:
> #define MENUEANZAHL ((sizeof mainMenue) / sizeof menue_t)

Ich würde diese Schreibweise wählen:

#define SIZE_OF_ARRAY(array) (sizeof(array)/sizeof((array)[0]))

Aber das ist eine Feinheit.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Wilhelm M. schrieb:
> Auch wenn ich mal sehr stark vermute, dass es sich hierbei um reinen
> C-Code handelt, so wäre die Lösung in C++ eben std::array für statische
> Arrays: dort ist die Größe Bestandteil des DT, und damit hat man kein
> Problem und keine Overhead.

std::array ist nur dann eine Lösung, wenn die Menüs, die an die Funktion
übergeben werden, immer die gleiche Anzahl von Einträgen haben. Das wird
hier wohl eher nicht der Fall sein.

von Wilhelm M. (wimalopaan)


Lesenswert?

J. F. schrieb:
> Rufus Τ. F. schrieb:
>> Ja. Mit einem simplen Macro:
>> #define MENUEANZAHL ((sizeof mainMenue) / sizeof menue_t)
>
> Ich würde diese Schreibweise wählen:
>
> #define SIZE_OF_ARRAY(array) (sizeof(array)/sizeof((array)[0]))
>
> Aber das ist eine Feinheit.

... und das geht eben nur (s.o.), wenn array nocht nicht zu einem 
Zeigertyp "zerfallen" ist.

von Wilhelm M. (wimalopaan)


Lesenswert?

Yalu X. schrieb:
> Wilhelm M. schrieb:
>> Auch wenn ich mal sehr stark vermute, dass es sich hierbei um reinen
>> C-Code handelt, so wäre die Lösung in C++ eben std::array für statische
>> Arrays: dort ist die Größe Bestandteil des DT, und damit hat man kein
>> Problem und keine Overhead.
>
> std::array ist nur dann eine Lösung, wenn die Menüs, die an die Funktion
> übergeben werden, immer die gleiche Anzahl von Einträgen haben.

Nö, jedes Menu kann eine unterschiedliche, aber zur Laufzeit konstante 
Anzahl von Elementen haben.

> Das wird
> hier wohl eher nicht der Fall sein.

Glaube ich kaum, sonst wären nach Standard-C auch keine rohen Arrays 
möglich.

von J. F. (Firma: Père Lachaise) (rect)


Lesenswert?

Wilhelm M. schrieb:
> ... und das geht eben nur (s.o.), wenn array nocht nicht zu einem
> Zeigertyp "zerfallen" ist.

Richtig, wie vorher schon angemerkt wurde. In meinen Augen ist es aber 
(in reinem C) akzeptabel wenn man einem kleinen Modul (welches die Daten 
des Arrays auswertet) die statische Definition global verarbeiten kann. 
Ich würde hier nicht von einem Code-Smell reden.

von Wilhelm M. (wimalopaan)


Lesenswert?

J. F. schrieb:
> Wilhelm M. schrieb:
>> ... und das geht eben nur (s.o.), wenn array nocht nicht zu einem
>> Zeigertyp "zerfallen" ist.
>
> Richtig, wie vorher schon angemerkt wurde. In meinen Augen ist es aber
> (in reinem C) akzeptabel wenn man einem kleinen Modul (welches die Daten
> des Arrays auswertet) die statische Definition global verarbeiten kann.
> Ich würde hier nicht von einem Code-Smell reden.

Das wollte ich auch nicht damit sagen. Jedoch kann ich mir wiederum 
viele Leute vorstellen, die nun glauben, diese Macro sei universell 
einsetzbar! Und genau das ist das Problem darin.

genau dafür gibt es in C++ std::size<>: das erkennt den potentiellen 
Fehler, weil es für Zeigertypen nicht spezialisiert ist.

: Bearbeitet durch User
von J. F. (Firma: Père Lachaise) (rect)


Lesenswert?

Wilhelm M. schrieb:
> Das wollte ich auch nicht damit sagen.

Das war auch nicht auf dich bezogen, ging aber aus dem Kontext nicht 
hervor.

> genau dafür gibt es in C++ std::size<>: das erkennt den potentiellen
> Fehler, weil es für Zeigertypen nicht spezialisiert ist.

Richtig, ein Grund warum ich C++ schöner finde. Der Threadersteller läßt 
uns aber nach wie vor im Dunkeln welche Sprache er in welcher Revision 
benutzt.

von Daniel A. (daniel-a)


Lesenswert?

Ich packe Arrays gerne in Structs. Ungetestet:
1
#define ARRAY(T, ...) (T[]){__VA_ARGS__}, sizeof((T[]){__VA_ARGS__})/sizeof(T)
2
3
struct int_array {
4
  int* values;
5
  size_t length;
6
};
7
8
struct int_array a = {ARRAY(int, 1,2,3,4)};

von Yalu X. (yalu) (Moderator)


Lesenswert?

Wilhelm M. schrieb:
> Yalu X. schrieb:
>> Wilhelm M. schrieb:
>>> Auch wenn ich mal sehr stark vermute, dass es sich hierbei um reinen
>>> C-Code handelt, so wäre die Lösung in C++ eben std::array für statische
>>> Arrays: dort ist die Größe Bestandteil des DT, und damit hat man kein
>>> Problem und keine Overhead.
>>
>> std::array ist nur dann eine Lösung, wenn die Menüs, die an die Funktion
>> übergeben werden, immer die gleiche Anzahl von Einträgen haben.
>
> Nö, jedes Menu kann eine unterschiedliche, aber zur Laufzeit konstante
> Anzahl von Elementen haben.

Wie müsste denn die Funktion test() deklariert werden, dass wahlweise
ein std::array<menue_t,5> oder ein std::array<menue_t,6> als Argument
übergeben werden kann?

Man könnte test() zwar als Template-Funktion mit der Array-Größe als
Parameter realisieren, das bläht aber ganz ordentlich, wenn man es mit
vielen verschiedenen Array-Größen zu tun hat und test() eine etwas
größere Funktion ist.

von A. S. (Gast)


Lesenswert?

Das Problem in C ist eigenlich, dass der Pointer zwei verschiedene 
Bedeutungen haben kann:

a) Eine Liste von Menüeinträgen. Hier bieten sich 0-Terminierte Listen 
an, wenn man über genügend C-Erfahrung verfügt, statische Analysetools 
hat und weiss, was man tut. Der meiste konservative Code zerfällt dann 
in fast nichts, analog zu den einfachen STringroutinen.

b) Einen konkreten Menüeintrag. Hier ist die Gesamtliste aber egal.

Von daher hast Du das Problem nicht, wenn Du einigermaßen Erfahrung 
hast. Fall nicht, musst Du Dir die Informationen der Arrays wrappen. Das 
geht auch elegant, aber Du brauchst jede Menge Code mehr.

von Wilhelm M. (wimalopaan)


Lesenswert?

Yalu X. schrieb:
> Wilhelm M. schrieb:
>> Yalu X. schrieb:
>>> Wilhelm M. schrieb:
>>>> Auch wenn ich mal sehr stark vermute, dass es sich hierbei um reinen
>>>> C-Code handelt, so wäre die Lösung in C++ eben std::array für statische
>>>> Arrays: dort ist die Größe Bestandteil des DT, und damit hat man kein
>>>> Problem und keine Overhead.
>>>
>>> std::array ist nur dann eine Lösung, wenn die Menüs, die an die Funktion
>>> übergeben werden, immer die gleiche Anzahl von Einträgen haben.
>>
>> Nö, jedes Menu kann eine unterschiedliche, aber zur Laufzeit konstante
>> Anzahl von Elementen haben.
>
> Wie müsste denn die Funktion test() deklariert werden, dass wahlweise
> ein std::array<menue_t,5> oder ein std::array<menue_t,6> als Argument
> übergeben werden kann?
>
> Man könnte test() zwar als Template-Funktion mit der Array-Größe als
> Parameter realisieren, das bläht aber ganz ordentlich, wenn man es mit
> vielen verschiedenen Array-Größen zu tun hat und test() eine etwas
> größere Funktion ist.

Genau!
Wir sind hier im Unterforum PC-Programmierung, und da ist die Code-Größe 
dann wohl egal. Bei µC hätte ich diese meine Antwort so nicht gegeben.

Und außerhalb des µC sollte man dann, also bei variablen Größen, eben 
besser auf den fast immer optimalen Container std::vector<> gehen.

Wobei der Code-Bloat eigentlich nur dann eintritt, wenn man fürchterlich 
ungeschickt vorgeht: also etwa eine Funktion test() schreibt, die 
sehr(!) lang ist und man sie nicht weiter untergliedert. Meistens ist es 
ja so, dass die öffentliche Schnittstelle als template gestaltet wird, 
intern dann aber was anderes abläuft, was oft nicht von den 
template-Parametern abhängt. Aber wie gesagt: das sollte einen 
eigentlich nur auf dem µC tangieren, wobei die heutigen Flash-Größen 
auch das Argument regelmäßig ad absurdum führen. Oft ist der 
RAM-Verbrauch auf µC der limitierende Faktor.

von Wilhelm M. (wimalopaan)


Lesenswert?

Hat der TO eigentlich schon mal verlauten lassen, ob er nun C oder C++ 
will?

von Jan H. (janiiix3)


Lesenswert?

Also das sollte für C sein. Hatte gedacht das man die Größe von dem 
Pointer Array raus bekommt. Von nem normalen Array das ich übergebe 
klappt das ja weil es eben nicht als pointer zerfällt.

von A. S. (Gast)


Lesenswert?

Jan H. schrieb:
> Von nem normalen Array das ich übergebe klappt das ja weil es eben
> nicht als pointer zerfällt.

???

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

Jan H. schrieb:
> Hatte gedacht das man die Größe von dem
> Pointer Array raus bekommt. Von nem normalen Array das ich übergebe
> klappt das ja weil es eben nicht als pointer zerfällt.
Du redest wirr. Jedes Array zerfaellt zu einem Pointer, wenn es an eine 
Funktion uebergeben wird. Egal ob es ein Array von Pointern ist, oder 
nicht.

Ja, du bekommst die Groesse des Arrays raus, aber nur bevor du es 
der Funktion uebergibst. In der Funktion geht das dann nicht mehr.

Geht:
1
void bar(irgendein_datentyp* p, size_t len)
2
{
3
    ...
4
}
5
6
void foo(void)
7
{
8
    irgendein_datentyp array[] = {...};
9
10
    bar(array, sizeof(array)/sizeof(array[0]));
11
}


Geht nicht:
1
void bar(irgendein_datentyp* p)
2
{
3
    size_t len = sizeof(p)/sizeof(p[0]);
4
}
5
6
void foo(void)
7
{
8
    irgendein_datentyp array[] = {...};
9
10
    bar(array);
11
}
Mach doch einfach mal ein vollstaendiges minimal Beispiel, damit wir 
nachvollziehen koennen was du willst/meinst.

von Jan H. (janiiix3)


Lesenswert?

Kaj G. schrieb:
> Jan H. schrieb:
> Hatte gedacht das man die Größe von dem
> Pointer Array raus bekommt. Von nem normalen Array das ich übergebe
> klappt das ja weil es eben nicht als pointer zerfällt.
>
> Du redest wirr. Jedes Array zerfaellt zu einem Pointer, wenn es an eine
> Funktion uebergeben wird. Egal ob es ein Array von Pointern ist, oder
> nicht.
>
> Ja, du bekommst die Groesse des Arrays raus, aber nur bevor du es der
> Funktion uebergibst. In der Funktion geht das dann nicht mehr.
 }
>
> Mach doch einfach mal ein vollstaendiges minimal Beispiel, damit wir
> nachvollziehen koennen was du willst/meinst.

Ich habe es aber schon mal mit nem Array hin bekommen..

CheckSize (char a[])
return (sizeof(a) /siueof(a|0]))

Beitrag #5293904 wurde vom Autor gelöscht.
von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

Jan H. schrieb:
> Ich habe es aber schon mal mit nem Array hin bekommen..
Nein, hast du nicht.
1
#include <stdio.h>
2
3
size_t check_size(char array[]);
4
5
6
int main(void)
7
{
8
    char text[] = "Was auch immer...";
9
10
    printf("Laenge: %ld\n", check_size(text));
11
    printf("Und jetzt richtig: %ld\n", sizeof(text)/sizeof(text[0]));
12
    return 0;
13
}
14
15
16
size_t check_size(char array[])
17
{
18
    return sizeof(array)/sizeof(array[0]);
19
}
1
$ gcc -Wall -Wextra -std=c99 -o main test.c
2
test.c: In function 'check_size':
3
test.c:18:18: warning: 'sizeof' on array function parameter 'array' will return size of 'char *' [-Wsizeof-array-argument]
4
     return sizeof(array)/sizeof(array[0]);
5
                  ^
6
test.c:16:24: note: declared here
7
 size_t check_size(char array[])
8
                        ^~~~~
Der Compiler sagt dir schon, dass das Unfug ist.
1
$ ./main 
2
Laenge: 8
3
Und jetzt richtig: 18
Haette das Array jetzt zufaellig genau 8 Elemente, dann wuerde es fuer 
Dich so aussehen, als ob es klappen wuerde. Tut es aber nicht.

von Rolf M. (rmagnus)


Lesenswert?

Yalu X. schrieb:
>> Nö, jedes Menu kann eine unterschiedliche, aber zur Laufzeit konstante
>> Anzahl von Elementen haben.
>
> Wie müsste denn die Funktion test() deklariert werden, dass wahlweise
> ein std::array<menue_t,5> oder ein std::array<menue_t,6> als Argument
> übergeben werden kann?
> Man könnte test() zwar als Template-Funktion mit der Array-Größe als
> Parameter realisieren, das bläht aber ganz ordentlich, wenn man es mit
> vielen verschiedenen Array-Größen zu tun hat und test() eine etwas
> größere Funktion ist.

Außerdem kann ich dann nicht mehr zur Laufzeit das Menü auswählen, denn 
ich muss ja dann bereits zur Compilezeit festelegen, welche Menügröße 
für diesen konkreten Aufruf gilt.

Jan H. schrieb:
> Ich habe es aber schon mal mit nem Array hin bekommen..

Dann war das kein C.

> CheckSize (char a[])
> return (sizeof(a) /siueof(a|0]))

a ist hier, auch wenn es irreführenderweise so aussieht, kein Array, 
sondern ein Zeiger. Du hast also die Größe eines Zeigers durch die Größe 
von dem, worauf er zeigt, dividiert.
Merke: Arrays ohne Größe gibt es nicht, also kann char a[] keine 
Array-Definition sein. Die einzige Stelle, wo man die Größe weglassen 
kann, ist beim Definieren einer Array-Variable mit gleichzeitiger 
Initialisierung. Dann ergibt sich die Größe aus dem Initializer.

: Bearbeitet durch User
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.