71 votes

Que « [*] » (étoile modificateur) signifie en C ?

Tout en essayant de mettre en œuvre un C11 parser (à des fins pédagogiques), j'ai trouvé que dans C11 (p. 470) , mais aussi en C99 (p. 412) (merci Jean!), le direct de demande de déclaration est définie comme:

(6.7.6) direct-declarator:  
    direct-declarator [ type-qualifier-list? * ]

Au début, je pensais que c'était une erreur dans la grammaire (la liste type ne devrait pas être facultatif). Cependant, quand j'ai essayé ma référence compilateur clang), j'ai eu une assez inattendue d'erreur:

int array[*] = { 1, 2, 3 };
// error: star modifier used outside of function prototype

Donc, apparemment, (en clang) cela s'appelle de la star modificateur.

J'ai vite appris qu'ils ne peuvent être utilisés dans les signatures de la fonction:

void foobar(int array[*])

Toutefois, ils ne peuvent être utilisés dans la déclaration. Essayez de l'utiliser dans une définition de fonction entraîne un message d'erreur:

void foobar(int array[*]) {
    // variable length array must be bound in function definition
}

Donc autant que je peux dire, que le comportement est d'utiliser [*] dans la déclaration de la fonction et ensuite utiliser un nombre fixe dans la définition de la fonction.

// public header
void foobar(int array[*]);

// private implementation
void foobar(int array[5]) {

}

Cependant, je ne l'ai jamais vu et je ne comprends pas très bien le but de qu'il soit.

  1. Quel est son but, pourquoi était-il venu?
  2. Quelle est la différence avec int[]?
  3. Quelle est la différence avec int *?

42voto

haccks Points 33022

Quel est son but, pourquoi était-il venu?

Le but est vu lors d'une de longueur variable à deux dimensions tableau est utilisé comme paramètre d'une fonction. La fonction

int foo(int n, int m, int a[n][m])  {...}   

peut être prototypée les suivantes

int foo(int , int, int [][*]);
int foo(int , int, int a[*][*]);
int foo(int , int, int (*a)[*]);
int foo(int n, int, int a[n][*]);
int foo(int , int m, int a[*][m]);
int foo(int , int m, int (*a)[m]);
int foo(int n, int m, int a[n][m]); 

Dans le cas d'un tableau à deux dimensions, lorsqu'il est utilisé comme paramètre de la fonction, la taille de la seconde dimension ne peut pas être omis. Si le nom de la première des variables en fonction de prototype est omis, alors il ne serait pas possible de spécifier la durée (deuxième dimension) de la matrice. L' * donne l'idée que la longueur de la matrice sera déterminé par le deuxième paramètre.

Quelle est la différence avec int[]?
Quelle est la différence avec int *?

En cas de 1D tableau, pour la définition de fonction

int bar(int n, int a[n]} {...}  

tout du prototype suivant est valide

int bar (int , int *);
int bar (int , int [*]);
Int bar (int , int []);
int bar (int n, int a[]);
int bar (int n, int a[n]);
int bar (int n, int [n]);   

Dans ce cas ni * ni n est nécessaire que le compilateur va traiter à la fois de l' int [*] et int [n] comme int *. Donc, avec un tableau unidimensionnel vous ne pouvez pas voir beaucoup de différence.


REMARQUE: Lors de l'utilisation de longueur variable tableau comme paramètre d'une fonction, la commande de paramètre est important. L'ordre des paramètres pour les quatre premiers prototypes de bar peut être changé, mais dans les deux derniers premier paramètre ne doit pas être le tableau lui-même.

int bar (int a[n], int n);  //Wrong. Compiler has not yet seen 'n'.

16voto

Le C justification document C99 dit

Un prototype de fonction peuvent avoir des paramètres qui ont une longueur variable type de matrice (§6.7.5.2) à l'aide d'une syntaxe particulière comme dans

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

Ceci est cohérent avec les autres C des prototypes d'où le nom du paramètre n'a pas besoin d'être spécifié.


Quelle est la différence avec int[]

Quelle est la différence avec le type int *.

Je pense que c'est simplement que ces types dans un prototype de fonction signifie "pointeur", alors qu'un [*] dans une non-position supérieure (int[*] toujours égal int[] je crois, dans un prototype de fonction) est en fait valable et moyens de tableau

// not recommended though: it is now unclear what the parameters
// mean to human callers!
void f(int, int [][*]);

void f(int n, int x[][n]) {
    x[1][0] = 1;
}

int main() {
   int a[2][1];
   f(1, a);
   printf("%d\n", a[1][0]);
}

Comme pour l'objectif, lors de l'indexation de la matrice dans la définition de la fonction, le compilateur a besoin de savoir combien de nombres entiers du prochain indice pour sauter au moment de donner le premier indice (x[i] saute i * n des entiers en f ci-dessus). Mais cette information n'est pas nécessaire dans la non-définition de prototype de déclaration, par conséquent, il peut être laissé de côté et remplacé par *.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X