web-dev-qa-db-fra.com

fonction main () en C

J'apprends la programmation C de manière autodidacte depuis quelques semaines, et j'ai quelques questions concernant la fonction main().

  1. Toutes les fonctions doivent être déclarées dans leur prototype de fonction, et plus tard, dans leur définition. Pourquoi ne devons-nous pas d'abord déclarer la fonction main() dans un prototype?

  2. Pourquoi devons-nous utiliser int main() au lieu de void main()?

  3. Que fait exactement retour 0 dans la fonction main()? Que se passerait-il si j'écrivais un programme terminant la fonction main() par return 1;, par exemple?

24
Heikki
  1. Une déclaration d'une fonction est nécessaire uniquement avant qu'une fonction soit utilisée. La définition est elle-même une déclaration, donc aucun prototype préalable n'est requis. (Certains compilateurs et autres outils peuvent avertir si une fonction est définie sans prototype préalable. Ceci est conçu comme une directive utile, pas comme une règle du langage C.)
  2. Parce que la norme C le dit. Les systèmes d'exploitation transmettent la valeur de retour au programme appelant (généralement le Shell). Certains compilateurs acceptent void main, mais il s'agit d'une extension non standard (cela signifie généralement "toujours retourner zéro au système d'exploitation").
  3. Par convention, une valeur de retour non nulle signale qu'une erreur s'est produite. Les scripts shell et autres programmes peuvent l'utiliser pour savoir si votre programme s'est terminé avec succès.
19
Fred Foo

1) Toutes les fonctions doivent être déclarées dans leur prototype de fonction, puis dans leur définition. Pourquoi ne devons-nous pas d'abord déclarer la fonction main () dans un prototype?

Pas vrai. Exemple simple:

void foo(){}  //definition

int main()
{
    foo();
    return 0;
}

Ce n'est que lorsqu'une fonction est appelée mais que la définition n'est pas encore vue qu'une déclaration est requise. Cela n'arrivera jamais à main car c'est le démarrage du programme.


2) Pourquoi devons-nous utiliser int main () au lieu de void main ()?

Parce que la norme le dit. (Pour être plus précis, c'est vrai sur un environnement hébergé, ce qui est généralement le cas)

C99 5.1.2.2.1 Démarrage du programme

La fonction appelée au démarrage du programme est nommée main. L'implémentation ne déclare aucun prototype pour cette fonction. Il doit être défini avec un type de retour de int et sans paramètres:

int main(void) { /* ... */ }

ou avec deux paramètres (appelés ici argc et argv, bien que tous les noms puissent être utilisés, car ils sont locaux à la fonction dans laquelle ils sont déclarés):

int main(int argc, char *argv[]) { /* ... */ }

ou équivalent; ou d'une autre manière définie par l'implémentation.


3) Que fait exactement return 0 dans la fonction main ()? Que se passerait-il si j'écrivais un programme terminant la fonction main () avec return 1, par exemple?

La valeur de retour indique le résultat du programme. Habituellement 0 indique le succès tandis que d'autres valeurs indiquent différents types d'échec.

17
Yu Hao

Vous n'êtes pas libre de choisir le type de retour de main car vous n'avez pas écrit le code qui appelle main. Le code appelant main existait déjà avant même que vous pensiez à l'apprentissage de C. Il a été écrit par les gens qui fournissent le code de démarrage du runtime C , qui est généralement lié automatiquement à votre exécutable sans que vous le sachiez. Ce code réside souvent dans un fichier appelé crt0.o (créé à partir de crt0.c ou même assembleur dans crt0.s). Il s'attend à utiliser une valeur de retour indiquant le succès (0) ou l'échec (différent de zéro), plus éventuellement d'autres informations comme si le code a été interrompu en raison d'un signal et si oui, lequel. Ce sont des morceaux de l'histoire Unix, que je ne répéterai pas ici :-)

2
Jens

1) Pas nécessairement; une définition sert également de déclaration. Deuxièmement, il n'y a de toute façon que quelques signatures valides pour main, et vous n'appelez normalement pas main dans votre code, sauf si vous écrivez une entrée pour l'IOCCC.

2) Réponse courte: parce que la définition du langage le dit. Réponse plus longue: c'est ainsi que votre programme indique la réussite ou l'échec de l'environnement hôte. Une implémentation individuelle est libre de prendre en charge des signatures supplémentaires pour main, mais elle doit documenter ces signatures supplémentaires. Si la documentation de votre compilateur ne répertorie pas void main() comme signature légale, vous ne devez pas l'utiliser.

3) Par convention (au moins sur les systèmes * nix où C a été utilisé pour la première fois), un état de 0 indique le succès, et un état non nul indique ... autre chose que le succès. Quelle valeur correspond exactement à quel statut dépend de la mise en œuvre.

1
John Bode

Mettez simplement l'essentiel pour toutes vos questions est les traditions et la conformité. Les chaînes d'outils, les systèmes d'exploitation, etc. savent de cette façon que cette procédure appelée main (), doit d'abord être appelée depuis l'espace de code utilisateur (programme) ...

Maintenant spécifiquement: 1) En raison de la conformité comme je l'ai dit. Vous n'avez pas besoin de déclarer car les chaînes d'outils et les systèmes d'exploitation connaissent déjà main. Il existe également d'autres fonctions de conformité comme exit ().

2) Lorsque le temps principal revient, le système d'exploitation peut en récupérer le résultat. Habituellement non nul signifie une erreur. Ainsi, lorsque U utilise des scripts ou d'autres programmes appelant votre programme, par exemple main (), vous pouvez vérifier si elle a réussi.

3) Renvoyer autre chose que zéro signifie erreur. Mais en fait, vous pouvez interpréter cette valeur comme vous le souhaitez. Mais comme je l'ai dit, OS peut avoir le résultat.

Informations supplémentaires: main () n'est en fait pas la première fonction (que vous avez écrite) qui sera appelée lorsque vous lancerez le programme. MAIS en fait, les systèmes d'exploitation et les chaînes d'outils facilitent les autres appels avant votre main, pour configurer l'environnement, faire l'initialisation ou autre chose. Mais vous ne le savez pas directement lorsque vous écrivez votre code et vous n'avez pas à y faire face et à y penser du tout. Dans les systèmes embarqués, il y aura généralement des fonctions de très bas niveau appelées pour configurer l'horloge principale du CPU, les interruptions, la pile, etc. Certaines chaînes d'outils comme IAR peuvent en fait vous permettre d'exécuter votre propre code avant l'appel de main.

J'espère que cela a aidé :)

0
arapEST

Les fonctions ne doivent pas nécessairement être déclarées d'abord comme un prototype. Une telle déclaration n'est nécessaire que si nous devons utiliser une fonction avant qu'elle ne soit définie.

main a le type int par définition.

La signification de la valeur renvoyée par main est conventionnelle. La convention généralement acceptée est que 0 est considéré comme un succès, et non 0 une sorte d'échec.

0
zentrunix

Lorsque nous exécutons un programme C, le contrôle des ordinateurs passe aux programmes C main (), à partir de là, le programme C commence à s'exécuter

0
Chawki

1.La fonction main () est implicitement appelée par la bibliothèque C en reconnaissant le mot clé intégré "main". Nous n'avons donc pas besoin de déclarer un prototype pour la fonction principale.

2.Ce que je ne sais pas, mais je pense que cela dépend du type d'éditeur utilisé. Dans Turbo C, void main () sera accepté, alors que dans dev-cpp main () devrait retourner une valeur.

3. retour 0 quitte simplement le programme avec l'état de sortie 0, en d'autres termes, la valeur de retour détermine l'état de sortie du thread principal.

0
Mahalakshmi

1) c'est faux, vous ne pouvez créer que la définition d'une fonction.

2) nous pouvons savoir si la fonction main () se termine correctement

3) la même chose sauf que dans votre Shell ce sera écrit 1 au lieu de 0

0
jambono