salut a tous pourquoi on commence toujour avec ce si
static void main( args[]
pourais quelqun mexpliqer ça en detail svp et merci d'avance
Version imprimable
salut a tous pourquoi on commence toujour avec ce si
static void main( args[]
pourais quelqun mexpliqer ça en detail svp et merci d'avance
Il faut bien que quand tu executes un programme, le système sache par où commencer. Il lui faut donc un point d'entrée identifiable et c'est la fonction main. C'est la 1ere fonction de ton programme qui sera executée.
A noter que si tu programmes sous windows, ça peut aussi bien etre winmain ou autre, mais il y a toujours une fonction de ce genre quelque soit le language.
C'est très etrange.
On m'a appris que le programme commence toujours par la fonction main. Cela est vrai. Mais on m'a aussi appris que main retourne l'etat final de l'execution.
Par consequent, main ne renvoid pas un void mais un int.
Normalement, un programme a toujours une fonction de la forme
Apres, je ne sais pas tout et il est possible qu'il existe d'autre forme. Notamment en C++, il existe :Code:
1
2 int main( int argc, char** argv )
Mais ce sont les deux seul forme que je connaisseCode:
1
2 int main()
En fait il y a des langages où la fonction main ne renvoie rien, c'est à dire "void", tel que le langage Java.
Pourquoi en Java ça renvoie void et en C++ ça renvoie int ?
Je laisse un Java-man te répondre pour le Java, mais pour le C++, la fonction main renvoie une valeur de type entier : 0 si tout va bien, toute autre valeur si pépin il y a eu.
Sinon pour l'OP, comme on te l'a dit, la fonction main est le point de départ de tout programme, c'est la première fonction qui sera exécutée.
argc/argv permet de récupérer les arguments. Si on sait qu'on n'aura pas à les récupérer alors autant écrire main sans arguments.
Sinon en effet la norme précise bien que main doit être de type int et non void. (même si certains compilo laisse passez ça.)
Java est un langage full-object : on ne manipule pas des applications au sens C++ mais des classes "exécutables" par la machine virtuelle.Citation:
Pourquoi en Java ça renvoie void et en C++ ça renvoie int ?
C'est à cette dernière qu'incombe la tâche d'interfaçage avec le système, et notamment l'envoi des codes d'erreur.
Une classe exécutable peut utiliser la méthode "System.exit(code)" pour indiquer à la JVM de renvoyer un code donné.
C# quant à lui accepte les deux versions du "Main" :
et :Code:static int Main(...)
Code:static void Main(...)
alors main joue le role de begin en pascal
et ma question a quoi ça sert main et void es c'est obligatoire
Effectivement, on pourrait tout a fait assimiler main a la fonction entre BEGIN et END. ( et non BEGIN - END; qui definie juste une fonction )
A quoi main sert-il ??
Tout simplement a definir le point de depart. Imagine que tu ai 115 fonction, comment sais-tu laquelle doit etre executer en premier ? C'est la fonction main et aucune autre.
Void est-il obligatoire ?
Non, il est meme fortement deconseiller dans la mesure ou on souhaite, en C++, savoir le resultat final de notre programme. main retourne donc un int, et ce retour a une convention : 0 veut dire "tout c'est bien passer, il n'y a pas eu de probleme", tout les autre chiffre veulent dire le contraire.
C'est pas fortement déconseillé c'est interdit. Et tout bon compilo bien réglé te sortira une erreur voir à la limite un warning.
(j'ai pas la norme sous les yeux mais la faq de clc++ fera foi) :
http://www.parashift.com/c++-faq-lit....html#faq-29.3
merci bcp pour les repenses alors void est indesiré en c++ je sais que je suis sortie du forum mais (void) est obligatoire en java contrairement au c++ ?
merci :lol:
Attention entendons nous bien, je dis que void n'est pas standard pour la fonction main hein! Pour les autres ça n'a rien a voir.
Je rejoins exactement le même commentaire que Goten.
Depuis le début, nous ne parlons exclusivement que de la fonction Main.
De plus, nous parlons de la syntaxe de Main dans le langage C++ ( et non Java, Pascal .... ).
En C++, la fonction main est la fonction de depart.
Cette fonction renvoit obligatoirement l'etat final sous forme de int.
Les deux seul syntaxe exacte que je connaisse sont :
Tout autre forme de main est, a ma connaissance, fausse et érroné.Code:
1
2
3 int main( int argc, char** argv ) int main()
Désolé si j'ai l'air de rabacher, mais au vu des question ambigue, il faut vraiment mettre les points sur les i.
Pas exactement. Toutes les formes de main doivent retourner int. Les deux formes que tu as citées sont obligatoire (sauf pour une implémentation freestanding, mais là c'est du chipotage à l'intérieur du chipotage que constitue déjà mon intervention). Mais il est autorisé pour une implémentation de définir d'autres formes (on peut imaginer une forme avec wchar_t pour argv, par exemple, ou une forme avec un argument supplémentaire pour transmettre des variables d'environnement).
Personne pour dire que la première fonction exécutée n'est pas main mais _start qui appelle main :mouarf: ? Et que bien sur avec je sais plus quelle option de gcc on peut changer ça.
Non, personne, car ce comportement n'a rien de standard, ni de portable :)
Et même si c'était standard ça serait complètement inutile dans le cas qui nous occupe, nous sommes d'accord :ccool:
De l'importance du int main(void) :
:mouarf:Citation:
Envoyé par interview de Jess Heinig, programmeur sur Fallout 1
@JolyLoic, @Mérovingien: D'ailleurs, c'est faux sous Windows, où la première fonction d'un exécutable C/C++ à être appelée est mainCRTStartup() (pour un programme console) ou WinMainCRTStartup() (pour un programme fenêtré). Et encore, le "point d'entrée" d'un exécutable peut en fait être n'importe quelle fonction int(void): Il s'agit juste des réglages par défaut de l'édition de liens.
...Et ce fameux point d'entrée est appelé par la fonction BaseProcessStart() de kernel32.dll; c'est la première fonction user-mode du programme.
@Médinoc : oui, c'est ce que disait JolyLoic, ce n'est pas standard, et on peut le changer :D. Le principal étant que tout le monde est bien compris que pour être standard, il faut utiliser une des deux formes :
Par contre, y'a t'il une différence entre :Code:
1
2 int main( int argc, char** argv ) int main(void)
etCode:int main( int argc, char** argv)
Parce que parfois je vois l'un, parfois je vois l'autre. Quelqu'un sait ce que la norme stipule ou bien celà n'a t'il pas d'importance ?Code:int main( int argc, char* argv[])
C'est la même chose. Un tableau n'est jamais copié par une fonction. Pour passer un tableau à une fonction, il faut passer une adresse. C'est imposé par le langage.Code:
1
2
3 f(TYPE * t) f(TYPE t[]) f(TYPE t[N])
C'est plutôt faux. Par défaut, tu vas passer un pointeur sur le premier élément tu tableau. Pointeur qui va être passé par copie. Si tu veux agrandir le tableau dans la fonction tel qu'elles sont définies, tu vas avoir des fuites de mémoire.Citation:
Un tableau n'est jamais copié par une fonction
J'ai dit un tableau n'est jamais copié par une fonction. Pas un pointeur vers un élément d'un tableau n'est jamais copié par une fonction. Pour ajouter de la précision, le nom d'un tableau lorsqu'il n'est pas utilisé seul en argument de sizeof est toujours converti par le compilateur en l'adresse de son premier élément (c'est dans les textes des normes du C et du C++, et aussi dans la FAQ C), donc impossible qu'un tableau sera passé par valeur (par valeur = par copie) à une fonction.
Ce n'est pas le nom d'un tableau qui est important, c'est le fait que ce soit une valeur de type tableau. Que le tableau soit nomme ou non (dans le cas des tableaux multidimentionnels et des pointeurs vers tableau, il n'y a pas de nom pour ces objets, pourtant la conversion a lieu).
En C, il y a deux contextes ou la conversion n'a pas lieu: argument de sizeof et argument de &.
En C++, il y a en plus le passage d'arguments quand la fonction est capable de prendre une reference vers le tableau (que la fonction soit template ou pas). Les regles de gestion des ambiguites pour raison de surcharges et de deduction des arguments templates sont complexes et avec des effets parfois surprenants.
En prime, si un objet est passe par valeur et qu'il a un membre tableau, celui-ci est naturellement copie.
C'est vrai. Même dans un forum C++, j'ai toujours la tête "C" :D.Citation:
Envoyé par JolyLoic
En effet, je l'ai oubliée mais elle est bien présente dans la FAQ.Citation:
En C, il y a deux contextes ou la conversion n'a pas lieu: argument de sizeof et argument de &
Waw, il y a de la rigueur dans l'air ... et aussi de quoi mettre à jour la FAQ ;).Citation:
Ce n'est pas le nom d'un tableau qui est important, c'est le fait que ce soit une valeur de type tableau (...) (dans le cas des tableaux multidimentionnels et des pointeurs vers tableau, il n'y a pas de nom pour ces objets, pourtant la conversion a lieu).
A propos du titre de ce fil : main() n'est pas une 'méthode' mais une fonction, à ce qu'il me semble...
(Du reste, par parenthèses, j'ai l'impression qu'en C++ le terme 'méthode', employé pour désigner une fonction définie dans une classe (donc pas main()), tombe en désuétude : dans les bouquins de Stroustrup, Meyers etc. ce terme est inexistant ou très rare, du moins d'après mes souvenirs...)
Pendant qu'on y est avec les réponses expertes sur les formes autorisées du main... quelqu'un pourrait m'expliquer pourquoi on ne peut pas faire :
Parce qu'être encore obligé de manipuler des char* en C++ en 2009, c'est dommage je trouve, non ?Code:int main(int argc, std::string argv[])
Parce que ça n'est pas binairement compatible, peut-être?
Encore qu'avec la surcharge de fonction, on devrait pouvoir faire des chaînes de compilation qui acceptent ça. .Net et Java suivent cette voie, après tout.
Salut,Typiquement, on accorde au terme méthode le fait de représenter une fonction membre ayant un comportement polymorphe (le fait que la fonction soit déclarée "virtual" pour faire simple) alors que pour tout autre type de fonction (libre ou membre et non polymorphe) on utilisera de préférence le terme fonction.
Mais tout cela n'est que du à la sensibilité des gens :D
Je vois plusieurs raisons à cela, mais peut-être fais-je tout à fait fausse route...
En premier lieu, nous pourrions nous appesantir sur le poids de l'héritage issu du C, car il n'y a, à ma connaissance, aucune différence lors du lancement d'une application écrite en C par rapport à une application écrite en C++.
Java et C# travaillant "derrière" une machine virtuelle, il était possible d'envisager le changement, mais, étant donné que nous sommes limités, pour le lancement de l'application, aux différentes bibliothèque du runtime (kernell32 dans le cas de windows), et en attente d'une uniformisation de l'ABI C++, il peut sembler "cohérent" de s'en tenir au dénominateur "le plus grand commun multiple", à savoir... l'interface C:D
La deuxième raison que je soupçonne est de ne pas vouloir ajouter une dépendance là où elle n'est pas forcément nécessaire:
Si l'on suivait le raisonnement jusqu'au bout, nous pourrions presque envisager de faire en sorte que le prototype de la fonction devienne
mais cela impliquerait une dépendance forcée vis à vis de la classe string et de la classe vector, alors... que ce serait peut être le seul endroit (accessible au départ de main, s'entend) où elle pourrait s'avérer nécessaireCode:int main(std::vector<std::string> argv)
Enfin, comme l'a fait valoir Médinoc, peut être n'est ce "simplement" que parce que la classe string n'est pas binairement compatible :question:
Il me semble qu'il était question de lancer une "traque" à toutes les fonctions C++ manipulant encore des chaines de caractères C style afin de les remplacer par leur équivalent manipulant des std:: (w)string, mais, si l'on peut, effectivement envisager de remplacer le constructeur d'un i/o fstream, un remplacement similaire au niveau de main nécessiterait une refonte en profondeur de l'existant sur les différents système.
Et comme il est plus "sensé" de faire en sorte qu'un langage s'adapte (sans trop de mal) aux environnements sur lesquels il est employé que de demander aux différents environnements de s'adapter aux exigences d'un langage (surtout si le langage en question a vocation à rester "aussi près que possible" du matériel)...
Je sais que cela ne tient pas debout sous Windows, puisque le processus ne reçoit qu'une ligne de commande, et c'est lui qui la sépare avant d'appeler main().
Mais d'ailleurs, ça ne triendrait pas debout ailleurs non plus: Après tout, rien n'empêche d'écrire un point d'entrée ainsi:
Code:
1
2
3
4
5
6
7 int main(int argc, char *argv[]) { std::vector<std::string> args; for(int i=0 ; i<argc, i++) //Démarrer à 1 si on saute la commande args.push_back(std::string(argv[i])); return main(args); }
En fait, main, c'est tout un ensemble de directive système compliqué, juste histoire que ton processus s'intègre complétement dans ton OS. C'est principalement ce qui cause le problème de non-portabilité entre OS d'une même architecture (ça + les lib bas niveau).
Aussi en c++, il est facile de faire éxecuté du code un peu dangereux (en le plaçant dans un constructeur d'objet static), qui s'exécutera avant le main.
Sinon, je rejoint la majorité, void main est non-standard est ne devrait pas être utilisé. Libre à toi de respecté se standard.
Quand à la valeur retourner, elle dépend du système, et se trouve dans stdlib.h. Un code portable se verra toujours retourner EXIT_SUCCESS en cas de "réussite".