2016-06-06 22 views
5

Hier ist, was ist es written als Begründung der Phantasie * Sterne-Syntax für das Hinzufügen von Array-Typen innerhalb Funktionsprototypen für vereinbar erklärt wird - nur zur Klärung, bevor wir in die Frage bekommen:Warum "[*]" anstelle von "[]" im Funktionsprototyp verwenden?

Ein Funktionsprototyp Parameter, die Variable hat Länge Array-Typen (§6.7.5.2) mit einer speziellen Syntax wie in int minimum(int,int [*][*]); Dies ist konsistent mit anderen C-Prototypen, wo der Name des Parameters nicht angegeben werden muss.

Aber ich bin mir ziemlich sicher, dass wir den gleichen Effekt, indem einfach nur gewöhnlichen Arrays mit unbestimmter Größe wie diese haben können (hier Umschreiben die Funktion Beispiel minimum oben in dem Zitat gegeben Namen mit dem, was ich genau glauben die gleiche Funktionalität (mit Ausnahme size_t statt int als erste Parameter, die nicht so wichtig in dem Fall ist, verwendet wird)):

#include <stdio.h> 


int minimum(size_t, int (*)[]); 

int (main)() 
{ 
    size_t sz; 

    scanf("%zu", &sz); 

    int vla[sz]; 

    for(size_t i = 0; i < sz; ++i) 
     vla[i] = i; 

    minimum(sizeof(vla)/sizeof(*vla), &vla); 

    int a[] = { 5, 4, 3, 2, 1, 0 }; 

    minimum(sizeof(a)/sizeof(*a), &a); 
} 


int minimum(size_t a, int (*b)[a]) 
{ 
    for(size_t i = 0; i < sizeof(*b)/sizeof(**b); ++i) 
     printf("%d ", (*b)[i]); 

    return printf("\n"); 
} 

Weil ich bin mir ziemlich sicher, dass es ein Ort in der Norm war die besagt, dass 2 Arrays sind nur kompatibel, wenn ihre Größe gleich ist und es keine Rolle spielt, ob sie variabel sind oder nicht.

Mein Punkt wird auch durch die Tatsache bestätigt, dass die minimum Definition würde sich nicht für "widersprüchliche Typen" beschweren, wie es wäre, wenn einige seiner Parameter inkompatible Typen hätte (was ich denke nicht, ist der Fall als beides Arrays haben eine Größe, die zur Kompilierzeit nicht spezifiziert ist - ich verweise auf den zweiten Parameter minimum.

OK neben - können Sie mich zeigen 1 single use-case für [*], die nicht mit gewöhnlichen Arrays nicht spezifizierter Größe ersetzt werden kann?

Der obige Code kompiliert ohne Warnungen sowohl mit clang und gcc. Es produziert auch die erwartete Ausgabe.

Für jeden, der C nicht kennt (oder irgendjemand, der denkt, dass er/sie es weiß) - der Funktionsparameter des Typs array wird implizit in "Zeiger auf seinen Elementtyp" umgewandelt. dies so:

int minimum(int,int [*][*]); 

Ruft angepasst:

int minimum(int,int (*)[*]); 

Und dann bin ich dem Argument, dass es auch geschrieben werden könnte:

int minimum(int,int (*)[]); 

ohne Folgen und mit dem gleichen Verhalten wie die 2 Formen oben. Somit ist das Formular [*] veraltet.

+4

'int (*) []' ist kein VLA. Welchen Compilerfehler bekommst du? Hast du zumindest versucht zu kompilieren? Worum geht es dir? Sieht aus wie ein Anfang der Diskussion. Dies ist kein Diskussionsforum. – Olaf

+2

@Olaf Ich frage nach einem Anwendungsfall, bei dem die Star-Array-Syntax für Funktionsprototypen nicht durch ein gewöhnliches Array mit nicht spezifizierter Größe ersetzt werden kann. Und ja 'int (*) []' ist kein VLA, aber was ist dein Standpunkt? – AnArrayOfFunctions

+0

Es gibt keine "Star-Array-Syntax"! Ein Zeiger ist kein Array und umgekehrt. Lerne die Unterschiede, es gibt genug Fragen zu diesen Grundlagen. – Olaf

Antwort

6

OK neben - können Sie mich zeigen 1 single use-case für [*], die nicht ersetzt werden kann mit gewöhnlichen Arrays nicht spezifizierter Größe?

dies der Fall wäre, wenn Sie dreidimensionale VLA-Array übergeben:

int minimum(size_t, int (*)[*][*]); 

oder sogar eine Reihe von nicht näher Größe:

int minimum(size_t, int [*][*][*]); 

Dies kann wie folgt geschrieben werden:

int minimum(size_t, int (*)[][*]); 

Aber Sie haben keine Möglichkeit zu unterlassen noch um das letzte indice herumkommen, so muss es als [*] in einer solchen Erklärung bleiben.

+1

'Aber du Ich habe keine Möglichkeit, das letzte Indiz zu umgehen, also muss es in einer solchen Erklärung so bleiben. "Kannst du klarstellen, was du damit meinst? Die Grammatik reicht gerade aus Ich kann nicht sagen, was du meinst. – callyalater

+0

@callyalater: Bearbeitet, hoffentlich jetzt ist es besser. –

+0

Viel besser. Vielen Dank. Das macht jetzt viel mehr Sinn. – callyalater

6

[] kann nur als äußerster linker "Dimensionsspezifizierer" eines mehrdimensionalen Arrays verwendet werden, während [*] überall verwendet werden kann.

In Funktionsparameter Erklärungen, die am weitesten links stehende (nur!) [...] ist sowieso (*) eingestellt, so dass man (*) in dieser Position auf Kosten der Klarheit nutzen könnten.

Man kann die Dimension in der nächsten links [...] weglassen, die leeren Klammern verlassen. Dies wird den Array-Elementtyp unvollständig lassen.Dies ist keine große Sache, da man es in der Nähe des Verwendungsortes (z.B. in der Funktionsdefinition) vervollständigen kann.

Die nächste [...] benötigt eine Nummer oder * innerhalb der nicht weggelassen werden kann. Diese Erklärungen

int foo (int [*][*][*]); 
int foo (int (*)[*][*]); 
int foo (int (*)[ ][*]); 

sind alle kompatibel, aber es ist nicht ein kompatibel mit denen, die nicht angibt, die dritte Dimension entweder als * oder eine Zahl. Wenn die dritte Dimension tatsächlich variabel ist, ist * die einzige Option.

Somit ist [*] mindestens ab Dimension 3 erforderlich.