Question

C-type (< strong> 5.1.2.2.1 démarrage du programme ) dit:

  

La fonction appelée au démarrage du programme   est nommé principal. [...]   Il est défini par une   type de retour int et sans   Paramètres:
   int main(void) { /* ... */ }

     

ou avec deux paramètres [...] :
   int main(int argc, char *argv[]) { /* ... */ }

Et dit plus tard:

  

La valeur de argc non négative.

  • Pourquoi ne devrait pas argc être défini comme un unsigned int, ce qui signifie argc soi-disant «nombre d'arguments?
  • Si argc être utilisé comme un indice pour argv?

Je commençais à me demander si la norme C dit quelque chose au sujet du type de l'index de tableau. Est-il signé?

6.5.2.1 souscriptage de tableau :

  

L'une des expressions doit avoir le type   « « pointeur type d'objet » », l'autre   expression a type entier ,   et le résultat est de type '' type .

Il ne dit rien au sujet de son signedness (ou je ne trouve pas). Il est assez fréquent de voir des codes en utilisant les indices de tableau négatifs (de array[-1]), mais est-ce pas un comportement non défini?

  • index de tableau non signé Faut-il?
Était-ce utile?

La solution

La raison de l'int main () est historique - il a toujours été de cette façon, depuis longtemps avant que la langue a été normalisée. L'exigence d'un indice de tableau est qu'il est dans les limites du tableau (ou dans certaines circonstances, un après la fin) -. Quoi que ce soit est non défini d'autre, de sorte que le signedness est immatériel

Autres conseils

1) A propos principal () Type de argc: à mon humble avis la norme continue une tradition très ancienne (plus de 30 ans), et maintenant ... il est tout simplement trop tard pour changer les choses (REMARQUE: sur la plupart des systèmes ni le compilateur, ni l'éditeur de liens, ni la CPU se plaindront si « argc » est défini « non signé », mais vous êtes hors de la norme!)

2) Sur la plupart des implémentations argv [argc] est légal et évalue à NULL. En effet, une autre façon de trouver la fin de la liste des arguments est de itérer sur argv de 0 lorsque se termine argv [i] est NULL.

3) arithmétique Array / pointeur avec des nombres négatifs est légal dans la mesure où la plage d'adresses à partir de (p-n) à p appartient au même objet mémoire. C'EST À DIRE. vous pouvez avoir

char array[100];
char *p;

p = &array[50];
p += -30; /* Now p points to array[20]. */

Cette utilisation de l'arithmétique de pointeur est légal, car le pointeur résultant reste encore à l'intérieur de l'objet de mémoire d'origine ( « tableau »). Le système le plus l'arithmétique de pointeur peut être utilisé pour naviguer en mémoire en violation de cette règle, mais ce n'est pas portable car il est complètement dépendant du système.

En général en C, le « principe de moindre surprise » implique qu'il est préférable de faire une variable signée à moins qu'il y ait une bonne raison pour qu'il soit non signé. En effet, les règles de type promotion peuvent conduire à des résultats inattendus lorsque vous mélangez valeurs signées et non signées: par exemple, si argc était non signée alors cette simple comparaison conduirait à des résultats surprenants:

if (argc > -1)

(Le -1 est promu unsigned int, de sorte que sa valeur est convertie en UINT_MAX, ce qui est presque certainement supérieure à argc).

1) ARGC est un nombre d'arguments, mais pour être tout à fait honnête, comment pouvez-vous précédez un argument avant le nom du programme qui argv[0]. Imaginez un programme appelé foo, vous ne pouvez pas dire simplement args1 foo args2 que cela n'a pas de sens, en dépit de la argc étant un type signé de int, à savoir pas une telle chose comme argv[-1] qui vous obtenez « args1 » ...

2) La raison argc est pas vraiment un indice au vecteur d'argument (d'où « argv ) comme exécution enfourne le nom du programme exécutable dans le zero'th offset, par exemple argv[0] donc le argc sera éteint par 1.

3) Les indices de tableau, en termes de manipulation de pointeur, fourni vous êtes dans les limites du bloc de mémoire où le pointeur est à l'aide des indices de tableau négatif est légal que les indices de tableau sont un raccourci pour les pointeurs, et non seulement, ils sont commutative par exemple

char v[100];
char *p = &v[0];

You can do this:

p[55] = 'a'; 

Which is the same as

*(p + 55) = 'a';

You can even do this:

p = &v[55];

p[-10] = 'b' /* This will stuff 'b' into 45'th offset! */

Which is the same as

*(p - 10) = 'b';

Aussi, si vous utilisez et de les manipuler de telle manière qui est en dehors des limites - c'est un comportement non défini et dépendra de la mise en œuvre de l'exécution sur la façon de gérer, peut-être une erreur de segmentation, ou un programme accident ....

4) Dans les environnements * nix, certains ont un troisième paramètre fourni principal char **endvp, encore une fois ce qui est rarement utilisé dans le monde Microsoft DOS / Windows. Certaines implémentations * nix d'exécution, pour des raisons pré-historiques, vous pourriez passer dans les variables d'environnement par l'exécution.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top