IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

La fonction Main()


Sujet :

C

  1. #1
    Invité
    Invité(e)
    Par défaut La fonction Main()
    Bonjours, à tous,

    Je vais commencer cette après-midi le language C et je bloque dès le départ sur la fonction Main.

    J'ai la norme ISO/IEC 9899꞉1999 n1256 et ISO IEC 9899꞉201x n1570 sous les yeux qui sont toutes les 2 les tous derniers brouillons des normes définitives du C99 et C11 et elles indiquent ceci:

    5.1.2.2.1 Program startup
    1 The function called at program startup is named main. The implementation declares no
    prototype for this function. It shall be defined with a return type of int and with no
    parameters:
    int main(void) { /* ... */ }
    or with two parameters (referred to here as argc and argv, though any names may be
    used, as they are local to the function in which they are declared):
    int main(int argc, char *argv[]) { /* ... */ }
    or equivalent;9) or in some other implementation-defined manner.
    2 If they are declared, the parameters to the main function shall obey the following
    constraints:
    — The value of argc shall be nonnegative.
    — argv[argc] shall be a null pointer.
    — If the value of argc is greater than zero, the array members argv[0] through
    argv[argc-1] inclusive shall contain pointers to strings, which are given
    implementation-defined values by the host environment prior to program startup. The
    intent is to supply to the program information determined prior to program startup
    from elsewhere in the hosted environment. If the host environment is not capable of
    supplying strings with letters in both uppercase and lowercase, the implementation
    shall ensure that the strings are received in lowercase.
    — If the value of argc is greater than zero, the string pointed to by argv[0]
    represents the program name; argv[0][0] shall be the null character if the
    program name is not available from the host environment. If the value of argc is
    greater than one, the strings pointed to by argv[1] through argv[argc-1]
    represent the program parameters.
    — The parameters argc and argv and the strings pointed to by the argv array shall
    be modifiable by the program, and retain their last-stored values between program
    startup and program termination.
    Or je vois un peu partout y compris dans mon livre intitulé
    Le livre du C : Premier langage (Claude Delannoy) mais aussi ici Le C en 20 heures des fonctions Main qui semble ne pas respecter les normes C99/C11.
    Quelques exemples (raccourci):
    int main() {/*...*/} http://c.developpez.com/tutoriels/20...s/?page=page_2
    void main() {/*...*/} http://www.exercices-corriges.com/20...l#.U29Ri00U9hF
    int main(void) {/*...*/} (La bonne en principe ?)

    Pourquoi ? Comment faut-il déclarer les fonctions Main ?
    Merci d'avance.
    Dernière modification par Domi2 ; 27/12/2015 à 16h42. Motif: Lien non pérenne

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Bonjour,

    Par défaut, une fonction retourne un int si on n'indique aucun type de retour, ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    main(void);
    int main(void);
    Sont équivalente.

    Mais actuellement, on préfère préciser le type de retours pour éviter toute ambiguïté.

    De même, quand on ne précise pas les paramètres d'une fonctions :
    • lors de la déclaration, cela signifie que main est une fonctions mais que ses paramètres ne sont pas connus pour le moment (si je ne me trompe pas)
    • lors de la définition, que main est une fonction ne prenant pas de paramètres.



    Toutefois, je te recommande de toujours préciser void, je trouve cela plus "propre", même si cela peut sembler subjectif.


    main doit retourner un int, ce prototype ne suit pas la norme et est incorrect.
    Par contre, en embarqué, on ne suit pas toujours la norme et il est possible que main ne doive rien retourner, mais l'embarqué est un cas particulier.

  3. #3
    Invité
    Invité(e)
    Par défaut
    D'accord, merci bien.

    Je vais toujours déclarer explicitement en int main(void).

    Je sais qu'à chaque nouvelle question, un nouveau sujet, mais j'ai une autre petite question en passant. Dans la norme, il y a écrit que:
    ...
    — minimum value for an object of type short int
    SHRT_MIN -32767 // −(215 − 1)
    — maximum value for an object of type short int
    SHRT_MAX +32767 // 215 - 1
    — maximum value for an object of type unsigned short int
    USHRT_MAX 65535 // 216 - 1
    — minimum value for an object of type int
    INT_MIN -32767 // -(215 - 1)
    — maximum value for an object of type int
    INT_MAX +32767 // 215 - 1
    ...
    à propos des limites des différents types de données en C (page 27).
    Ça apparait dans C99 et C11. Concernant les limites minimum, il s'agit d'une erreur ou ... ? Pourtant, ça apparait dans les 2 documents.

    La norme stricte nous dit-elle réellement que -32767 est la valeur min d'un Integer ou j'ai mal compris ?
    Visual Studio m'indique bien -32768 et -2147483648 pour respectivement SHRT_MIN et INT_MIN pourtant.

    Merci d'avance,
    A+
    Dernière modification par Invité ; 11/05/2014 à 17h05.

  4. #4
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    J'ai écrit un article sur le prototype de la fonction main() : http://gradot.wordpress.com/2013/12/...-de-main-en-c/

    Par défaut, une fonction retourne un int si on n'indique aucun type de retour, ainsi :
    Code :Sélectionner tout - Visualiser dans une fenêtre à part
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    main(void);
    int main(void);
    Sont équivalente.
    C'est vrai en C89, ce ne l'est plus en C99.

    lors de la définition, que main est une fonction ne prenant pas de paramètres.
    Un test récent m'a montré que tu pouvais en fait lui passer un nombre quelconque de paramètres de n'importe quel type mais tu ne peux pas y accéder dans la fonction.

    main doit retourner un int, ce prototype ne suit pas la norme et est incorrect.
    D'après mes lectures, c'est valable d'un environnement (embarqué par exemple ^^) qui définit main() de cette façon.

    Ça apparait dans C99 et C11. Concernant les limites minimum, il s'agit d'une erreur ou ... ? Pourtant, ça apparait dans les 2 documents.

    La norme stricte nous dit-elle réellement que -32767 est la valeur min d'un Integer ou j'ai mal compris ?
    Visual Studio m'indique bien -32768 et -2147483648 pour respectivement SHRT_MIN et INT_MIN pourtant.
    Ce ne sont pas des erreurs. Un int est codé sur 16 bits minimum, comme un short, donc les valeurs minimales de SHRT_MIN et INT_MIN sont les mêmes. Néanmoins, il est possible de faire des int sur 32 bits et des shorts sur 16. C'est ton cas avec Visual.

  5. #5
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Citation Envoyé par Bktero Voir le message
    C'est vrai en C89, ce ne l'ai plus en C99.
    Mouais, apparemment, on a juste un warning qui s'ajoute en c99 (compilation avec gcc -std=c99/-std=c11 -pedantic).


    Un test récent m'a montré que tu pouvais en fait lui passer un nombre quelconque de paramètres de n'importe quel type mais tu ne peux pas y accéder dans la fonction.
    Mmmmm... c'est marrant ça.
    Je pense qu'on dois pouvoir s'amuser un peu avec cela et des pointeurs de fonctions .

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #include <stdio.h>
     
    int (*foo)(int);
     
    int faa()
    {
            puts("toto");
    }
     
    int main(void)
    {
            foo = faa;
            foo(51);
            return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #include <stdio.h>
     
    int (*foo)();
     
    int faa(int i)
    {
            printf("%d\n", i);
    }
     
    int main(void)
    {
            foo = faa;
            foo(51, 77);
            return 0;
    }
    \o/
    EDIT : dommage que cela ne marche pas en C++

    D'après mes lectures, c'est valable d'un environnement (embarqué par exemple ^^) qui définit main() de cette façon.
    Attention, c'est valable mais contraire à la norme et comme je l'ai dit, l'embarqué est un cas particulier.

  6. #6
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Ce n'est pas contraire à la norme. La norme autorise un prototype de main() à être différent : cela dépend alors de l'implémentation. En gros, la norme définit deux prototypes "classiques" de main() et autorise les implémenteurs à faire autre chose.

    Je pense qu'on dois pouvoir s'amuser un peu avec cela et des pointeurs de fonctions .
    Je pense qu'on doit en effet pouvoir faire un peu tout et n'importe quoi

    Je vais commencer cette après-midi le language C et je bloque dès le départ sur la fonction Main.

    J'ai la norme ISO/IEC 9899꞉1999 n1256 et ISO IEC 9899꞉201x n1570 sous les yeux qui sont toutes les 2 les tous derniers brouillons des normes définitives du C99 et C11 et elles indiquent ceci:
    PS : lire la norme ne me semble vraiment pas être un bon moyen d'apprendre le C ! Il faut s'accrocher, c'est assez imbuvable et faut vraiment y chercher une information particulière pour que la lecture soit instructive.

    J'adore faire des expéditions sur le territoire de la norme

  7. #7
    Invité
    Invité(e)
    Par défaut
    Merci,

    La norme me servira en complément du livre et des articles que j'ai dans mon marque-page Firefox.
    Pour la limite minimum des types, j'ai:
    SHRT_MIN => -32767 au lieu de -32768 habituellement. Je me demandait si c'été une erreur ou non.

  8. #8
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par Nouveau2 Voir le message
    Pour la limite minimum des types, j'ai:
    SHRT_MIN => -32767 au lieu de -32768 habituellement. Je me demandait si c'été une erreur ou non.
    Non ce n'est pas une erreur.

    La raison est que la norme autorise trois façons de coder les nombres négatifs : complément à 2, complément à 1 et signe + valeur. Or le complément à 1 et la représentation signe + valeur ne permettent pas de représenter -32768 sur 16 bits (mais admettent deux façons de représenter 0).
    En pratique la grande majorité des implémentations utilise le complément à 2.

    La norme spécifie la plage minimale qui doit être supportée (on doit pouvoir au moins représente les nombres de -32767 à 32767 avec un int ou un short), une implémentation peut faire mieux (i.e. des plages plus larges et donc avoir des valeurs plus petites pour SHRT_MIN, INT_MIN, etc. et plus grandes pour SHRT_MAX, INT_MAX, etc.).

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par Nouveau2 Voir le message
    int main(void) {/*...*/} (La bonne en principe ?)
    Le void sert juste à insister pour dire au compilateur "IL N'Y A PAS DE PARAMÈTRE TU COMPRENDS"

    C'est un problème résolu depuis [très] longtemps: sans void on pouvait quand même passer des paramètres.


    Citation Envoyé par Neckara Voir le message
    Mmmmm... c'est marrant ça.
    Je pense qu'on dois pouvoir s'amuser un peu avec cela et des pointeurs de fonctions .
    Cela s'appelle une ellipse

    Un peu de documentation: stdarg.h

  10. #10
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Citation Envoyé par foetus Voir le message
    Cela s'appelle une ellipse
    En es-tu vraiment sûr ?

    In C, a comma must precede the ellipsis
    D'ailleurs, si on utilise va_start :
    main.c:13:15: error: ‘va_start’ used in function with fixed args
    va_start(vl,n);

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par Neckara Voir le message
    En es-tu vraiment sûr ?
    L'ellipse c'est bien les 3 points. "Variadic function" pour le terme générique anglais.

    Citation Envoyé par Neckara Voir le message
    D'ailleurs, si on utilise va_start :
    test_1.c:13:5: error: ‘va_start’ used in function with fixed args
    va_start(ap, arg1);
    Ah flûte je n'avais pas eu le temps de tester avant de poster
    J'aurais cru

  12. #12
    Invité
    Invité(e)
    Par défaut Bonjours,
    @ gl,

    Merci, c'est exactement ce que je voulais savoir.

    A+

  13. #13
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Merci de cliquer sur si tel est le cas

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 21
    Dernier message: 20/06/2006, 16h49
  2. fonction main en C++
    Par steph_nied dans le forum C++
    Réponses: 3
    Dernier message: 26/05/2006, 15h03
  3. arguments dans ma fonction main
    Par salseropom dans le forum C
    Réponses: 10
    Dernier message: 15/03/2006, 23h12
  4. la fonction main
    Par harvouj dans le forum Langage
    Réponses: 1
    Dernier message: 13/02/2006, 01h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo