
Envoyé par
dalfab
J'ajoute qu'il reste pourtant une différence entre la définition d'un tableau local et d'un paramètre de type tableau. Essaye de comparer sizeof(var) et sizeof(argv) reçu de main().
C'est un paradoxe du C et du C++, pour avoir exactement la même chose, il faut déclarer :
1 2
| const char * var[] = {"Path", "-in", "fichierEntré", "-out", "fichierSortie"};
const char ** var2 = var; |
La variable var2 est alors totalement équivalente à argv!
En fait, c'est plutôt que ton tableau sera converti en pointeur vers son premier élément lorsque tu le passes à une fonction. Ce n'est pas un paradoxe, c'est la manière de faire... et je te l'accorde, ça peut sembler un peu tordu !
Le premier point à mettre au clair est le prototype exact de main(). J'ai écrit un article là-dessus : https://gradot.wordpress.com/2013/12...-de-main-en-c/ Ici, la forme qui nous intéresse est int main(int argc, char *argv[]);. Cette forme est équivalente à int main(int arg, char **argv). On s'en fiche donc un peu de déclarer notre variable de type char ** ou de type char*[] (je passe outre les différents const), car les variables du second type seront automatiquement convertis en variables du premier lorsqu'elles seront passées en paramètre à une fonction.
Voir ce code :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #include <stdio.h>
void f(const char **argv)
{
printf("%d\n", sizeof argv);
printf("%d\n", sizeof argv[0]);
}
int main(int argc, char *argv[])
{
puts("argv dans main()");
printf("%d\n", sizeof argv);
printf("%d\n", sizeof argv[0]);
puts("my_argv dans main()");
const char *my_argv[] = {"bonjour", "le", "monde"};
printf("%d\n", sizeof my_argv);
printf("%d\n", sizeof my_argv[0]);
puts("f() avec argv");
f(argv);
puts("f() avec my_argv");
f(my_argv);
} |
Compiler avec -Wall -Wextra -std=c99, il produit 2 warnings logiques :
||=== Build: Debug in C (compiler: GNU GCC Compiler) ===|
C:\cmp.c||In function 'main':|
C:\cmp.c|21|warning: passing argument 1 of 'f' from incompatible pointer type [enabled by default]|
C:\cmp.c|3|note: expected 'const char **' but argument is of type 'char **'|
C:\cmp.c|9|warning: unused parameter 'argc' [-Wunused-parameter]|
||=== Build finished: 0 error(s), 2 warning(s) (0 minute(s), 0 second(s)) ===|
||=== Run: Debug in C (compiler: GNU GCC Compiler) ===|
La sortie en console :
argv dans main()
4
4
my_argv dans main()
12
4
f() avec argv
4
4
f() avec my_argv
4
4
Au final, const char ** var2 = var; ne sert à rien. Au passage, si tu peux affecter var à var2 sans que le compilateur crie, c'est bien que tu peux utiliser var ou var2 (presque) de la même manière. Le compilateur sera automatiquement une telle conversion
Partager