Je lis une section de C Primer Plus sur l'argument de ligne de commande argv
et j'ai du mal à comprendre cette phrase.
Il dit que
Le programme stocke les chaînes de ligne de commande en mémoire et stocke le adresse de chaque chaîne dans un tableau de pointeurs. L'adresse de ce tableau est stocké dans le deuxième argument. Par convention, ce pointeur sur les pointeurs s'appelle
argv
, pour les valeurs d'argument.
Cela signifie-t-il que les chaînes de ligne de commande sont stockées en mémoire en tant que tableau de pointeurs sur le tableau de char
?
argv
est de type char **
. Ce n'est pas un tableau . C'est un pointeur sur lequel indiquer char
. Les arguments de ligne de commande sont stockés dans la mémoire et l'adresse de chacun des emplacements de mémoire est stockée dans un tableau. Ce tableau est un tableau de pointeurs sur char
. argv
pointe vers le premier élément de ce tableau.
Certains tableau + ------- + + ------ + ------ + ------------- + ------ + argv - ---------> | | | | | | | | 0x100 + ------> | | | . . . . . . | | Nom du programme1 0x900 | | | | | | | | | + ------ + ------ + ------------- + ------ + + ------- + 0x100 0x101 | | + ------ + ------ + ------------- + ------ + | 0x205 | | | | | | 0x904 | + ------> | | | . . . . . . | | Arg1 | | . | | | | | + ------- + + ------ + ------ + ------------- + ------ + | . | . 0x205 0x206 | . | | . | . | . | + ------- +. + ------ + ------ + ------------- + ------ + | | | | | | | | 0x501 + ------> | | | . . . . . . | | Argargc-1 | | | | | | | + ------- + + ------ + ------ + ------------- + ------ + | | 0x501 0x502 | NULL | | | + ------- + 0xXXX représente l'adresse de la mémoire
1. Dans la plupart des cas, argv[0]
représente le nom du programme, mais si le nom du programme n'est pas disponible dans l'environnement hôte, argv[0][0]
représente un caractère nul.
Ce fil est une épave de train. Voici la situation:
argc+1
éléments de type char *
.argv
pointe vers le premier élément de ce tableau.argc
autres tableaux de type char
et de longueurs différentes, contenant des chaînes terminées par null représentant les arguments de la ligne de commande.char
; à l'exception du dernier élément du tableau de pointeurs, qui est un pointeur nul.Parfois, les gens écrivent "pointeur sur le tableau de X" pour signifier "pointeur sur le premier élément d'un tableau de X". Vous devez utiliser les contextes et les types pour déterminer s'ils ont réellement voulu dire cela.
argv
est un tableau de pointeurs sur des caractères.
Le code suivant affiche la valeur de argv
, le contenu de argv
et effectue un vidage de la mémoire sur la mémoire pointée par le contenu de argv
. Espérons que cela éclaire le sens de l'indirection.
#include <stdio.h>
#include <stdarg.h>
print_memory(char * print_me)
{
char * p;
for (p = print_me; *p != '\0'; ++p)
{
printf ("%p: %c\n", p, *p);
}
// Print the '\0' for good measure
printf ("%p: %c\n", p, *p);
}
int main (int argc, char ** argv) {
int i;
// Print argv
printf ("argv: %p\n", argv);
printf ("\n");
// Print the values of argv
for (i = 0; i < argc; ++i)
{
printf ("argv[%d]: %p\n", i, argv[i]);
}
// Print the NULL for good measure
printf ("argv[%d]: %p\n", i, argv[i]);
printf ("\n");
// Print the values of the memory pointed at by argv
for (i = 0; i < argc; ++i)
{
print_memory(argv[i]);
}
return 0;
}
Exemple de cycle:
$ ./a.out Hello World!
argv: ffbfefd4
argv[0]: ffbff12c
argv[1]: ffbff134
argv[2]: ffbff13a
argv[3]: 0
ffbff12c: .
ffbff12d: /
ffbff12e: a
ffbff12f: .
ffbff130: o
ffbff131: u
ffbff132: t
ffbff133:
ffbff134: H
ffbff135: e
ffbff136: l
ffbff137: l
ffbff138: o
ffbff139:
ffbff13a: W
ffbff13b: o
ffbff13c: r
ffbff13d: l
ffbff13e: d
ffbff13f: !
ffbff140:
$
Vous avez ce grand tableau contigu allant de ffbff12c
à ffbff140
qui contient les arguments de la ligne de commande (la norme ne garantit pas qu'elle soit contiguë, mais c'est généralement ce qui est fait). argv
ne contient que des pointeurs dans ce tableau pour que vous sachiez où chercher les mots.
argv
est un pointeur ... sur des pointeurs ... sur des caractères
Oui, exactement.
argv
est un char**
ou char*[]
, ou simplement un tableau de caractères *.
Ainsi, argv [0] est un char*
(une chaîne) et argv[0][0]
est un char
.
Oui.
Le type de argv
est char**
, c’est-à-dire un pointeur sur lequel indiquer char
. Fondamentalement, si vous considérez un char*
comme une chaîne, alors argv
est un pointeur sur un tableau de chaînes.