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 :

Petite explication sur les variables externes


Sujet :

C

  1. #1
    Membre éprouvé
    Avatar de Ladgalen
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Novembre 2007
    Messages
    466
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Novembre 2007
    Messages : 466
    Points : 982
    Points
    982
    Par défaut Petite explication sur les variables externes
    Bonjour

    Supposons que j'ai un programme avec chaque fonction et le main dans un fichier source différent.

    Dans le fichier main.c je déclare une variable comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    ...
    extern double force;
     
    int main(void) {
     ...
    }
    Est ce que du coup je peux utiliser force dans n'importe qu'elle fonction de mon programme ? ou faut - il que je la redéclare dans chaque fichier ou j'utilise force :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    ...
    extern double force;
    ...
    int fonction1 () {
    ...
    }
    Mon but étant par exemple de déclarer force au départ, si c'est un tableau de l'allouer un peu plus tard, puis qu'une fonction les calcules une autres les utilises une autre les modifies ect ... toutes ces fonctions utilisant la MEME variables (et zone mémoire).

    Il me semble que le fait de mettre extern joue se role mais dans un programme en c que j'ai un peu parcouru, tout un tas de variables globales sont définies (avec extern) dans un main.h qui est inclu dans presque toutes les fonctions. D'où ma question !

    Pour ceux qui connaissent je voudrais retrouver le même type d'utilisation de variables globales d'un programme qui sont défini en fortran dans un common ou un module. Mais dans ce cas on fait appel au common ou au module dans chaque sous programme.

    Merci pour votre aide

  2. #2
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    Dans un fichier .c, tu définies ta variable globale comme d'habitude.
    Dans les fichiers qui ont besoin d'utiliser cette variable, tu la déclares avec le qualificatif extern et rigoureusement de la même façon que lors de la définition. Le but est de dire à cette unité de compilation que cette variable est de tel type et existe quelque part. Cette déclaration peut figurer dans un .h sans problème puisqu'elle n'entraine pas de création de variables.

    Donc, avec ton exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    double force; 
    int main(void) {
     ...
    }
    // utilisation dans un autre fichier
    extern double force;
    int fonction1 () {
    ...
    }
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Tu dois la redéclarer dans chaque unité de compilation (pour ça, on a tendance à mettre la déclaration dans un fichier d'en-tête .h) et la définir vraiment dans une seule unité de compilation. Exemple:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    /*Globales.h*/
     
    extern double g_force;
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    /*Globales.c*/
    #include "Globales.h"
     
    double g_force = 0.0;
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /*Main.c*/
    #include "Globales.h"
     
    int main(void) {
     ...
    }
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    /*AutreFichier.c*/
    #include "Globales.h"
     
    ...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Membre éprouvé
    Avatar de Ladgalen
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Novembre 2007
    Messages
    466
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Novembre 2007
    Messages : 466
    Points : 982
    Points
    982
    Par défaut
    Merci pour vos réponses, je vais donc les déclarer dans mon .h !

    Est ce qu'il est nécessaire de repréciser

    Pourquoi indiquer à nouveau le double ?

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Parce que c'est une définition (ici avec initialisation, mais je ne sais plus si c'est vraiment nécessaire), pas une simple affectation.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Membre éprouvé
    Avatar de Ladgalen
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Novembre 2007
    Messages
    466
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Novembre 2007
    Messages : 466
    Points : 982
    Points
    982
    Par défaut
    J'y arrive pas !

    J'ai ces trois fichiers :

    main..h
    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
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
     
    /* thermo */
    extern	int	nat ;
    extern	double	volume ;
    extern	double	temperature ;
    extern	double 	xi ;
    extern	double	pression ;
     
    /* atome */
    extern	double	masse ;
    extern	double	LJsigma ;
    extern	double	LJeps ;
    extern	char 	*aname ;
     
    /* constantes physiques ou mathematiques */
    extern	double	boltzman ;
    extern	double	avogadro ;
    extern	double	qElectron ;
    extern	double	aBohr ;
    extern	double	pi ;
    Mon fichier main.c
    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 "main.h"
     
    extern int initialisation( void );
     
    int main( int narg, char *arg[] ) {
     
    	int 	erreur = 0 ;
    	int 	i ;
     
    	// Initialisation des constantes et ouverture fichiers de sorties
    	erreur += initialisation();
     
    	printf ( "erreur  : %d \n", erreur );
     
    	printf ("temperature	: %e \n", temperature );
    	printf ("LJsigma	: %e \n", LJsigma );
    	printf ("LJeps  	: %e \n", LJeps );
     
    	return erreur;
    }
    et le fichier initialisation.c
    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
     
    #include "main.h"
     
    int initialisation(void) {
     
    	int	erreur;
     
    	double	boltzman  	= 1.380662e-23 ;  	// J.K-1
    	double	avogadro 	= 6.0228e23 ;		// mol-1
    	double	qElectron 	= 1.6021892e-19 ;	// C
    	double	aBohr 		= 0.5291e-10 ;		// m
    	double	pi 		= 4. * atan(1.) ;	
     
    	double temperature 	= 300.e0 ;
     
    	char 	*aname		= "Ar" ;
    	double 	masse		= 39.95e-3 / avogadro ;
    	double	LJsigma		= 3.405e-10 ;
    	double	LJeps		= 1.6567944e-21 ;
     
    	erreur = 0;
     
    	return erreur;
     
    }
    et j'ai le message d'erreur suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    /tmp/ccD5P3Wj.o: In function `main':
    simLad.c:(.text+0x35): undefined reference to `temperature'
    simLad.c:(.text+0x4b): undefined reference to `LJsigma'
    simLad.c:(.text+0x61): undefined reference to `LJeps'
    collect2: ld a retourné 1 code d'état d'exécution
    Pourquoi il ne trouve pas les variables vu qu'elles sont dans le main.h ? Peut être que ce n'est pas du tout la bonne façon de faire en C ! Dites moi ?

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Tes définitions de variables sont dans une fonction, elles ne touchent donc pas les variables globales: Ce sont seulement des variables locales du même nom.

    Essaie ainsi:
    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
    23
    24
    25
    26
    27
    28
    /*Initialisation.c*/
    #include "main.h"
     
    double	boltzman  	= 1.380662e-23 ;  	// J.K-1
    double	avogadro 	= 6.0228e23 ;		// mol-1
    double	qElectron 	= 1.6021892e-19 ;	// C
    double	aBohr 		= 0.5291e-10 ;		// m
    double	pi;
     
    double temperature 	= 300.e0 ;
     
    char 	*aname		= "Ar" ; /*devrait être char const * */
    double 	masse;
    double	LJsigma		= 3.405e-10 ;
    double	LJeps		= 1.6567944e-21 ;
     
    int initialisation(void) {
     
    	int	erreur;
     
    	pi 		= 4. * atan(1.) ;	
     	masse		= 39.95e-3 / avogadro ;
     
    	erreur = 0;
     
    	return erreur;
     
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Membre éprouvé
    Avatar de Ladgalen
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Novembre 2007
    Messages
    466
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Novembre 2007
    Messages : 466
    Points : 982
    Points
    982
    Par défaut
    oui pour le coup des variables locale j'aurai pu voir ça tout seul ...

    Mais il n'existe aucun moyen de ne déclarer ces variables externes qu'une seule fois car sinon ça perd de son intéret. Avec ce que tu me propose, il faut que je les déclare à chaque fois que je met mon main.h dans une fonction qui les utilise (ce qui est probablement l'origine de l'erreur que j'ai dans le main.c).

  9. #9
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    La variable g_force n'est définie (créée) qu'une fois : lorsque tu as écrit double g_force = 0.0 ;
    Les extern double g_force ; ne crée pas une autre variable g_force, ils déclarent simplement qu'il existe quelque part ailleurs dans le programme une variable de type double et qui s'appelle g_force et que lorsque tu utilises g_force, il s'agit de cette variable.

    Avec ce que tu me propose, il faut que je les déclare à chaque fois que je met mon main.h dans une fonction qui les utilise (ce qui est probablement l'origine de l'erreur que j'ai dans le main.c).
    Evidemment, à chaque fois que tu utilises g_force, il faut qu'elle soit définie par un extern double g_force (c'est naturellement inutile là où elle est définie), sinon comment le compilateur peut-il deviner ce que c'est ?
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  10. #10
    Membre éprouvé
    Avatar de Ladgalen
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Novembre 2007
    Messages
    466
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Novembre 2007
    Messages : 466
    Points : 982
    Points
    982
    Par défaut
    Je viens de comprendre.

    Si j'ai une variable globale, il faut que dans toutes mes fonctions elles soit déclarée en dehors de la fonction comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    extern double globale;
    sauf dans une des fonction du programme ou elle est déclaré en dehors de cette fonction de cette manière :

    En faisant ça ça marche. Ce que j'avais pas compris c'est que par rapport à ce qu'à écrit Médinoc je pensais que dans toutes les fonctions, il fallait déclarer les variables globales avec et sans le extern ... je trouvais ça louche !

    Merci à vous tous

  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Petite correction.
    Citation Envoyé par diogene Voir le message
    Evidemment, à chaque fois que tu utilises g_force, il faut qu'elle soit déclarée par un extern double g_force (c'est naturellement inutile là où elle est définie), sinon comment le compilateur peut-il deviner ce que c'est ?
    Aussi, il me semble avoir lu que la déclarer extern avant de la définir était obligatoire en C++.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

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

Discussions similaires

  1. [XSLT] petite question sur les variables
    Par lol88 dans le forum XSL/XSLT/XPATH
    Réponses: 6
    Dernier message: 25/11/2009, 10h46
  2. petite question sur les variables
    Par discogarden dans le forum ASP.NET
    Réponses: 2
    Dernier message: 02/06/2008, 14h48
  3. petite explication sur les classes
    Par elmcherqui dans le forum Qt
    Réponses: 2
    Dernier message: 15/05/2008, 11h05
  4. question sur les variables globales et les thread posix
    Par souris_sonic dans le forum POSIX
    Réponses: 5
    Dernier message: 13/06/2003, 13h59
  5. recherches des cours ou des explications sur les algorithmes
    Par Marcus2211 dans le forum Algorithmes et structures de données
    Réponses: 6
    Dernier message: 19/05/2002, 22h18

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