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 :

structures de données en paramètres, définitions et déclarations


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Par défaut structures de données en paramètres, définitions et déclarations
    Bonjour. J'ai un problème lorsque je veux écrire un programme en C ayant un algorithme apparenté au jeu de la vie. J'aimerai avoir des précisions sur quelques difficultés syntaxiques :

    *Dans le programme, j'écris les prototypes de fonction à l'intérieur et au début du main, si bien que j'ai quelque chose qui ressemble à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int main(void)
         {
         int fonction1(int,double);
         double fonction2(int,double);
         ....
    Est ce bien correct ?

    *J'écris les définitions de fonction après le main, si bien que j'ai quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    int main(void)
         {
         int carre(int,int);
         ...     
         return 0;
         }
     
    int carre(int a, int b)
         {
         return a*b;
         }
    Est ce bien correct ?

    *Enfin, et je crois que c'est mon plus gros problème, j'ai du mal dans la manipulation des structures (passage par valeur, déclaration de nouvelles variable de type structure, ...)

    La déclaration d'un nouveau type de structure par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct ma_structure
         {
         int champ1;
         double champ2;
         ...
         };
    1) est-elle correcte ?
    2) Cela se fait-il dans le main (début) ou à l'extérieur du main (début ou fin ?), en particulier dans le cas de fonctions définies à l'extérieur du main manipulant des objets de type ma_structure ?

    Pour terminer, j'aimerai savoir comment utiliser le nouveau type créé. Doit on écrire dans le cas de la création d'un nouvel objet de type ma_structure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    struct ma_structure objet1;
    ou bien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ma_structure objet1;
    ?

    De même, lorsque ce type est manipulé par des fonctions, comment doit on écrire prototype et définition :

    prototype ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    struct ma_structure une_fonction(struct ma_structure);
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ma_structure une_fonction(ma_structure);
    définition?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    struct ma_structure une_fonction(struc ma_structure objet1)
         {
         ...
         }
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    ma_structure une_fonction(ma_structure objet1)
         {
         ...
         }
    Merci beaucoup de bien vouloir éclairer ma lanterne.

  2. #2
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    *Dans le programme, j'écris les prototypes de fonction à l'intérieur et au début du main, si bien que j'ai quelque chose qui ressemble à ça :
    C'est possible, mais pas courant puisque le prototype ne sera connu qu'après sa déclaration donc tardivement à moins de placer le main en premier. On préfère placer les prototypes en tête du fichier pour pouvoir utiliser les fonctions "à tout moment"
    J'écris les définitions de fonction après le main, si bien que j'ai quelque chose du genre :
    C'est possible avant ou après. Mais si les prototypes sont dans le main et les fonctions avant le main, les prototypes ne servent plus à rien. Avec les prototypes en tête de fichier, l'ordre des fonctions (y compris main) est indifférent.
    La déclaration d'un nouveau type de structure par
    struct ma_structure
    {
    int champ1;
    double champ2;
    ...
    };
    1) est-elle correcte ?
    Oui
    2) Cela se fait-il dans le main (début) ou à l'extérieur du main (début ou fin ?), en particulier dans le cas de fonctions définies à l'extérieur du main manipulant des objets de type ma_structure
    En tête du fichier avant les prototypes si ils utilisent ce type. De toute façon, en dehors du main (sinon elle ne sera pas connue à l'extérieur de main)
    Pour terminer, j'aimerai savoir comment utiliser le nouveau type créé. Doit on écrire dans le cas de la création d'un nouvel objet de type ma_structure
    struct ma_structure objet1;
    Oui
    De même, lorsque ce type est manipulé par des fonctions, comment doit on écrire prototype et définition :
    prototype ?
    struct ma_structure une_fonction(struct ma_structure);
    Oui
    Pour se "dispenser" du mot struct, définir un nouveau type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    typedef struct 
         {
         int champ1;
         double champ2;
         ...
         }ma_structure;

  3. #3
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Salut,

    La réponse à beaucoup de tes questions se trouvent dans n'importe bouquin de C. Voici quelques éléments de réponse:
    Citation Envoyé par kromartien
    *Dans le programme, j'écris les prototypes de fonction à l'intérieur et au début du main, si bien que j'ai quelque chose qui ressemble à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int main(void)
         {
         int fonction1(int,double);
         double fonction2(int,double);
         ....
    Est ce bien correct ?
    Oui, même si moi je préfère les déclarer en dehors de main. En les déclarant dans le corps de main, tu limites leur utilisation à main.
    Citation Envoyé par kromartien
    *J'écris les définitions de fonction après le main, si bien que j'ai quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    int main(void)
         {
         int carre(int,int);
         ...     
         return 0;
         }
     
    int carre(int a, int b)
         {
         return a*b;
         }
    Est ce bien correct ?
    Exact! Une fonction ne peut être définie dans le corps d'une autre fonction. C'est le bon endroit pour définir carre. Tu peux également, suivant une approche plus modulaire, définir carre dans un autre fichier sources et lier les fichiers objet à l'édition des liens.
    Citation Envoyé par kromartien
    *Enfin, et je crois que c'est mon plus gros problème, j'ai du mal dans la manipulation des structures (passage par valeur, déclaration de nouvelles variable de type structure, ...)

    La déclaration d'un nouveau type de structure par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct ma_structure
         {
         int champ1;
         double champ2;
         ...
         };
    1) est-elle correcte ?
    2) Cela se fait-il dans le main (début) ou à l'extérieur du main (début ou fin ?), en particulier dans le cas de fonctions définies à l'extérieur du main manipulant des objets de type ma_structure ?
    1) C'est correct!
    2) Je le fait en général avant main. Tu trouveras plus d'infos sur la manière d'organiser tes développement à cette adresse: http://emmanuel-delahaye.developpez....ganiser_source

    Citation Envoyé par kromartien
    Pour terminer, j'aimerai savoir comment utiliser le nouveau type créé. Doit on écrire dans le cas de la création d'un nouvel objet de type ma_structure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    struct ma_structure objet1;
    ou bien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ma_structure objet1;
    ?
    C'est la première version que tu dois utiliser, ou alors créer un alias de type avec la syntaxe suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    typedef struct ma_structure ma_structure;
     
    /*...*/
    ma_structure objet1;
    Citation Envoyé par kromartien
    De même, lorsque ce type est manipulé par des fonctions, comment doit on écrire prototype et définition :

    prototype ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    struct ma_structure une_fonction(struct ma_structure);
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ma_structure une_fonction(ma_structure);
    Ni l'un ni l'autre! En général, on ne passe pas de structure par valeur à une fonction (idem pour la valeur de retour). On préfère passer un pointeur sur la structure en question en argument de la fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void une_fonction(struct ma_structure *);
    Citation Envoyé par kromartien
    définition?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    struct ma_structure une_fonction(struc ma_structure objet1)
         {
         ...
         }
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    ma_structure une_fonction(ma_structure objet1)
         {
         ...
         }
    En ce qui concerne la définition, on fait:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void une_fonction(struct ma_structure *p_objet)
    {
        p_objet->champ1 = 10;
    }
    On peut également retourner l'adresse d'une structure allouée dynamiquement à l'intérieur de la fonction:
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #include <stdio.h>
    #include <stdlib.h>
     
    struct ma_structure * une_fonction(void)
    {
        struct ma_structure *p_temp;
        p_temp = malloc(sizeof *p_temp);
        if (p_temp != NULL)
        {
            /*...*/
        }
        return p_temp; /* Si p_temp vaut NULL, l'allocation a échoué*/
    }
     
    int main(void)
    {
        struct ma_structure *p_obj = une_fonction(void)
        if (p_obj == NULL)
        {
            fprintf(stderr, "L'allocation dans une fonction a échoué");
            exit(EXIT_FAILURE);
        }
        /*...*/
        free(p_obj), p_obj = NULL;
        return EXIT_SUCCESS;
    }
    Bonne chance

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  4. #4
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    mujigka A propos des prototypes :
    En les déclarant dans le corps de main, tu limites leur utilisation à main.
    Je ne crois pas que leur visibilité soient limitée à la fonction (comme dans le cas de la définition d'un nouveau type) mais au fichier

  5. #5
    Membre émérite Avatar de crocodilex
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    697
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 697
    Par défaut
    Citation Envoyé par diogene
    mujigka A propos des prototypes : Je ne crois pas que leur visibilité soient limitée à la fonction (comme dans le cas de la définition d'un nouveau type) mais au fichier
    Hmmm, pas si sûr...
    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
    16
    17
    18
    19
    20
    21
    #include <stdio.h>
     
    int main(void)
    {
        void afficheHello(void);
        void afficheBonjour(void);
        afficheHello();
        afficheBonjour();
        return 0;
    }
     
    void afficheHello(void)
    {
        printf("Hello\n");
        afficheBonjour();
    }
     
    void afficheBonjour(void)
    {
        printf("Bonjour\n");
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Project   : Console application
    Compiler  : GNU GCC Compiler (called directly)
    Directory : E:\Tmp\
    --------------------------------------------------------------------------------
    Switching to target: default
    Compiling: main.c
    main.c: In function `afficheHello':
    main.c:15: warning: implicit declaration of function `afficheBonjour'
    Linking console executable: E:\Tmp\zzzz.exe
    Process terminated with status 0 (0 minutes, 0 seconds)
    0 errors, 1 warnings

  6. #6
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par diogene
    mujigka A propos des prototypes : Je ne crois pas que leur visibilité soient limitée à la fonction (comme dans le cas de la définition d'un nouveau type) mais au fichier
    Si c'est dans la fonction, si, d'où l'absurdité de la chose.

    de toutes façon, si on définit avant d'utiliser comme le recommande le Bon Sens, il n'y a pas à s'embêter avec les prototypes séparés, sauf pour les cas de récursion mutuels, qui n'est pas inutile de repérer clairement, sachant les troubles que ça peut entrainer...

  7. #7
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par diogene
    mujigka A propos des prototypes :
    Je ne crois pas que leur visibilité soient limitée à la fonction (comme dans le cas de la définition d'un nouveau type) mais au fichier
    Je crois que tu te trompes (non vérifié), mais je ne déclare jamais mes fonctions de cette manière. La notion de portée existe aussi pour les déclarations de fonctions.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  8. #8
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Par défaut
    Oui auparavant j'écrivais toujours les prototypes de fonction au début du main, ce qui empêche d'utiliser les fonctions définies dans le corps d'autre fonctions. Maintenant je vais écrire tous les prototypes à l'extérieur du main pour pouvoir à tout endroit du fichier accéder aux fonctions. Mais encore mieux, plutôt que d'être dans le cas "prototypes avant le main, définitions après", on peut écrire les définitions avant le main et se passer de tout prototype si j'ai bien compris.
    C'est possible avant ou après. Mais si les prototypes sont dans le main et les fonctions avant le main, les prototypes ne servent plus à rien. Avec les prototypes en tête de fichier, l'ordre des fonctions (y compris main) est indifférent.
    Merci.
    Petite question dans le cas d'une fonction récursive : ai je le droit d'écrire au début de mon fichier
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    long factorielle(long a)
             {
             if(a==0)
                    {
                    return 1;
                    }
             return(a*factorielle(a-1)
             }
    sans utiliser de prototype ? Je pense que oui.

    En fait oui ça marche très bien. Merci beaucoup. Vous me parliez d'un livre que je ferai bien d'acheter. Le livre ANSI-C de Ritchie est il assez complet ? Que me conseillez vous ? Je compile sous Linux avec GCC, j'en voudrai un qui colle bien avec ça.

  9. #9
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par kromartien
    *Dans le programme, j'écris les prototypes de fonction à l'intérieur et au début du main, si bien que j'ai quelque chose qui ressemble à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int main(void)
         {
         int fonction1(int,double);
         double fonction2(int,double);
         ....
    Est ce bien correct ?
    Non.

    Si les fonctions sont définies dans le même fichier source, place les avant leur utilisation, selon le principe de bon sens "définir avant d'utiliser"

    Si elle sont définies dans un autre fichier source (compilation séparée) place le prototypes séparés dans un .h que tu inclues dans le source contenant la définition des fonctions (pour la cohérence) et dans chacun des sources qui utilise ces fonctions.

    http://emmanuel-delahaye.developpez....ganiser_source
    http://emmanuel-delahaye.developpez.....htm#organiser

    *J'écris les définitions de fonction après le main, si bien que j'ai quelque chose du genre :
    Est ce bien correct ?
    Non, voir ci-dessus.

    *Enfin, et je crois que c'est mon plus gros problème, j'ai du mal dans la manipulation des structures (passage par valeur, déclaration de nouvelles variable de type structure, ...)

    La déclaration d'un nouveau type de structure par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct ma_structure
         {
         int champ1;
         double champ2;
         ...
         };
    1) est-elle correcte ?
    2) Cela se fait-il dans le main (début) ou à l'extérieur du main (début ou fin ?), en particulier dans le cas de fonctions définies à l'extérieur du main manipulant des objets de type ma_structure ?
    "définir avant d'utiliser". C'est le principe de base. Quand on ne peut pas, on fait des déclarations séparées.

    Au fait, il ne s'agit pas d'une création de type (rien de tel en C), mais d'une définition de structure.
    Pour terminer, j'aimerai savoir comment utiliser le nouveau type créé. Doit on écrire dans le cas de la création d'un nouvel objet de type ma_structure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    struct ma_structure objet1;
    ou bien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ma_structure objet1;
    ?
    #1
    De même, lorsque ce type est manipulé par des fonctions, comment doit on écrire prototype et définition :

    prototype ?
    définition ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    struct ma_structure une_fonction(struct ma_structure);
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ma_structure une_fonction(ma_structure);
    Pareil. De plus, je recommande l'usage des pointeurs pour éviter les copies. Pour les cas de lecture seul, l'usage du qualificateur 'const' permet de protéger les données initiales.

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

Discussions similaires

  1. Comment créer une structure de donnée dynamiquement ?
    Par Beaunico dans le forum Langage
    Réponses: 9
    Dernier message: 24/01/2006, 09h34
  2. Aide pour diagramme de structure des données
    Par DeezerD dans le forum Décisions SGBD
    Réponses: 4
    Dernier message: 04/12/2004, 19h10
  3. Méta-Programmation - [ structures de données ]
    Par Dam)rpgheaven dans le forum C++
    Réponses: 3
    Dernier message: 03/12/2004, 19h38
  4. Structure des données en retour d'un DBExtract ?
    Par mikouts dans le forum XMLRAD
    Réponses: 4
    Dernier message: 24/01/2003, 15h15
  5. Structure de données de type "RECORD"
    Par chaours dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 30/09/2002, 17h10

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