2016-03-28 9 views
3

Ich mag würde das folgende Makro mit einer tatsächlichen Funktion in C.Länge beliebigen Array-Typ in C-Funktion

#define ARRAY_LENGTH(a) (sizeof(a)/sizeof((a)[0])) 
+10

Kann nicht gemacht werden. Wenn das Array an eine Funktion übergeben wird, geht die Größeninformation verloren. Weitere Informationen finden Sie in diesem Beitrag (https://stackoverflow.com/questions/1461432/what-is-array-decaying). – user3386109

+2

Warum willst du das? Es gibt gute Anwendungen für Makros. Dies ist einer von ihnen. – Olaf

+0

@ user3386109: Genauer gesagt: das Array verfällt zu einem Zeiger auf seine Elemente, die offensichtlich ein anderer Typ ist. Aber selbst wenn dies nicht der Fall wäre, können Sie unter Beibehaltung der Typinformationen keinen beliebigen Typ an eine Funktion übergeben. – Olaf

Antwort

-5
int arraySz(void **a) 
{ 
return(sizeof(a[])/sizeof(a[][])); 
} 

jedoch ersetzen ein würde zu einem bestehenden rechteckigen zu zeigen Array, nicht nur ein Zeiger auf einen Zeiger oder Rückgabewert von malloc().

+0

Für einen Starter: 'a' ist kein Array, also wo ist die Größe? Hinweis: Sie können ein Array nicht an eine Funktion übergeben. Und Ihr Code verliert wichtige Typinformationen der Elemente. Es gibt andere Probleme und Fehler in diesem Code. Mehr als Linien. – Olaf

1

Behalten Sie Ihr Makro. Ersetzen ist ein Fehler. Wenn Sie ein Array an eine Funktion übergeben, zerfällt es in einen Zeiger und Sie verlieren Größeninformationen.

+0

Bitte beachten Sie [meine Kritik bezüglich der Implikationen von Phrasen wie "it (sic: the array) decays"] (http://stackoverflow.com/questions/36272402/length-of-arbitrary-array-type-in-c-) Funktion # comment60176087_36272402), oben ... – Sebivor

+0

Guter Punkt. Ich werde meine Terminologie verbessern. –

1

Wie andere gesagt haben, können Sie nicht.


Wenn Sie ein Argument an eine Funktion übergeben, wird der Wert dieses Ausdrucks in ein neues Objekt kopiert.

Ein Problem ist functions can't have arrays as arguments. Array-Deklarationen in Funktionsprototypen werden in Zeigerdeklarationen konvertiert.

In ähnlicher Weise wird der Ausdruck, der das übergebene Array bezeichnet, in einen Zeiger auf das erste Element des Arrays konvertiert.

Ein weiteres Problem auf Ihrem Weg ist, dass C keine generischen Funktionen hat. Es gibt keine Möglichkeit, eine Funktion mit einem "Array von T" zu versehen, wobei T ein beliebiger Typ sein kann, abgesehen von der Verwendung eines void * Parameters und der Weitergabe von Größeninformationen.


Funktionelle Makros werden jedoch in einer anderen Phase erweitert. Sie werden während der Kompilation übersetzt. Stellen Sie sich vor, dass Sie den Code für das Makro kopieren und einfügen, wo immer es erwähnt wird, und ersetzen Sie die Argumente vor der Kompilierung. Das macht dein Compiler mit Makros.

Wenn Sie zum Beispiel printf("%zu\n", ARRAY_LENGTH(foo)); schreiben, wird dieses durch: printf("%zu\n", (sizeof(foo)/sizeof((foo)[0]))); ersetzt.


P.S. sizeof ist keine Funktion; es ist ein Operator ... Zufälligerweise ist es einer der wenigen (die anderen sind die & Adresse-Operator und der neu übernommene _AlignOf-Operator), die nicht die Array-Ausdruck zu einem Zeiger Ausdruck umgewandelt werden .