Was Sie in Ihrem Beitrag sagen, ist absolut richtig. Ich würde sagen, dass jeder C-Entwickler zu genau der gleichen Entdeckung und zu genau der gleichen Schlussfolgerung kommt, wenn (wenn) er bestimmte Kenntnisse der C-Sprache erreicht.
Wenn die Besonderheiten Ihres Anwendungsbereichs ein Array mit einer bestimmten festen Größe erfordern (die Arraygröße ist eine Konstante für die Kompilierungszeit), können Sie ein solches Array nur mithilfe eines Zeiger-zu-Array-Parameters an eine Funktion übergeben
void foo(char (*p)[10]);
(In der C ++ - Sprache erfolgt dies auch mit Referenzen
void foo(char (&p)[10]);
).
Dies ermöglicht die Typprüfung auf Sprachebene, wodurch sichergestellt wird, dass das Array mit genau der richtigen Größe als Argument angegeben wird. Tatsächlich verwenden Menschen diese Technik in vielen Fällen implizit, ohne es überhaupt zu merken, und verstecken den Array-Typ hinter einem typedef-Namen
typedef int Vector3d[3];
void transform(Vector3d *vector);
/* equivalent to `void transform(int (*vector)[3])` */
...
Vector3d vec;
...
transform(&vec);
Beachten Sie außerdem, dass der obige Code in Bezug auf den Vector3d
Typ, der ein Array oder ein Array ist, unveränderlich ist struct
. Sie können die Definition von Vector3d
jederzeit von einem Array in ein struct
und zurück ändern, ohne die Funktionsdeklaration ändern zu müssen. In beiden Fällen erhalten die Funktionen ein aggregiertes Objekt "als Referenz" (es gibt Ausnahmen, aber im Kontext dieser Diskussion ist dies wahr).
Sie werden diese Methode der Array-Übergabe jedoch nicht allzu oft explizit verwenden, einfach weil zu viele Leute durch eine ziemlich verworrene Syntax verwirrt sind und mit solchen Funktionen der C-Sprache einfach nicht vertraut genug sind, um sie richtig zu verwenden. Aus diesem Grund ist es im durchschnittlichen realen Leben ein beliebterer Ansatz, ein Array als Zeiger auf sein erstes Element zu übergeben. Es sieht einfach "einfacher" aus.
In Wirklichkeit ist die Verwendung des Zeigers auf das erste Element für die Array-Übergabe eine sehr Nischentechnik, ein Trick, der einem ganz bestimmten Zweck dient: Sein einziger Zweck besteht darin, die Übergabe von Arrays unterschiedlicher Größe (dh Laufzeitgröße) zu erleichtern. . Wenn Sie wirklich in der Lage sein müssen, Arrays mit Laufzeitgröße zu verarbeiten, können Sie ein solches Array am besten durch einen Zeiger auf sein erstes Element übergeben, wobei die konkrete Größe durch einen zusätzlichen Parameter angegeben wird
void foo(char p[], unsigned plen);
Tatsächlich ist es in vielen Fällen sehr nützlich, Arrays mit Laufzeitgröße verarbeiten zu können, was ebenfalls zur Popularität der Methode beiträgt. Viele C-Entwickler stoßen einfach nie auf die Notwendigkeit (oder erkennen sie nie), ein Array mit fester Größe zu verarbeiten, und sind sich daher der richtigen Technik mit fester Größe nicht bewusst.
Wenn die Arraygröße jedoch fest ist, übergeben Sie sie als Zeiger auf ein Element
void foo(char p[])
ist ein schwerwiegender Fehler auf technischer Ebene, der heutzutage leider ziemlich weit verbreitet ist. Eine Zeiger-zu-Array-Technik ist in solchen Fällen ein viel besserer Ansatz.
Ein weiterer Grund, der die Einführung der Array-Passing-Technik mit fester Größe behindern könnte, ist die Dominanz des naiven Ansatzes zur Typisierung dynamisch zugeordneter Arrays. Wenn das Programm beispielsweise feste Arrays vom Typ char[10]
(wie in Ihrem Beispiel) aufruft , verwendet ein durchschnittlicher Entwickler malloc
Arrays wie
char *p = malloc(10 * sizeof *p);
Dieses Array kann nicht an eine als deklarierte Funktion übergeben werden
void foo(char (*p)[10]);
Dies verwirrt den durchschnittlichen Entwickler und veranlasst ihn, die Parameterdeklaration mit fester Größe aufzugeben, ohne weiter darüber nachzudenken. In Wirklichkeit liegt die Wurzel des Problems jedoch im naiven malloc
Ansatz. Das malloc
oben gezeigte Format sollte für Arrays mit Laufzeitgröße reserviert werden. Wenn der Array-Typ eine Größe zur Kompilierungszeit hat, malloc
sieht der folgende Weg besser aus
char (*p)[10] = malloc(sizeof *p);
Dies kann natürlich leicht an die oben angegebene weitergegeben werden foo
foo(p);
und der Compiler führt die richtige Typprüfung durch. Aber auch dies ist für einen unvorbereiteten C-Entwickler zu verwirrend, weshalb Sie es im "typischen" durchschnittlichen Alltagscode nicht allzu oft sehen.
10
kann das Array durch eine beliebige Variable im Gültigkeitsbereich ersetzt werden