Zunächst einige Standardese :
6.7.5.3 Funktionsdeklaratoren (einschließlich Prototypen)
...
7 Eine Deklaration eines Parameters als '' Array vom Typ '' wird an '' qualifizierter Zeiger auf Typ '' angepasst
, wobei die Typqualifizierer (falls vorhanden) die angegebenen sind innerhalb der [und ]der Array-Typ-Ableitung. Wenn das Schlüsselwort staticauch in der Ableitung [und ]des Array-Typs vorkommt, muss der Wert des entsprechenden tatsächlichen Arguments bei jedem Aufruf der Funktion den Zugriff auf das erste Element eines Arrays mit mindestens so vielen Elementen ermöglichen, wie durch die Größe angegeben Ausdruck.
Kurz gesagt, jeder Funktionsparameter, der als deklariert T a[]oder T a[N]behandelt wird, wird so behandelt, als ob er deklariert worden wäre T *a.
Warum werden Array-Parameter so behandelt, als wären sie als Zeiger deklariert? Hier ist der Grund:
6.3.2.1 L-Werte, Arrays und Funktionsbezeichner
...
3 Außer wenn es sich um den Operanden des sizeofOperators oder des unären &Operators handelt oder um ein Zeichenfolgenliteral, das zum Initialisieren eines Arrays verwendet wird, einen Ausdruck vom Typ '' Array vom Typ ' 'wird in einen Ausdruck mit dem Typ' 'Zeiger auf Typ ' ' konvertiert, der auf das Anfangselement des Array-Objekts zeigt und kein l-Wert ist. Wenn das Array-Objekt eine Registerspeicherklasse hat, ist das Verhalten undefiniert.
Gegeben den folgenden Code:
int main(void)
{
int arr[10];
foo(arr);
...
}
Beim Aufruf von fooist der Array-Ausdruck arrkein Operand von entweder sizeofoder &, daher wird sein Typ gemäß 6.2.3.1/3 implizit von "10-Element-Array von int" in "Zeiger auf int" konvertiert. Somit foowird eher ein Zeigerwert als ein Arraywert empfangen.
Aufgrund von 6.7.5.3/7 können Sie schreiben fooals
void foo(int a[]) // or int a[10]
{
...
}
aber es wird interpretiert als
void foo(int *a)
{
...
}
Somit sind die beiden Formen identisch.
Der letzte Satz in 6.7.5.3/7 wurde mit C99 eingeführt und bedeutet im Grunde, dass, wenn Sie eine Parameterdeklaration wie haben
void foo(int a[static 10])
{
...
}
Der entsprechende tatsächliche Parameter amuss ein Array mit mindestens 10 Elementen sein.