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 :

headers include et .c


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Février 2009
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 44
    Par défaut headers include et .c
    Hello,

    Je souhaiterais developper (plutot découper) mon programme de la manière suivante :

    programme.c
    h_headers1.h
    h_headers1.c

    Le programme.c étant le code contenant le main() et compilé (gcc programme.c ...) et dans les h_* mettre toutes mes fonctions. Je souhaiterais enfaite que dans le .h il y ait les signatures des fonctions ainsi que le blabla qui va bien (commentaires!) et que dans le .c associé il y ait le code proprement dit de la fonction.

    Deux questions :
    1. Comment faire ? (Je pense à une manière autre que programme.c include h_headers.h qui lui-même include h_headers.c) - Je me disais qu'étant donné qu'ils ont les mêmes nom ça pourrait être implicite à la compilation ?
    2. Y-a-t-il un interet ?


    Merci,

  2. #2
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par n0mad Voir le message
    Deux questions :
    1. Comment faire ? (Je pense à une manière autre que programme.c include h_headers.h qui lui-même include h_headers.c) - Je me disais qu'étant donné qu'ils ont les mêmes nom ça pourrait être implicite à la compilation ?
    Euh.. Je crois que tu n'as pas compris la notion sous-jacente.

    Le .h contiendra bien la déclaration des fonctions, mais c'est la seule chose qu'on incluera dans programme.C (pour qu'à la compilation il y ait vérification des paramètres et que le compilateur sache que les fonctions sont définies extérieurement.

    Le ...headers.c sera compilé séparément, et lié (phase de link/édition de liens du compilateur) à programme.c, où les références seront résolues..

    Citation Envoyé par n0mad Voir le message
    2. Y-a-t-il un interet ?
    Plusieurs :

    • modularité
    • maintenance
    • fabrication de bibliothèques
    • éventuellement code binaire plus petit (si bibliothèque dynamique)

  3. #3
    Membre averti
    Inscrit en
    Février 2009
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 44
    Par défaut
    Euh.. Je crois que tu n'as pas compris la notion sous-jacente.
    Ca se discutte, je pencherais plutot pour le fait que je ne sache pas l'implémenter :o)

    Bref, j'ai les trois bout de code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    // test.c
    #include <stdio.h>
    #include "h_header.h"
    int main(void)
    {
    	printf("bonjour !\n");
    	ma_fonction(5);
    	return 1;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    // h_header.h
    /* Ma Super Fonction */
    void ma_fonction(int);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    // h_header.c
    void ma_fonction(int a)
    {
    	printf("a x a = %d\n", a*a);
    }
    Et je compile comme suit :
    ~$ gcc -o test test.c

    et j'obtiens :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    /tmp/ccaWyFH8.o: In function `main':
    test.c:(.text+0x27): undefined reference to `ma_fonction'
    collect2: ld returned 1 exit status
    Donc je dois bien oublier un truc....

  4. #4
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par n0mad Voir le message
    Donc je dois bien oublier un truc....
    Comme je te l'ai dit au dessus, tu oublies de compiler h_header.c, et de lier test.c (après compilation) à h_header.o (après compil)

  5. #5
    Membre averti
    Inscrit en
    Février 2009
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 44
    Par défaut
    euh oui j'avais compris mais je demandais comment on fait concrètement ! J'ai du mal m'exprimer.

    J'ai trouvé l'option qui me manquait "-c"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ~$ gcc -c h_header.c 
    ~$ gcc -c test.c    
    ~$ gcc h_header.o test.o  -o test
    Merci =)

  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 n0mad Voir le message
    Hello,

    Je souhaiterais developper (plutot découper) mon programme de la manière suivante :

    programme.c
    h_headers1.h
    h_headers1.c
    C'est techniquement possible, mais le choix des noms a son importance. En effet, la séparation entre interface (header) et implémentation (source C) est déjà faite par l'extension (.h / .c). Elle ne doit donc pas apparaitre dans le nom (il est est en effet absurde de nommer un .c, 'headers_1.c' ...)

    Il faut au contraire réfléchir à la manière dont on découpe le code. Le but étant de créer une 'unité fonctionnelle' (ou bloc fonctionnel) qui rassemble les fonctions d'une même 'famille'. Cette famille peut être fonctionnelle (entrées sécurisées, affichage spécialisé etc.) ou formée autour d'un objet (structure de donnée et ensemble de fonctions permettant de la manipuler).

    Tout cela n'es en aucun cas du au hasard, mais découle du processus de gestion du projet, et notamment des phases 1 (définition) et surtout 2 (conception) qui sont justement là pour organiser le développement en unités de travail homogènes (les blocs fonctionnels) le plus souvent matérialisés par un couple .h / .c. Par exemple, le bloc fonctionnel xxx est composé de xxx.h et xxx.c. (au minimum).

    Le programme.c étant le code contenant le main() et compilé (gcc programme.c ...) et dans les h_* mettre toutes mes fonctions. Je souhaiterais enfaite que dans le .h il y ait les signatures des fonctions ainsi que le blabla qui va bien (commentaires!) et que dans le .c associé il y ait le code proprement dit de la fonction.

    Deux questions :
    1. Comment faire ? (Je pense à une manière autre que programme.c include h_headers.h qui lui-même include h_headers.c) - Je me disais qu'étant donné qu'ils ont les mêmes nom ça pourrait être implicite à la compilation ?
    2. Y-a-t-il un interet ?
    J'explique ici la démarche sous Code::Blocks :

    http://video.google.fr/videoplay?doc...17817010204120

  7. #7
    Membre averti
    Inscrit en
    Février 2009
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 44
    Par défaut
    Hello,

    Merci pour vos réponses... mais ya encore une coui**e dans le potage..

    Bref voila mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    // session.h
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
     
    #ifndef _H_SESSION_H
    #define _H_SESSION_H 
     
    char *LOG      = NULL;
    char *SESSION  = NULL;
     
    void start_session(char *, int);
    #endif
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    // session.c
    #include "session.h"
     
    void start_session(char *name, int flag)
    {
            printf("bonjour\n");
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    // main - test.c
    #include <stdio.h>
    #include "session.h"
     
    int main(void)
    {
    	start_session("toto",1);
    	return 1;
    }

    La compilation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ~$ gcc -Wall -c session.c
    ~$ gcc -Wall -c test.c
    ~$ gcc -Wall session.o test.o -o test
    session.o et test.o sont produit correctement, mais à l'assemblage finale ça coince avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    test.o:(.bss+0x0): multiple definition of `LOG'
    session.o:(.bss+0x0): first defined here
    test.o:(.bss+0x4): multiple definition of `SESSION'
    session.o:(.bss+0x4): first defined here
    collect2: ld returned 1 exit status
    Help (je dirais que ça viens du session.h qui est ajouté dans le test.c et dans le session.c ...mais du fais de mon #ifndef / #define je ne comprends pas !)

    Merci de votre aide (moi ye né pas être développeur!)

    :-)

  8. #8
    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
    La compilation des deux .c est faite séparément. Le .h est donc inclus dans les deux .c au moment de leur compilation.
    Alors, il trouve deux globales définies deux fois: LOG et SESSION.

    Ton erreur est de définir des globales dans un .h.
    Un .h ne doit contenir que des définitions de types ou des prototypes ou des #define ... Jamais de définitions de variables.
    Définis tes globales dans un .c (si vraiment tu en as besoin) et dans le .h déclares les en extern :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    //.h
    extern char *LOG ;
    //.c
    char * LOG = NULL;

  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 diogene Voir le message
    Ton erreur est de définir des globales dans un .h.
    Mais la véritable erreur est d'utiliser des globales totalement injustifiées ici ...

  10. #10
    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
    ...mais euh...le globals.c je l'inclu quand et ou ? :-)
    Nulle part, un .c n'a pas vocation à être inclus. Tu n'es pas forcé de créer un .c supplémentaire pour définir tes deux variables globales (si vraiment tu en as besoin)

  11. #11
    Membre averti
    Inscrit en
    Février 2009
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 44
    Par défaut
    Ouki ... donc je créer "globals.c" comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    // globals.c
    char *LOG        = NULL;
    char *SESSION = NULL;
    et puis donc dans mon session.h je fais la même chose en ajoutant le mot extern devant les définitions.

    ...mais euh...le globals.c je l'inclu quand et ou ? :-)

    Citation Envoyé par Emmanuel Delahaye Voir le message
    Mais la véritable erreur est d'utiliser des globales totalement injustifiées ici ...
    Mwais euh ce genre de réflexion c'est pas franchement utile car quand je pose une question je réduis le code pour ne montrer que l'essentiel....donc bon....

Discussions similaires

  1. Header & Include
    Par Ronan_ dans le forum C++
    Réponses: 6
    Dernier message: 24/03/2014, 11h41
  2. [Cookies] headers include
    Par Oprichnik dans le forum Langage
    Réponses: 6
    Dernier message: 22/09/2007, 15h42
  3. Réponses: 2
    Dernier message: 07/03/2006, 01h53
  4. [VC++] Problème include de header
    Par Yellowmat dans le forum MFC
    Réponses: 10
    Dernier message: 08/12/2005, 13h50
  5. [compil] #include <header> ou #include <head
    Par guejo dans le forum MFC
    Réponses: 5
    Dernier message: 02/06/2004, 15h31

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