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 :

init variable dans le .h


Sujet :

C

  1. #1
    Membre confirmé
    Homme Profil pro
    Auditeur informatique
    Inscrit en
    Avril 2014
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Auditeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2014
    Messages : 80
    Par défaut init variable dans le .h
    Bonjour,

    Je me sert de .h pour stocker des typedef enum. Je souhaite savoir si l’initialisation de variable dans le .h est correcte ou pas ?
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    typedef enum {
    UN,
    DEUX,
    TROIS
    }chiffre;
     
    char chiffre2[] = "1 2 3";
     
    int chiffre3 = 123;
    D'avance merci.

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Le contenu d'un .h est copié dans l'unité de compilation avec les directives #include.
    Tu peux déclarer des variables, mais elles seront différentes dans chaque unité de compilation.
    Vue ta question, je doute que ce soit ce que tu veuilles faire.
    extern ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre confirmé
    Homme Profil pro
    Auditeur informatique
    Inscrit en
    Avril 2014
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Auditeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2014
    Messages : 80
    Par défaut
    Si c'est bien ça.
    Selon mon defined symbol, j'appelle à la compilation le .h qui me convient avec #include. Donc, j'ai l'initialisation de mon enum que je souhaite.
    Je voulais juste savoir si c'était "conventionnel" d'initialiser des variables des les .h.
    Merci

  4. #4
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Ce n'est pas la bonne façon de procéder.

    Ici, tes variables vont être dupliquées entre plusieurs `.c, elles auront le même nom, et donc au moment de l'assemblage des *.c pour faire un *.exe, tu auras une erreur "mutiple definitions of....".

    La "bonne" solution d'avoir un *.h avec des déclarations avec le mot-clé "extern" et un *.c avec les définitions (là où tu leur donnes leurs valeurs). Je met des guillemets à "bonne" car tu fais là des variables globales et ce n'est pas souvent une "bonne" idée. Comme ce n'est pas le sujet de la discussion, je ne m'éternise pas là-dessus.

    Une autre solution est de rajouter le mot-clé "static" dans ton *.h. A ce moment-là, chaque *.c recevra une instance différente de ton groupe de variables. Sauf que tu peux pas modifier celles de toto.c depuis titi.c et je ne suis pas sür que ça te convienne.

  5. #5
    Membre confirmé
    Homme Profil pro
    Auditeur informatique
    Inscrit en
    Avril 2014
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Auditeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2014
    Messages : 80
    Par défaut
    Ici, tes variables vont être dupliquées entre plusieurs `.c, elles auront le même nom, et donc au moment de l'assemblage des *.c pour faire un *.exe, tu auras une erreur "mutiple definitions of....".
    L'include du *.h n'est fait qu'à un seul endroit, seront-elles quand même dupliquées ?

    La "bonne" solution d'avoir un *.h avec des déclarations avec le mot-clé "extern" et un *.c avec les définitions (là où tu leur donnes leurs valeurs). Je met des guillemets à "bonne" car tu fais là des variables globales et ce n'est pas souvent une "bonne" idée. Comme ce n'est pas le sujet de la discussion, je ne m'éternise pas là-dessus.
    L'idée c'était d'avoir un *.h stockant seulement des variables, define, pas de méthode et sans *.c.

    Une autre solution est de rajouter le mot-clé "static" dans ton *.h. A ce moment-là, chaque *.c recevra une instance différente de ton groupe de variables. Sauf que tu peux pas modifier celles de toto.c depuis titi.c et je ne suis pas sür que ça te convienne.
    Ma variable ne doit pas être modifiée, je vais donc la passer en const. Static ne me convient pas car sont utilisation est limitée à son propre fichier.

  6. #6
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 759
    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 759
    Par défaut
    Citation Envoyé par alaska90 Voir le message
    L'idée c'était d'avoir un *.h stockant seulement des variables, define, pas de méthode et sans *.c.
    Il faut mettre les include guards (<- lien wiki en français)

  7. #7
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par alaska90 Voir le message
    L'include du *.h n'est fait qu'à un seul endroit, seront-elles quand même dupliquées ?

    L'idée c'était d'avoir un *.h stockant seulement des variables, define, pas de méthode et sans *.c.

    Ma variable ne doit pas être modifiée, je vais donc la passer en const. Static ne me convient pas car sont utilisation est limitée à son propre fichier.
    Je pense que tu t'égares dans une mauvaise solution à un problème que tu ne nous a pas vraiment décrit.

    Si tu inclus un *.h à un seul endroit (cet endroit étant logiquement un *.c), pourquoi avoir un *.h ? Pourquoi ne pas simplement mettre son contenu dans l'unique *.c où tu l'inclus ?

    Cette idée me semble hautement bizarre. Quel est le vrai but de faire ça ?

    Si elle ne doit pas être modifiée, alors ce n'est pas une variable, c'est uen constante. "#define" ou "static const" devrait faire l'affaire.
    Tu dis que "static" ne te convient pas car limité à un fichier et pourtant tu as aussi dit que ton *.h est inclus une seule fois, ça ne me semble pas cohérent.


    Citation Envoyé par foetus Voir le message
    Il faut mettre les include guards (<- lien wiki en français)
    Les include guards permettent de ne pas inclure plus fois le même *.h dans un fichier *.c, elles ne sont d'aucune aide face au problème de multiples définitions de variables.

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 827
    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 827
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par alaska90 Voir le message
    Static ne me convient pas car sont utilisation est limitée à son propre fichier.
    Tu n'as pas bien saisi le rôle de "static" qui, dans le cas d'une variable globale (ou même d'une fonction), est justement de limiter ladite variable (ou fonction) à son propre fichier...

    Citation Envoyé par alaska90 Voir le message
    L'include du *.h n'est fait qu'à un seul endroit, seront-elles quand même dupliquées ?
    Ce n'est pas en utilisant un mauvais truc dans une configuration qui fait que ça marche que ça rend le truc correct. Peut-être qu'aujourd'hui ce ".h" ne sera inclus qu'une fois et donc que cela se passera bien mais tu auras pris une mauvaise habitude qui t'explosera au visage un jour ou l'autre.
    Alors qu'il existe des solutions efficaces qui marchent dans toutes les configurations (surtout celle présentée hier par Bktero à base de "extern"), donc y compris pour un ".h" qui n'est inclus qu'une fois (et accessoirement là je rejoins Bktero sur le but de cette manoeuvre).

    Citation Envoyé par Bktero Voir le message
    Je pense que tu t'égares dans une mauvaise solution à un problème que tu ne nous a pas vraiment décrit.
    Problème XY...
    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 confirmé
    Homme Profil pro
    Auditeur informatique
    Inscrit en
    Avril 2014
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Auditeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2014
    Messages : 80
    Par défaut
    Selon la configuration choisie lors de la compilation, j'inclue un .h

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    ifdef A
        #include a.h
    endif
    ifdef B
        #include b.h
    endif
    Ces fichier a.h et b.h comprennent les mêmes noms de define, typedef enum et constantes.

    fichier a.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    typedef enum{
    TEST1,
    TEST2
    }enumerateur
    const int entier = 1
    fichier b.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    typedef enum{
    TEST5,
    TEST6
    }enumerateur
    const int entier = 4
    Selon le fichier que j'inclue dans mon main, entier et enum n'auront pas les mêmes valeurs.
    Initialiser la constante entier dans le .h comme je viens de l'écrire est-elle bonne ?

  10. #10
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    -On ne doit jamais utiliser de variables globales, ça donne un code ingérable.
    -On ne doit jamais jamais définir de variables dans un header. Le C (pas le C++) tolère la redéfinition de variables donc pourrait fonctionner ici, mais cela est permis pour gérer le cas ingérable autrement de 2 variables pré-initialisées qui se référencent l'une l'autre.
    -Et surtout on ne doit jamais jamais jamais définir des variables static dans un header, ça provoque des multidéfinitions qui amènent à des bugs complètement tordus (on croit utiliser une même variable alors qu'il en a plusieurs.)

    Si ce sont des constantes, la règle devient:
    -On peut les déclarer globales, ou y préférer utiliser des define (pas la même chose en C++).
    -On ne les déclare surtout pas static. Ça provoque au mieux une consommation mémoire inutile, et si on venait en prendre l'adresse ça donnerais aussi des bugs tordus et quasi-impossibles à résoudre.

    Dans ton cas, on peut considérer que ce ne sont pas des fichiers entête, ce sont des extraits de code. Il faut donc ne pas leur mettre le suffixe .h ni .c. Tu peux y mettre ce que du mets dans un .c et tu peux utiliser un autre suffixe, par exemple .selection ou autre.

  11. #11
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 827
    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 827
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par alaska90 Voir le message
    Selon la configuration choisie lors de la compilation, j'inclue un .h
    Tu mets directement tes directives dans un seul ".h" que tu inclus directement. Ou bien encore plus directement dans ton ".c".
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #ifdef A
    typedef enum{
    	TEST1,
    	TEST2
    }enumerateur;
    const int entier = 1;
    #else // B
    typedef enum{
    	TEST5,
    	TEST6
    }enumerateur;
    const int entier = 4;
    #endif //A
    Citation Envoyé par alaska90 Voir le message
    Initialiser la constante entier dans le .h comme je viens de l'écrire est-elle bonne ?
    Non. Voir premier post de Bktero à ce sujet. Tu déclares ta variable en "extern" dans le ".h" sans lui mettre de valeur, tu inclus ce ".h" partout où la variable est utilisée, et tu la définis dans un seul fichier ".c" (pour simplifier on choisit généralement celui qui contient le "main") et là tu lui initialises sa valeur.

    Citation Envoyé par dalfab Voir le message
    On ne doit jamais utiliser de variables globales, ça donne un code ingérable.
    Et on ne doit jamais dire "jamais" en prog. Je suis d'accord que les globales sont très souvent une fausse bonne idée mais elles existent néanmoins et donc, de fait, ont (ou peuvent avoir) un rôle à jouer, aussi minime soit-il. Si par exemple tu fais de la gestion de signal avec kill() et signal() tu ne pourras pas éviter les globales.

    Et pour "améliorer" la gestion du code dans le cas d'utilisation de globales, il existe aussi certains outils (ou certaines façons d'écrire). Je présume que quand tu parles de code ingérable, tu fais (comme moi) référence à un code qui modifie des globales un peu partout sans trop se préoccuper du relecteur. Exemple
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int v;
    void toto() {
    	... (du code, beaucoup de code)...
    	v=123;
    	... (du code, beaucoup de code)...
    }
    Un souci donc ici c'est que la modification de "v" est cachée par le fouillis du code avant et après. Et rien ne dit, au départ, que "toto" va modifier (voire même utiliser) "v". Mais si tu utilises judicieusement le extern...
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int v;
    void toto() {
    	extern int v;
    	... (du code, beaucoup de code)...
    	v=123;
    	... (du code, beaucoup de code)...
    }
    ... hé oui, le extern n'est pas que réservé aux variables se trouvant dans un autre source lié à la compilation. Il a parfaitement le droit de faire référence localement à une variable globale située dans le même source. Ok c'est pas une protection absolue mais ça peut aider à savoir dès la première lecture que "toto" va utiliser "v"...
    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]

  12. #12
    Membre confirmé
    Homme Profil pro
    Auditeur informatique
    Inscrit en
    Avril 2014
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Auditeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2014
    Messages : 80
    Par défaut
    Merci pour ces informations.

    Tu mets directement tes directives dans un seul ".h" que tu inclus directement. Ou bien encore plus directement dans ton ".c".
    Ces deux solutions ont déjà été faites. Je cherche une nouvelle solution pour le faire car le code devient illisible (trop de #ifdef...). Dans mon exemple j'ai mis deux cas, mais ça peut aller à plus de dix.

    Dans ton cas, on peut considérer que ce ne sont pas des fichiers entête, ce sont des extraits de code. Il faut donc ne pas leur mettre le suffixe .h ni .c. Tu peux y mettre ce que du mets dans un .c et tu peux utiliser un autre suffixe, par exemple .selection ou autre.
    C'est surement la bonne solution. Je vais voir comment faire ça. Merci

  13. #13
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 827
    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 827
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par alaska90 Voir le message
    Je cherche une nouvelle solution pour le faire car le code devient illisible (trop de #ifdef...). Dans mon exemple j'ai mis deux cas, mais ça peut aller à plus de dix.
    Hum, quand on en arrive à ce genre de situation où tu dépasses le stade de la simple compilation conditionnelle et où tu effondres le programmeur sous autant de cas à coder, alors peut-être essayer dans une autre direction totalement différente. Tu as dans ton post précédent parlé de configuration choisie. Tu peux alors te tourner vers un vrai fichier de configuration, le fameux ".ini" sous windows (ou .xxxrc sous Linux) qui est lu au début du programme. Ainsi ton code redescends en poids, redevient plus lisible et peut de lui-même s'adapter aux multiples cas de figures qui sont là et à celles qui peuvent arriver demain...
    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]

  14. #14
    Membre confirmé
    Homme Profil pro
    Auditeur informatique
    Inscrit en
    Avril 2014
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Auditeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2014
    Messages : 80
    Par défaut
    Tu peux alors te tourner vers un vrai fichier de configuration, le fameux ".ini" sous windows (ou .xxxrc sous Linux) qui est lu au début du programme.
    La solution est intéressante et bien adaptée. Merci pour vos explications !

  15. #15
    Membre Expert
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    667
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 95
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 667
    Par défaut
    Bonjour,

    Un entête en tant que fichier de configuration, avec quelques précautions ça me semble envisageable :

    my_config.h :
    Code c : 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
    #if defined my_config
    #pragma once
      int my_config_x_def_guard= 1;
     
      int common_var= 5;
     
      #if   my_config == 1 
         int a_var= 1; 
         //or #include "..."
         //...
     
      #elif my_config == 2
         int a_var= 2;
         //...
     
      #else 
         #error "oops! misconfiguration."
      #endif
     
    #else
       #error "oops! improper use of my_config.h"
    #endif

    exemple d'utilisation :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #define my_config 2
    #include "my_config.h"
     
    #include <stdio.h>
    int main(){
      printf("a_var= %d, common_var= %d", a_var, common_var);
    }

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

Discussions similaires

  1. Problème init variable dans controle utilisateur
    Par stolken dans le forum VB.NET
    Réponses: 8
    Dernier message: 02/04/2010, 09h26
  2. [LG]variables dans procédure
    Par néo333 dans le forum Langage
    Réponses: 2
    Dernier message: 04/11/2003, 23h24
  3. comment recuperer une variable dans flash
    Par krépuscul dans le forum Flash
    Réponses: 30
    Dernier message: 16/10/2003, 09h40
  4. Réponses: 13
    Dernier message: 14/06/2003, 22h15
  5. [syntaxe] Gerer les variables dans une requete
    Par rastapopulos dans le forum MS SQL Server
    Réponses: 12
    Dernier message: 15/04/2003, 12h53

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