web-dev-qa-db-fra.com

C ++ - char ** argv contre char * argv []

Quelle est la différence entre char** argv Et char* argv[]? dans int main(int argc, char** argv) et int main(int argc, char* argv[])?

Sont-ils les mêmes? Surtout que la première partie n'a pas [].

49
Simplicity

Ils sont entièrement équivalents. char *argv[] doit être lu comme un tableau de pointeurs vers char et un argument de tableau est rétrogradé en pointeur, donc pointeur vers pointeur vers char ou char **.

C'est la même chose dans C .

54
Fred Foo

Ils sont en effet exactement les mêmes.

La règle d'or des tableaux à retenir est la suivante:

"Le nom d'un tableau est un pointeur vers le premier élément du tableau."

Donc, si vous déclarez ce qui suit:

char text[] = "A string of characters.";

Ensuite, la variable "texte" est un pointeur sur le premier caractère du tableau de caractères que vous venez de déclarer. En d'autres termes, le "texte" est de type char *. Lorsque vous accédez à un élément d'un tableau à l'aide de l'index [], ce que vous faites réellement est d'ajouter un décalage de indexer le pointeur sur le premier élément du tableau, puis déréférencer ce nouveau pointeur. Les deux lignes suivantes initialiseront donc les deux variables à 't':

char thirdChar = text[3];
char thirdChar2 = *(text+3);

L'utilisation des crochets est une commodité fournie par le langage qui rend le code beaucoup plus lisible. Mais la façon dont cela fonctionne est très importante lorsque vous commencez à penser à des choses plus complexes, telles que des pointeurs vers des pointeurs. char** argv est le même que char* argv[] car dans le second cas "le nom du tableau est un pointeur vers le premier élément du tableau".

À partir de cela, vous devriez également pouvoir comprendre pourquoi les index de tableau commencent à 0. Le pointeur vers le premier élément est le nom de variable du tableau (règle d'or à nouveau) plus un décalage de ... rien!

J'ai eu des débats avec un de mes amis pour savoir lequel est préférable d'utiliser ici. Avec le char* argv[] notation, il peut être plus clair pour le lecteur qu'il s'agit en fait d'un "tableau de pointeurs vers des caractères" par opposition à char** argv notation qui peut être lue comme un "pointeur vers un pointeur vers un caractère". Mon opinion est que cette dernière notation ne transmet pas autant d'informations au lecteur.

Il est bon de savoir qu'ils sont exactement les mêmes, mais pour la lisibilité, je pense que si l'intention est un tableau de pointeurs, le char* argv[] la notation exprime cela beaucoup plus clairement.

24
James Bedford

À toutes fins pratiques, ce sont les mêmes. Cela est dû à la gestion par C/C++ des tableaux passés en arguments, où un tableau se désintègre en un pointeur.

3
Erik

Pour la première partie de la question:

  • char ** argv: pointeur vers un pointeur vers un caractère
  • char * argv []: pointeur vers un tableau

La question est donc de savoir si un pointeur vers un type C et un tableau C [] sont les mêmes choses. Ils ne sont pas du tout en général, MAIS ils sont équivalents lorsqu'ils sont utilisés dans les signatures .

En d'autres termes, il n'y a pas de différence dans votre exemple, mais il est important de garder à l'esprit la différence entre pointeur et tableau sinon.

3
David Cournapeau

La forme de parenthèse n'est utile que dans les déclarations d'instructions comme:

char *a[] = {"foo", "bar", "baz"};
printf("%d\n", sizeof a / sizeof *a);
// prints 3

Parce qu'il connaît au moment de la compilation la taille du tableau. Lorsque vous passez une forme de parenthèse en tant que paramètre à une fonction (principale ou autre), le compilateur n'a aucune idée de la taille du tableau au moment de l'exécution, c'est donc exactement la même chose que char ** a. Je préfère char ** argv car il est plus clair que sizeof ne fonctionnerait pas comme sur le formulaire de déclaration de déclaration.

2
Jake