web-dev-qa-db-fra.com

Pourquoi avons-nous besoin d'argc alors qu'il y a toujours un nul à la fin de argv?

Il semble que le argv[argc] est toujours NULL, donc je pense que nous pouvons parcourir la liste des arguments sans argc. Une seule boucle while fera cela.

S'il y a toujours un NULL à la fin de argv, pourquoi avons-nous besoin d'un argc?

113
StarPinkER

Oui, argv[argc]==NULL est garanti. Voir C11 5.1.2.2.1 Démarrage du programme (c'est moi qui souligne)

S'ils sont déclarés, les paramètres de la fonction principale doivent respecter les contraintes suivantes:

La valeur de argc doit être non négative. argv [argc] doit être un pointeur nul.

Fournir argc n'est donc pas vital mais reste utile. Entre autres choses, il permet de vérifier rapidement que le nombre correct d'arguments a été transmis.

Edit: La question a été modifiée pour inclure C++. n3337 draft 3.6.1 Fonction principale dit

2 ... argc doit être le nombre d'arguments transmis au programme à partir de l'environnement dans lequel le programme est exécuté. .... La valeur de argc doit être non négative. La valeur de argv [argc] doit être.

102
simonc

Oui, argv[argc] est garanti d'être un pointeur nul. argc est utilisé pour plus de commodité.

Citant l'explication officielle de la justification C99, notez les mots contrôle redondant :

Justification de la norme internationale - Langages de programmation - C §5.1.2.2.1 Démarrage du programme

La spécification de argc et argv comme arguments de main reconnaît une pratique antérieure étendue. argv[argc] doit être un pointeur nul pour fournir un contrôle redondant pour la fin de la liste, également sur la base de la pratique courante.

43
Yu Hao

C'est pour des raisons historiques et pour la compatibilité avec l'ancien code. À l'origine, il n'y avait aucune garantie qu'il existerait un pointeur nul comme dernier élément du tableau argv. Mais argc a toujours existé.

18
zentrunix

Nous en avons "besoin", car il est requis par diverses normes.

Nous sommes libres d'ignorer complètement la valeur, mais comme c'est le premier paramètre de main, nous devons l'avoir dans la liste des paramètres. En C++ (et probablement en dialectes C non standard), vous pouvez simplement omettre le nom du paramètre, comme cet extrait C++ (facile à convertir en C):

#include <stdio.h> // C-compatible include, guarantees puts in global namespace

// program will print contents of argv, one item per line, starting from argv[0]

int main(int /*argc*/, char *argv[]) { // uncomment argc for C

    //(void)argc; // uncomment statement for C

    for (int i=0; argv[i]; ++i) {
        puts(argv[i]);
    }

    return 0;
}

En C standard, avec des paramètres d'avertissement courants, le paramètre inutilisé génère un avertissement, qui peut être corrigé par une instruction comme (void)argc;, ce qui permet d'utiliser le nom sans générer de code.

argc est agréable à avoir, car sinon, de nombreux programmes devraient parcourir les paramètres pour obtenir le nombre. De plus, dans de nombreux langages de programmation avec des tableaux de longueur, il n'y a pas de paramètre argc, il y a juste un tableau avec les éléments.

6
hyde