[C++] Write to a Pointer

03/15/2012 16:09 jacky919#16
Quote:
Originally Posted by Metin2Spieler97 View Post
Das ARRAYSIZE-Makro macht auch nicht viel anderes als sizeof zu benutzen.
Richtig.
Code:
#define ARRAYSIZE(a) \
  ((sizeof(a) / sizeof(*(a))) / \
  static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
03/15/2012 16:10 ms​#17
Also sind wir uns nun einig, dass mein erster Post richtig war? ;O
03/15/2012 16:28 jacky919#18
Das Nutzen des Makros in Kombination mit einem Zeiger würde nicht funktionieren.
03/15/2012 19:55 MrSm!th#19
Nein, sind wir nicht.

Das richtige ArraySize Makro funktioniert sehr wohl mit Pointern, es wirft da nämlich nen Compiler-Fehler, dass die Aktion nicht erlaubt ist :P
Während ein selbstdefiniertes Makro mit sizeof die Größe des Pointers nutzen und damit rechnen würde.

Quote:
char *c und char c[] sind als Parameter genau das selbe.
In C vielleicht, in C++ nicht.

Zumindest VS sieht es einfach so, dass es selbst die Größe zu erkennen hat.
03/16/2012 17:02 ms​#20
Dass ein Pointer und ein Array zwei verschiedene Sachen sind ist klar.

Ich bin mir aber ziemlich sicher, dass als Parameter char *c und char c[] genau das selbe ist.
03/16/2012 17:17 jacky919#21
Bis darauf, dass bei dem Pointer ARRAYSIZE nicht richtig funktionieren würde, ist es dasselbe.
03/16/2012 17:21 ms​#22
Was wiederrum eine Eigenart von Visual C++ wäre, da sizeof ja nicht die Länge eines Arrays als Parameter herausfinden kann.

Ich glaube wir drehen uns hier im Kreis. :p
03/16/2012 17:52 jacky919#23
Habe dir Unrecht getan :)
Wenn ARRAYSIZE mit einem formalen Parameter genutzt wird, gibt es wirklich die Größe des Zeigers zurück.
03/17/2012 15:11 MrSm!th#24
Wir hatten beide Recht.

Um euch beim ARRAYSIZE Makro zu korrigieren:

Wie ich bereits sagte, es ist nicht einfach als sizeof(array)/sizeof(array[0]) definiert, deshalb gibt es keine Rechenfehler bei Pointern, die man diesem Makro übergibt.
Stattdessen wirft es einen Compiler-Fehler, da er die größe des Arrays nicht herausfinden kann.

M2S du hattest insofern Recht, dass es bei Parametern nicht möglich ist, da kommt dann wirklich die Meldung, er könne die Größe nicht von char [] herleiten, genau wie bei char * (habs mit char Arrays getestet). Bei statisch deklarierten Arrays wiederum funktioniert es. Das gilt aber für jegliche Arten von Arrays als Parametern, selbst, wenn man die größe explizit mit char param[42] angibt, kann er sie nicht herleiten (da musste ich den Umweg gehen und eine lokale Variable erstellen und den Inhalt aus dem Parameter kopieren).

Bei lokalen/globalen Variablen funktioniert es wie erwartet mit beiden Varianten, char var[42] oder auch char var[], wobei bei letzterem ja dann die Größe automatisch erkannt wird.

Übrigens ist das ganze keine Eigenart von VS, sondern ein wohldefiniertes Verhalten des ARRAYSIZE Makros, welches im WinDDK definiert ist.
Genauer gesagt gibt es 2 Varianten, eine Version für C und eine für C++. Erstere verhält sich so, wie ihr es bereits gesagt habt, zweitere ist folgendermaßen definiert:

Code:
template <typename T, size_t N>
char (*RtlpNumberOf( UNALIGNED T (&)[N] ))[N];

#define RTL_NUMBER_OF_V2(A) (sizeof(*RtlpNumberOf(A)))
03/18/2012 11:01 theredvex#25
heißt also quasi wenn ich die Größe nicht jedesmal als Parameter mitgeben will muss ich in der Funktion eine Variable erstellen die den Parameter kopiert, deren größe auslesen und damit arbeiten hab ich das jetzt richtig verstanden?
03/18/2012 11:05 jacky919#26
Verwnde std::vector :)
03/18/2012 12:50 ms​#27
Quote:
Originally Posted by theredvex View Post
heißt also quasi wenn ich die Größe nicht jedesmal als Parameter mitgeben will muss ich in der Funktion eine Variable erstellen die den Parameter kopiert, deren größe auslesen und damit arbeiten hab ich das jetzt richtig verstanden?
Nein, du musst einfach zu dem Pointer auch noch die Länge des Arrays übergeben.

Also aus

Code:
int f(char *c)
{
    //...
}
das hier machen.

Code:
int f(char *c, size_t s)
{
    //...
}
Egal ob du als Parameter char *c oder char c[] oder char c[5] nimmst, es ist immer ein Pointer. Ohne die Länge zu wissen kannst du das Array nicht kopieren weil du dann ja nicht weiß, wie groß es überhaupt ist.

Oder du benutzt eben std::vector, dann brauchst du keinen zusätzlichen Parameter für die Länge.