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 :

Problème d'inclusion et initialisation


Sujet :

C

  1. #1
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    623
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 623
    Points : 1 554
    Points
    1 554
    Par défaut Problème d'inclusion et initialisation
    Bonjour / bonsoir à tous,

    J'ai un petit problème dont je n'arrive pas à me dépatouiller. Je vous explique.
    J'ai plusieurs fichiers .c qui ont besoin (sans la modifier, c'est pour de l'info) d'une même variable: dayname.
    Je souhaiterais définir celle-ci dans un .h (disons dayname.h) et l'y initialiser, puis inclure ce fichier .h dans les .c:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const char *dayname={"Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"};
    Et mon linker râle (warning seulement) en me disant que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Warning: Public symbol '_dayname' defined in both module A.OBJ and B.OBJ
    pour chaque .c dans lequel j'inclus le .h
    Et j'ai tenté de mettre un extern devant la variable dans le .h, et de faire dans un module #define extern, mais rien n'y fait.

    Quelqu'un aurait-il une petite idée pour résoudre ce problème ?

    D'avance merci,

    Edgar.

    PS: j'ai bien sur pensé à déclarer la variable dans le .h en tant que char dayname[7][9], et de faire un strcpy() des valeurs dans le .c d'initialisation, mais je ne trouve pas ça particulièrement élégant.... mais si c'est la seule solution, il faudra bien y arriver !
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  2. #2
    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
    C'est un tableau, et non pas une seule chaîne de caractères

    Je te propose cela
    dayname.h:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #ifndef DAYNAME_H
    #define DAYNAME_H
     
    extern const char* DAYNAME[7];
     
     
    namespace globals {
        extern const char* dayname[7];
    };
     
    #endif // DAYNAME_H

    dayname.cpp:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    const char* DAYNAME[7] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};
     
     
    namespace globals {
        const char* dayname[7] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};
    }
    ou alors
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #include "dayname.h"
     
    const char* DAYNAME[7] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};
     
    const char* globals::dayname[7] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};

    La taille 7 n'est pas obligatoire

    Ensuite l'utilisation:
    • Faire des #include "dayname.h" dans les fichiers qui en ont besoin
    • Construire le module dayname.o ainsi g++ -c dayname.cpp. Et linker tes sources avec ce module. Par exemple: g++ main.cpp dayname.o -o main.
    • Directement linker tes sources avec le cpp. Par exemple: g++ main.cpp dayname.cpp -o main.

  3. #3
    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
    @foetus : nous sommes sur le forum C, une solution en C aurait été plus adaptée...

    @edgarjacobs : il s'agit ici de bêtement déclarer une variable globale. Comme ferais-tu pour un entier ? Il faut faire la même chose avec un tableau de chaines, à savoir :
    • déclaration externe dans un fichier h
    • déclaration + définition dans un fichier c
    • utilisation dans d'autres fichiers en incluant le fichier h qui déclare (de manière externe) le tableau

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 685
    Points : 30 974
    Points
    30 974
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Tu crées un "dayname.h" contenant
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #ifndef DAYNAME_H
    #define DAYNAME_H
     
    extern const char* dayname[];
    void foo();			// Exemple
    #endif // DAYNAME_H
    Jusque là, foetus avait bon.

    Ensuite, dans ton source principal (celui qui a le main)
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #include <stdio.h>
    #include "dayname.h"
    const char* dayname[]={"Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi", NULL};
     
    int main()
    {
    	foo();
    }

    Et dans les autres sources
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <stdio.h>
    #include "dayname.h"
     
    void foo()
    {
    	int i;
    	const char **pt;
    	for (pt=dayname, i=1; *pt; pt++, i++)
    		printf("jour %d: %s\n", i, *pt);
    }

    L'include de dayname.h dans le main est facultatif mais ça permet de garder une homogénéité dans le code (ça dépend aussi de l'endroit où seront déclarées les fonctions car dans mon premier essai je déclarais foo() dans le main donc c'est selon ton choix). Et le rajout d'un NULL dans le tableau ne va pas te faire perdre beaucoup de place (juste une adresse) mais t'affranchira de devoir te coltiner la valeur "7" à chaque fois que tu devras traiter ton tableau.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    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 Bktero Voir le message
    @foetus : nous sommes sur le forum C, une solution en C aurait été plus adaptée...
    Désolé, j'ai fait cela en C++

    Mais, il ne faut que supprimer le namespace.


    Citation Envoyé par Sve@r Voir le message
    Jusque là, foetus avait bon.
    Effectivement, s'il n'y a pas beaucoup de choses dans le fichier source dayname.c[pp] on peut le fusionner avec le main


    Citation Envoyé par Sve@r Voir le message
    Et le rajout d'un NULL dans le tableau ne va pas te faire perdre beaucoup de place (juste une adresse) mais t'affranchira de devoir te coltiner la valeur "7" à chaque fois que tu devras traiter ton tableau.
    Soit la sentinelle, soit l'énumération avec une valeur terminale "NB_DAYS"

  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
    Si la déclaration externe inclue le fameux 7, on doit pouvoir faire un sizeof pour connaitre le nombre d'éléments.

    J'aime bien le concept du marqueur de fin également, qui sera peut-être plus pratique à l'usage.

  7. #7
    Membre émérite
    Avatar de Daïmanu
    Homme Profil pro
    Développeur touche à tout
    Inscrit en
    Janvier 2011
    Messages
    696
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur touche à tout

    Informations forums :
    Inscription : Janvier 2011
    Messages : 696
    Points : 2 438
    Points
    2 438
    Par défaut
    Une autre solution serait d'emprunter la notion d'encapsulation des langages objets.

    On déclare le tableau static et on y accède à travers une ou plusieurs fonctions :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    //dayname.h
    #ifndef DAYNAME_H
    #define DAYNAME_H
     
    static const char *dayname={"Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"};
     
    const char *get_dayname(unsigned int num) {
    	return dayname[num % 7]; //0 = dimanche
    	//return dayname[(num + 1) % 7]; //0 = lundi
    }
     
    #endif //DAYNAME_H

    Les avantages sont :
    - on évite la lecture hors du tableau (avec un modulo) ;
    - on peut facilement décider quel est le premier jour de la semaine ;
    Je fais appel aux esprits de Ritchie, Kernighan, Stroustrup et Alexandrescu
    Donnez moi la force, donnez moi le courage de coder proprement !

    « Ça marche pas » n'est PAS une réponse convenable, merci de détailler le souci en fournissant l’environnement, le code source, les commandes et les messages d'erreur.

    Ce club possède également un clavardage, on y trouve quelques perles entre deux sessions d'entraides.

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 685
    Points : 30 974
    Points
    30 974
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par manudiclemente Voir le message
    On déclare le tableau static et on y accède à travers une ou plusieurs fonctions :
    Oui mais chaque source qui inclus le ".h" aura son propre dayname local ; identique aux autres daynames certes mais c'est bête (choquant ?) de définir x fois le même contenu. Surtout si (évolution) on se met à vouloir ensuite le modifier dans une fonction f1() pour le traiter dans une autre fonction f2()...

    Sinon perso je préfère la sentinelle au define. Déjà ça évite de devoir se creuser la tête pour trouver un nom de macro (NB_DAYS, NB_DAYNAME, SIZE_DAYNAME, SZ_DAYNAME, DAYNAMELEN, DAYNAME_LEN, etc...). Surtout si on est limite maniaque et que l'on veut absolument que les noms des macros aient tous une certaine homogénéité les uns avec les autres (ça agace quand on développe à plusieurs de voir d'un cote NB_MONTH et de l'autre DAYNAME_LEN)...
    En plus, la macro crée un lien logique entre deux éléments (le tableau et la macro contenant sa taille) et tout relecteur du code (autre que son créateur) devra alors lui-aussi créer ce lien dans son esprit pour comprendre le code (et même s'il met 1/2 seconde pour établir le lien, c'est toujours ça de perdu).
    Alors que la sentinelle est directement intégrée au tableau et je trouve ça plus simple à relire.

    Et pour sizeof je le trouve trop dangereux à utiliser. sizeof(dayname) renverra certes 7 mais char **pt=dayname; sizeof(pt) renverra 4 (voire 2)...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    623
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 623
    Points : 1 554
    Points
    1 554
    Par défaut
    Hello,

    A la lecture des posts de Bktero et Sve@r, je me dis qu'il y a parfois des moments où je dois être aussi buté qu'un âne pour m'être acharné à modifier MA solution pour qu'elle fonctionne.... alors qu'en laissant reposer les choses quelques heures et en reprenant à tête reposée, j'aurais sans doute trouvé la solution (en fait, je l'avais, mais je déclarais dayname dans le main, et non en gobale....)

    Merci à tous pour vos réponses.,

    Edgar.
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  10. #10
    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
    Citation Envoyé par manudiclemente Voir le message
    Une autre solution serait d'emprunter la notion d'encapsulation des langages objets.

    On déclare le tableau static et on y accède à travers une ou plusieurs fonctions :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    //dayname.h
    #ifndef DAYNAME_H
    #define DAYNAME_H
     
    static const char *dayname={"Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"};
     
    const char *get_dayname(unsigned int num) {
    	return dayname[num % 7]; //0 = dimanche
    	//return dayname[(num + 1) % 7]; //0 = lundi
    }
     
    #endif //DAYNAME_H

    Les avantages sont :
    - on évite la lecture hors du tableau (avec un modulo) ;
    - on peut facilement décider quel est le premier jour de la semaine ;
    Tu voulais savoir doute faire ça dans un .c et faire un .h pour donner connaissance de la fonction ?

    Sinon comme dit Sve@r, tu dupliques la variable statique et tu vas surtout te taper des références multiples sur la fonction.

    @Sve@r :
    sizeof(dayname) renverra certes 7
    Plutôt 7 * sizeof(un pointeur).

  11. #11
    Membre émérite
    Avatar de Daïmanu
    Homme Profil pro
    Développeur touche à tout
    Inscrit en
    Janvier 2011
    Messages
    696
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur touche à tout

    Informations forums :
    Inscription : Janvier 2011
    Messages : 696
    Points : 2 438
    Points
    2 438
    Par défaut
    Citation Envoyé par Bktero Voir le message
    Tu voulais savoir doute faire ça dans un .c et faire un .h pour donner connaissance de la fonction ?

    Sinon comme dit Sve@r, tu dupliques la variable statique et tu vas surtout te taper des références multiples sur la fonction.
    En effet, mon C est un peu rouillé

    C'était juste histoire de montrer une autre approche.
    Je fais appel aux esprits de Ritchie, Kernighan, Stroustrup et Alexandrescu
    Donnez moi la force, donnez moi le courage de coder proprement !

    « Ça marche pas » n'est PAS une réponse convenable, merci de détailler le souci en fournissant l’environnement, le code source, les commandes et les messages d'erreur.

    Ce club possède également un clavardage, on y trouve quelques perles entre deux sessions d'entraides.

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

Discussions similaires

  1. [MFC] Problèmes d'inclusion d'une DLL
    Par CaptnB dans le forum MFC
    Réponses: 1
    Dernier message: 12/05/2006, 18h01
  2. Réponses: 2
    Dernier message: 25/04/2006, 17h08
  3. Problème d'inclusions multiples
    Par Le Furet dans le forum C
    Réponses: 2
    Dernier message: 03/10/2005, 23h59
  4. Problème d'inclusion de pages.
    Par julien85 dans le forum XML/XSL et SOAP
    Réponses: 6
    Dernier message: 01/05/2005, 18h06
  5. Problème d'inclusion
    Par degreste dans le forum MFC
    Réponses: 5
    Dernier message: 27/01/2004, 00h56

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