2010-09-12 5 views
15

In C99 gibt es Arrays variabler Länge, und es kann statischer Qualifier (und gibt Qualifikation) wird in Parameterarray Deklaratoren:C Parameter Array Deklaratoren

void f(int i, int *a); 
void f(int i, int a[]); 
void f(int i, int a[i]); 
void f(int i, int a[*]);   // Only allowed in function prototypes. 
void f(int i, int a[static i]); 

Da Parametern Array-Funktion einfach Abklingen auf Zeiger, gibt es Gibt es einen praktischen Unterschied zwischen den vorherigen Erklärungen oder ist es eine Frage des Stils? Wann sollte einer von ihnen verwendet werden? Was bedeutet insbesondere der Qualifier static? Der Standard macht den Grund für jede Syntax nicht klar.

Antwort

23

Solange Sie nur mit eindimensionalen Arrays arbeiten, sind die obigen Deklarationen alle gleichwertig. Die letzte aber

void f(int i, int a[static i]) 

hat eine zusätzliche Wirkung. Es entspricht den vorherigen in Bezug auf die Parametertypen, teilt dem Compiler aber auch mit, dass es sich auf a Parameter stützen kann, die auf ein Array von mindestens i Elementen zeigen (die in Optimierungen verwendet werden können).

Sie vergessen auch wieder eine neue Erklärung

void f(int i, int a[const]) 

Dies tut man tatsächlich einen Effekt auch bei einem eindimensionalen Array. Es entspricht

void f(int i, int *const a) 

obwohl einige argumentieren könnten, dass const-Qualifikationen auf Funktionsparameter nutzlos sind. Bevor es unmöglich war, den Zeiger konstant zu qualifizieren, "zerfällt" der Array-Parameter zu, wenn die Syntax [] für die Deklaration verwendet wird.

Die * (sowie i) zwischen den [] beginnt erst Rolle, wenn es zwischen dem zweiten (oder mehr) Paar in [] mehrdimensionales Array Erklärung verwendet wird. Im Wesentlichen ist es wie immer: Array-Größe in der Parameter-Deklaration zählte immer nur zwischen dem zweiten oder weiteren Paar von []. Die * wird in Prototyp-Deklarationen für VLA-Parameter verwendet, wenn der Größenwert nicht explizit benannt wird. Zum Beispiel können Sie

void bar(int n, int m, int a[n][m]); 

und die Compiler wissen, erklären, dass a ein VLA ist, da die Größen nicht Konstanten sind. Aber wenn Sie es vorziehen, Parameter nicht in Prototypen zu benennen, wie werden Sie dem Compiler sagen, dass a ein VLA ist? Das ist, wenn * hilft

void bar(int, int, int a[*][*]); 
+2

Vielen Dank für Ihre Klarstellung. Ich vermutete zunächst, dass der "statische" Qualifier mit Optimierungsproblemen zusammenhing. Außerdem haben Sie vergessen zu erwähnen, dass in dem Array-Deklarator alle Typ-Qualifier deklariert werden können, die eine sehr wichtige Rolle spielen (wie zum Beispiel "restrict" oder "volatile") als "const" selbst. – alecov

+0

Wenn ich 'func (int a [statisch 4] [6])' die statische kann nur innerhalb der ersten Klammern erklärt werden. Was ist, wenn ich das 'func (int (* a) [statisch 6])' was wird das tun? Gestatten Sie mir, die ersten 6 Werte der ersten Zeile vorab zu holen? Und was ist mit 'func (int * a [static 6])'? – user10607

+0

Was wäre die Bedeutung von 'void func1 (int a [-1])', 'void func2 (int a [some_global ++]);' oder 'void func3 (int length, int dat [length]);'? – supercat