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 static
auch 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 sizeof
Operators 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 foo
ist der Array-Ausdruck arr
kein Operand von entweder sizeof
oder &
, daher wird sein Typ gemäß 6.2.3.1/3 implizit von "10-Element-Array von int
" in "Zeiger auf int
" konvertiert. Somit foo
wird eher ein Zeigerwert als ein Arraywert empfangen.
Aufgrund von 6.7.5.3/7 können Sie schreiben foo
als
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 a
muss ein Array mit mindestens 10 Elementen sein.