Ce que vous dites dans votre post n'est absolument correct. Tout développeur C vient exactement la même découverte et exactement à la même conclusion quand (si) ils atteignent un certain niveau de compétence, avec C la langue.
Lorsque les spécificités de votre secteur d'activité appel à un certain nombre de taille fixe (taille de la matrice est une constante de compilation), la seule bonne façon de passer un tableau à une fonction en utilisant un pointeur de tableau de paramètre
void foo(char (*p)[10]);
(en langage C++ cela se fait aussi avec des références
void foo(char (&p)[10]);
).
Cela permettra de langue au niveau de la vérification de type, qui sera assurez-vous que le tableau de exactement de taille correcte est fournie en argument. En fait, dans de nombreux cas, les gens d'utiliser cette technique de manière implicite, sans même s'en rendre compte, se cachant le type du tableau derrière un typedef nom
typedef int Vector3d[3];
void transform(Vector3d *vector);
/* equivalent to `void transform(int (*vector)[3])` */
...
Vector3d vec;
...
transform(&vec);
Notez que le code ci-dessus est invariante par rapport à l' Vector3d
type d'un tableau ou d'un struct
. Vous pouvez changer la définition de l' Vector3d
à tout moment à partir d'un tableau à un struct
et à l'arrière, et vous n'aurez pas à changer le reste du code (il ya des exceptions à cela, mais dans le contexte de cette discussion, c'est vrai).
Cependant, vous ne verrez pas cette méthode de la matrice de passage utilisé explicitement trop souvent, tout simplement parce que trop de nombreuses personnes se confondre par un plutôt alambiqué et de syntaxe ne sont tout simplement pas assez confortable avec de telles caractéristiques du langage C pour les utiliser correctement. Pour cette raison, en moyenne, la vraie vie, le passage d'un tableau comme un pointeur vers son premier élément est le plus répandu. Il a juste l'air plus "simple".
Mais en réalité, à l'aide du pointeur vers le premier élément de la matrice de passage est un créneau très technique, une astuce, qui sert un but très précis: son seul but est de faciliter le passage de tableaux de taille différente (c'est à dire au moment de l'exécution de la taille). Si vous avez vraiment besoin pour être en mesure de traiter les tableaux de la durée d'exécution de la taille, puis à la bonne façon de passer un tableau est un pointeur vers son premier élément avec le béton de la taille fournie par un paramètre supplémentaire
void foo(char p[], unsigned plen);
En fait, dans de nombreux cas, il est très utile d'être en mesure de traiter les tableaux de la durée d'exécution de la taille, ce qui contribue également à la popularité de la méthode. De nombreux développeurs C tout simplement de ne jamais rencontrer (ou jamais reconnaître) la nécessité de traiter un tableau de taille fixe, donc en restant insensible à la bonne taille fixe de la technique.
Néanmoins, si la taille de la matrice est fixe, passant comme un pointeur vers un élément
void foo(char p[])
est une technique principale erreur de niveau, ce qui n'est malheureusement assez répandue de nos jours. Un pointeur vers tableau technique doit être utilisée à la place dans de tels cas.
Une autre raison qui pourrait empêcher l'adoption du tableau de taille fixe la technique de passage, c'est la domination de l'approche naïve, à la saisie de tableaux alloués dynamiquement. Par exemple, si le programme d'appels pour les matrices de type char[10]
(comme dans votre exemple), une moyenne développeur malloc
de ces tableaux
char *p = malloc(10 * sizeof *p);
Ce tableau ne peut pas être transmis à une fonction déclarée comme
void foo(char (*p)[10]);
qui confond le développeur moyen, et leur fait abandonner la taille fixe déclaration de paramètre sans lui donner une autre pensée. En réalité, si, à la racine du problème réside dans le naïf malloc
approche. L' malloc
technique ci-dessus est, à nouveau, réservés pour les tableaux de la durée d'exécution de taille. Si le type du tableau a au moment de la compilation de la taille, de la bonne façon d' malloc
il se présenterait comme suit
char (*p)[10] = malloc(sizeof *p);
Bien entendu, cela peut être facilement transmis à la ci-dessus déclarée foo
foo(p);
et le compilateur d'effectuer le bon type de vérification. Mais encore une fois, c'est trop confus pour un non préparés développeur C, qui est pourquoi vous ne voyez pas trop souvent dans le "typique" de la moyenne quotidienne de code.