Différence entre int main () et int main (void)?
que signifie ce qui suit :
int main(void) {...}
VS
int main() {...}
?
je pense que int main() {...}
signifie que main ne reçoit aucun paramètre (de la ligne de commande) , cependant:
int main(int argc, char *argv[])
ne.
mais que signifie int main(void) {...}
? que signifie le nul ?
j'ai regardé ici mais c'est une autre question .
8 réponses
en C++, il n'y a pas de différence.
en C, la différence est discutable. Certains aiment à faire valoir que cette dernière version (celle sans void
) est techniquement juste une extension commune de la mise en œuvre et ne garantit pas de fonctionner par la norme en raison de la formulation dans la norme. Cependant, la norme stipule clairement que, dans la définition d'une fonction d'un ensemble vide de paramètres a un comportement défini: que la fonction ne ne pas prendre tous les paramètres. Ainsi, une telle définition pour main correspond à la description suivante de la norme:
Il [principal] doit être défini avec le type de retour de type int et sans paramètres.
il y a, cependant, une différence notable entre les deux: à savoir, la version sans void
ne fournit pas un prototype correct pour la fonction:
// this is OK.
int main()
{
if (0) main(42);
}
// this requires a diagnostic to be shown during compiling
int main(void)
{
if (0) main(42);
}
Oh, et juste pour être complete: le void
a la signification suivante dans tous les declarateurs de fonction:
(6.7.6.3p10) le cas particulier d'un paramètre sans nom de type void comme seul élément de la liste spécifie que la fonction n'a pas de paramètres.
En C, dans un prototype (pas en C++) un argument vide de la liste signifie que la fonction "prendre 151920920" tout arguments (dans la définition d'une fonction, cela signifie pas d'arguments). Dans C++, une liste de paramètres vide signifie pas d'arguments. En C, pour obtenir aucun argument, vous devez utiliser void
. Voir cette" question pour une meilleure explication.
en C++ ayant une fonction foo(void)
et foo()
est la même chose. Cependant, en C, c'est différent: foo(void)
est une fonction qui n'a pas d'arguments, tandis que foo()
est une fonction avec des arguments Non spécifiés.
en C++, il n'y a pas de différence, les deux sont identiques.
les deux définitions fonctionnent aussi en C, mais la deuxième définition avec vide est considérée techniquement meilleure car elle spécifie clairement que main ne peut être appelé que sans aucun paramètre. En C, si une signature de fonction ne spécifie aucun argument, cela signifie que la fonction peut être appelée avec n'importe quel nombre de paramètres ou sans n'importe quels paramètres. Par exemple, essayez de compiler et exécuter deux programmes C (souvenez-vous de enregistrer vos fichiers comme .C.)
tout d'abord, il y a une différence entre ce qui est autorisé pour les systèmes hébergés et les systèmes autonomes, comme montré ici .
pour les systèmes hébergés, 5.1.2.2.1 le démarrage du programme s'applique:
la fonction appelée au démarrage du programme s'appelle main. La mise en œuvre déclare non prototype pour cette fonction. Il doit être défini avec un type de retour int et sans paramètres:
int main(void)
... (plus de texte suit concernant les styles argv/argc etc).
la partie intéressante est"sans paramètres". int main()
et int main (void)
sont actuellement équivalents, car ils sont tous deux des déclarants de fonctions et n'ont pas de paramètres. Les dispositions suivantes s'appliquent (6.7.6.3 ):
10 le cas particulier d'un paramètre sans nom de type NULL comme seul élément de la liste spécifie que la fonction n'a pas paramètre.
/ -- /
14 une liste d'identificateurs ne déclare que les identificateurs des paramètres de la fonction. vide liste dans une fonction de demande de déclaration qui fait partie d'une définition de cette fonction spécifie que le la fonction n'a pas de paramètres. la liste vide d'un déclarant de fonction qui ne fait pas partie d'un la définition de cette fonction précise qu'aucune information sur le nombre ou les types de paramètres est fournie.145)
je souligne, le texte en gras est celui qui s'applique à int main()
. Il y a aussi la note 145) à la fin du texte, qui dit "Voir" orientations linguistiques futures’ (6.11.6)":
6.11.6 declarateurs de fonctions
l'utilisation de declarateurs de fonctions avec des parenthèses vides (pas de declarateurs de type de paramètre de format prototype) est une caractéristique obsolescente.
et voici la différence. Étant un déclarant de fonction, int main()
est mauvais style en raison de ce qui précède, car il n'est pas garanti de travailler dans la prochaine version de la norme C. Il est signalé comme une caractéristique obsolescente en C11.
vous devez donc toujours utiliser int main (void)
sur un système hébergé et jamais int main()
, même si les deux formes sont, pour l'instant, équivalentes.
en C++ les deux formes sont complètement équivalentes, mais il y a int main()
qui est le style préféré pour des raisons subjectives et cosmétiques (Bjarne Stroustrup le dit... ce qui est probablement une assez mauvaise raison pour expliquer pourquoi vous faites quelque chose d'une manière particulière).
en C++, il n'y a pas de différence entre les deux, et int main()
est une signature légale et un type de retour pour main
.
prototype de Fonction ayant Type foo(void)
est absolument la même chose que Type foo()
, il n'y a pas de différence entre les deux. Les premières peuvent être utilisées pour la lisibilité.
comme avec main
- en prenant des arguments ou non, le programme peut encore accéder à des informations en ligne de commande par d'autres moyens comme __argv
, __argc
, GetCommandLine
, ou d'autres symboles spécifiques de la plateforme / du compilateur.
je sais que le fil est vieux mais cette question me dérangeait il y a quelques années donc j'ai voulu jeter dans mon demi-cent(si cela).
je traite toujours les fonctions C comme si elles avaient un nombre fixe d'arguments indépendamment du contexte, à moins qu'elles n'utilisent va_args. C'est-à-dire, je fais confiance à main pour avoir toujours le prototype:
int main(int argc, char **argv).
même si aucun argument n'est passé, la fonction a ces arguments sur la pile parce que la fonction principale ne pas de surcharge de fonctions.
C a la capacité d'avoir une surcharge primitive en faisant semblant que l'argument n'est pas là. Dans ce cas, l'argument est toujours passé et est sur la pile mais vous n'y accédez jamais, donc il réduit simplement la taille du code source.
dire int main() signifie simplement que je sais que la fonction peut avoir des paramètres, mais je ne les utilise pas, donc j'écris int main().
disant int main (void) dit que main N'a certainement pas d'arguments, et implique qu'il y a deux prototypes de fonction différents:
int main(void);
int main(int argc, char **argv);
comme C n'a pas de surcharge de fonction, cela m'est quelque peu trompeur, et je me méfie du code qui contient main(void). Je ne le ferais pas si main N'a jamais pris aucun paramètre, auquel cas main(nul) serait complètement OK.
NOTE: dans certaines implémentations, il y a plus de paramètres dans le main que argc et argv, comme env, mais cela ne me dérange pas parce que je sais que je ne le disent pas explicitement que ce sont les deux seuls paramètres, mais ces paramètres minimaux et il est normal d'avoir plus, mais pas moins. Ceci est en contraste avec le fait de dire directement int main (void) qui hurle à moi comme cette fonction N'a pas de paramètres, ce qui n'est pas vrai, car il le fait, ils sont juste omis.
Voici mon code de base:
/* sample.c - build into sample. */
#include <stdio.h>
int main(void)
{
int _argc = *((int *)2686800);
char ***_pargv = (char ***)2686804;
int i;
for (i = 1; i < _argc; ++i) {
printf("%s ", (*_pargv)[i]);
}
return 0;
}
./ exemple j'ai clairement des arguments
la fonction a clairement des arguments qui lui ont été transmis, malgré le fait qu'elle ne le soit pas en tapant vide dans le prototype de la fonction.
Comme eq - dit au-dessus:
(6.7.6.3p10) le cas particulier d'un paramètre sans nom de type vide comme le seul élément de la liste indique que la fonction n'a pas de paramètres.
disant Ainsi que la fonction a nul comme un argument mais avoir des arguments sur la pile est une contradiction.
mon point est que les arguments sont toujours là, donc affirmer explicitement que main est sans arguments est malhonnête. La façon honnête serait de dire int main(), qui ne revendique rien sur le nombre de paramètres qu'il a, seulement le nombre de paramètres dont vous vous souciez.
NOTE2: les _argc, _pargv sont dépendants du système, pour trouver vos valeurs vous devez les trouver en exécutant ce programme:
/* findargs.c */
#include <stdio.h>
int main(int argc, char **argv)
{
printf("address of argc is %u.\n", &argc);
printf("address of argv is %u.\n", &argv);
return 0;
}
ces valeurs doivent rester correctes pour votre système spécifique.