variable globale

variable globale - C - Programmation

Marsh Posté le 12-04-2007 à 15:42:18    

voilà je suis en train d'écrire un programme en C et j'aimerais définir une variable qui soit présente et qui ait la meme valeur dans toutes les fonctions, main et sous programme

 


comment faire ?

 

merci d'avance


Message édité par Profil supprimé le 12-04-2007 à 15:42:40
Reply

Marsh Posté le 12-04-2007 à 15:42:18   

Reply

Marsh Posté le 12-04-2007 à 15:45:21    

la passer par référence à toutes tes fonctions :ange:
 
ou bosser comme un goret, la coller dans une zone mémoire figée, et taper à la main à cette adresse depuis partout dans ton programme [:magicbuzz]

Reply

Marsh Posté le 12-04-2007 à 15:45:57    

ya pas un moyen plus simple que ça ?
 

Reply

Marsh Posté le 12-04-2007 à 15:47:36    

chais pas, je sais pas faire de C :D

Reply

Marsh Posté le 12-04-2007 à 15:48:29    

 

Voire eventuellement extern pour la compilation séparée.
Mais le pointeur est la solution la plus élégante.


Message édité par _darkalt3_ le 12-04-2007 à 15:57:40

---------------
Töp of the plöp
Reply

Marsh Posté le 12-04-2007 à 15:53:08    

ah oui c'est vrai qu'en C on parle pas de référence, mais de pointeur plutôt :D

Reply

Marsh Posté le 12-04-2007 à 17:47:19    

+1 pour le pointeur, c'est très mauvais les variables globales....


---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 12-04-2007 à 17:48:23    

ben si elle est globale mais constante ?

Reply

Marsh Posté le 12-04-2007 à 18:25:06    

.h
extern const int foo;
 
.c
#include .h
const int foo = 3;

Reply

Marsh Posté le 12-04-2007 à 19:13:07    

did-54 a écrit :

ben si elle est globale mais constante ?


déjà, si elle est constante, on ne parle plus de variable...
 
ensuite, le risque des variables globales, c'est qu'elles soient écrasées par le scope local. je ne sais pas ce que fait le C dans ce cas. toujours est-il que c'est risqué et pas propre, parce qu'un dev qui passe derrière est rapidement induit en erreur par la valeur globale.

Reply

Marsh Posté le 12-04-2007 à 19:13:07   

Reply

Marsh Posté le 12-04-2007 à 19:24:10    

MagicBuzz a écrit :

ensuite, le risque des variables globales, c'est qu'elles soient écrasées par le scope local. je ne sais pas ce que fait le C dans ce cas.


Il gère parfaitement la situation. Toute nouvelle définition d'une variable masque la précédente dans le bloc dans lequel elle est définie. Dès qu'on quitte le bloc, on a de nouveau accès à la variable précédente.
 
Le mot clef "extern" peut être utilisé chaque fois qu'on veut faire référence à la globale
 

Code :
  1. int var=10;                 // Variable globale
  2. int main()
  3. {
  4.     // Ici, "var" est connue et correspond à la globale
  5.     printf("var=%d\n", var);                    // Affiche 10
  6.     // Ouverture d'un nouveau bloc
  7.     {
  8.          int var=500;
  9.          // Ici, "var" fait référence à la variable locale
  10.          printf("var=%d\n", var);                    // Affiche 500
  11.          // Ouverture d'un nouveau bloc
  12.          {
  13.               // Ici, "var" fait toujours référence à la variable du dessus soit 500
  14.               // Et ce, tant qu'on ne la masquera pas par une nouvelle déclaration
  15.               // Maintenant, on déclare "var" comme "extern" pour récupérer la globale
  16.               extern int var;
  17.               // Maintenant, quand on parlera de "var", on parlera de la globale
  18.               printf("var=%d\n", var);                    // Affiche 10
  19.          }
  20.          // Ici, on a quitté le sous-bloc donc "var" fait de nouveau référence à 500
  21.          printf("var=%d\n", var);                    // Affiche 500
  22.     }
  23.     // Ici, on a quitté le sous-bloc donc "var" fait de nouveau référence à 10
  24.     printf("var=%d\n", var);                    // Affiche 10
  25.     return 0;
  26. }


 
Une des solutions pour utiliser des variables globales tout en "essayant" de rester propre est de redéclarer la variable avec "extern" dans chaque fonction où elle est utilisée => au-moins, si la variable est perdue (écrasée) par accident, on peut "facilement" (entre guillemets) cibler les fonctions qui sont suceptibles d'avoir écrasée la globale...
 
Ex:

Code :
  1. int var=10;                 // Variable globale
  2. <........ suite du programme .....>
  3. void fonction_quelconque()
  4. {
  5.      // Cette fonction utilisera "var" => On redéclare "var" ici même si c'est inutile
  6.      extern int var;
  7.      <... code de la fonction ...>
  8. }

Message cité 2 fois
Message édité par Sve@r le 12-04-2007 à 19:33:03

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 12-04-2007 à 20:00:15    

Sve@r a écrit :

Il gère parfaitement la situation. Toute nouvelle définition d'une variable masque la précédente dans le bloc dans lequel elle est définie. Dès qu'on quitte le bloc, on a de nouveau accès à la variable précédente.


Justement, en C# par exemple, c'est interdit de faire ça, tout comme en Java je crois.
 
Parceque si effectivement, ça peut s'avérer utile dans certains cas, c'est très dangereux notamment pour la maintenance.
 

Code :
  1. int main()
  2. {
  3.    /* bla bla sur 500 lignes */
  4.    int nbColonnes = 4;
  5.    /* bla bla sur 500 lignes */
  6.    {
  7.         /* bla bla sur 500 lignes */
  8.         j'utilise nbColonnes
  9.         /* bla bla sur 500 lignes */
  10.         int nbColonnes = 12;
  11.         /* bla bla sur 500 lignes */
  12.         j'utilise nbColonnes
  13.         /* bla bla sur 500 lignes */
  14.    }
  15.    /* bla bla sur 500 lignes */
  16.    j'utilise nbColonnes
  17.    /* bla bla sur 500 lignes */
  18. }


 
=> Ce cas, si le dev qui doit modifier le code ne dispose pas d'un super environnement permettant d'atteindre la définition des variables, il y a de grandes chances pour qu'il ne retienne pas la bonne valeur lors de sa modification. Ainsi, il va introduire un bug, qu'il va avoir un mal de chien à corriger, car la raison très loin d'être évidente.
 
 
Anyway, dans le Whitepaper "How to design unmaintainable code" ils recommandent l'utilisation des variables globales, on peut donc en déduire rapidement que c'est à éviter comme la peste ;)
Le C++ et le C sont d'ailleurs lourdement montrés du doigt par ce document, indiquant dès l'introduction que ce sont des langages de prédilection pour faire du code impossible à relire :D
ADA par contre, est fortement déconseillé par ce document, car il empêche près de 95% des méthodes obfuscation :) Vive ADA ! :bounce:

Message cité 2 fois
Message édité par MagicBuzz le 12-04-2007 à 20:12:16
Reply

Marsh Posté le 12-04-2007 à 20:47:48    

MagicBuzz a écrit :


Anyway, dans le Whitepaper "How to design unmaintainable code" ils recommandent l'utilisation des variables globales, on peut donc en déduire rapidement que c'est à éviter comme la peste utiliser avec componction, intelligence et de manière documentée ;)


 
( et au fait, on ne fait pas des fonction de 4klignes directement dans le main :o )


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 12-04-2007 à 22:11:16    

bin en fait, c'est pas vraiment une variable, c'est plutot un paramètre
 
ca changera pas pendant une execution du programme
 
mais je voudrais lancer le programme pour plusieurs valeurs de ce paramètre [:aloy]

Reply

Marsh Posté le 12-04-2007 à 22:15:56    

MagicBuzz a écrit :

Justement, en C# par exemple, c'est interdit de faire ça, tout comme en Java je crois.


Bon, on va pas comparer les langages. Parce que sinon, moi je cite "Python" où toute fonction a automatiquement accès à toutes les variables du programme principal... mais en lecture par défaut (si on veut l'écriture faut l'expliciter)
 

MagicBuzz a écrit :

Parceque si effectivement, ça peut s'avérer utile dans certains cas, c'est très dangereux notamment pour la maintenance.
 

Code :
  1. int main()
  2. {
  3.    /* bla bla sur 500 lignes */
  4.    int nbColonnes = 4;
  5.    /* bla bla sur 500 lignes */
  6.    {
  7.         /* bla bla sur 500 lignes */
  8.         j'utilise nbColonnes
  9.         /* bla bla sur 500 lignes */
  10.         int nbColonnes = 12;
  11.         /* bla bla sur 500 lignes */
  12.         j'utilise nbColonnes
  13.         /* bla bla sur 500 lignes */
  14.    }
  15.    /* bla bla sur 500 lignes */
  16.    j'utilise nbColonnes
  17.    /* bla bla sur 500 lignes */
  18. }


 
=> Ce cas, si le dev qui doit modifier le code ne dispose pas d'un super environnement permettant d'atteindre la définition des variables, il y a de grandes chances pour qu'il ne retienne pas la bonne valeur lors de sa modification. Ainsi, il va introduire un bug, qu'il va avoir un mal de chien à corriger, car la raison très loin d'être évidente.


Evidemment. Ce n'est pas parce que l'écriture d'une énormité est autorisée qu'il faut absolument l'écrire. S'amuser à redéfinir des variables dans des sous-blocs c'est très dangereux. Possible... mais dangereux !!!
 

MagicBuzz a écrit :

Le C++ et le C sont d'ailleurs lourdement montrés du doigt par ce document, indiquant dès l'introduction que ce sont des langages de prédilection pour faire du code impossible à relire :D


Boaf... dans tout langage il y a une façon saine d'écrire du code... et il y a 999.999 autres façons d'écrire porc...
 

MagicBuzz a écrit :

ADA par contre, est fortement déconseillé par ce document, car il empêche près de 95% des méthodes obfuscation :) Vive ADA ! :bounce:


Vive Python !!! :bounce:  :bounce:  :bounce:


Message édité par Sve@r le 13-04-2007 à 19:28:48

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 13-04-2007 à 11:27:35    

Sve@r a écrit :

Il gère parfaitement la situation. Toute nouvelle définition d'une variable masque la précédente dans le bloc dans lequel elle est définie. Dès qu'on quitte le bloc, on a de nouveau accès à la variable précédente.

t'as aussi le droit d'avoir un compilateur pas quiche qui va te dire les ambiguités.

Reply

Marsh Posté le 13-04-2007 à 11:47:56    

Taz a écrit :

t'as aussi le droit d'avoir un compilateur pas quiche.


[:rofl]
 

Taz a écrit :

qui va te dire les ambiguités


 
Non, sans rire, le C a été conçu dans l'optique "le programmeur sait ce qu'il fait". Maintenant, on se met à écrire des compilos pour nous avertir que, peut-être, on ne sait pas ce qu'on fait. Il n'y a pas quelque part une certaine incohérence ???

Message cité 2 fois
Message édité par Sve@r le 13-04-2007 à 11:57:32

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 13-04-2007 à 13:22:22    

Sve@r a écrit :


Non, sans rire, le C a été conçu dans l'optique "le programmeur sait ce qu'il fait". Maintenant, on se met à écrire des compilos pour nous avertir que, peut-être, on ne sait pas ce qu'on fait. Il n'y a pas quelque part une certaine incohérence ???


 
J'aurais dis plutôt dans l'optique "bon on a pas encore ni les outils ni la puissance pour savoir à la place du programmeur ce qu'il fait et on aimerait éviter que les  les compils durent trois plombes, on verra plus tard..."


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 13-04-2007 à 14:03:06    

Sve@r a écrit :

[:rofl]
 
 
 
Non, sans rire, le C a été conçu dans l'optique "le programmeur sait ce qu'il fait". Maintenant, on se met à écrire des compilos pour nous avertir que, peut-être, on ne sait pas ce qu'on fait. Il n'y a pas quelque part une certaine incohérence ???


euh je vois pas le rapport. Le C précise l'ordre de résolution. -Wshadow avertit quand il y a masquage.

Reply

Marsh Posté le 14-04-2007 à 19:24:19    

Taz a écrit :

-Wshadow avertit quand il y a masquage.


Ben normallement, il ne devrait jamais avoir besoin de cette option car quand tu crées ta locale

  • soit tu décides de masquer la globale en toute connaissance de cause parce que tu n'en as pas besoin
  • soit tu ignores qu'il y a une globale qui porte ce nom ce qui prouve que, pour la zone dans laquelle tu programmes, tu n'as là non-plus pas besoin de la globale
  • soit tu as besoin aussi de la globale et tu t'apercevras très vite tout seul du soucis => là t'auras certes quelques modifs à faire mais est-vraiment bien contraignant ? Surtout qu'en général, certains conseils de prog préconisent de particulariser les globales pour bien les repérer (par un préfixe "g" par exemple...)

Message cité 2 fois
Message édité par Sve@r le 14-04-2007 à 19:25:16

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 14-04-2007 à 19:32:44    

Sve@r a écrit :

Ben normallement, il ne devrait jamais avoir besoin de cette option car quand tu crées ta locale

  • soit tu décides de masquer la globale en toute connaissance de cause parce que tu n'en as pas besoin
  • soit tu ignores qu'il y a une globale qui porte ce nom ce qui prouve que, pour la zone dans laquelle tu programmes, tu n'as là non-plus pas besoin de la globale
  • soit tu as besoin aussi de la globale et tu t'apercevras très vite tout seul du soucis => là t'auras certes quelques modifs à faire mais est-vraiment bien contraignant ? Surtout qu'en général, certains conseils de prog préconisent de particulariser les globales pour bien les repérer (par un préfixe "g" par exemple...)


Dans le pire des cas, tu est au sein d'un bloc qui masque, mais trop loin de la déclaration pour le voir, et tu compte utiliser la globale. Ça ne devrait cependant pas arriver si tu évites de faire des fonctions de 4km de long. (et sinon y'a ton point n°3 pour te sauver la vie).


Message édité par 0x90 le 14-04-2007 à 19:37:38

---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 15-04-2007 à 13:10:19    

Sve@r a écrit :

Ben normallement, il ne devrait jamais avoir besoin de cette option car quand tu crées ta locale

  • soit tu décides de masquer la globale en toute connaissance de cause parce que tu n'en as pas besoin



 
#include <stdio.h>
 
Combien de déclaration de variables globales importes-tu ? Peux tu me les citer de tête avec leur type ?

Sve@r a écrit :


  • soit tu ignores qu'il y a une globale qui porte ce nom ce qui prouve que, pour la zone dans laquelle tu programmes, tu n'as là non-plus pas besoin de la globale


La politique de l'autruche a fait ses preuves.

Sve@r a écrit :


  • soit tu as besoin aussi de la globale et tu t'apercevras très vite tout seul du soucis => là t'auras certes quelques modifs à faire mais est-vraiment bien contraignant ? Surtout qu'en général, certains conseils de prog préconisent de particulariser les globales pour bien les repérer (par un préfixe "g" par exemple...)

Dans mon monde, le problème des bugs, c'est justement qu'on ne s'en aperçoit pas de prime abord. Si mon outil peut m'aider à la prévenir, je l'utilise.

Reply

Marsh Posté le 16-04-2007 à 15:00:43    

Taz a écrit :

Dans mon monde, le problème des bugs, c'est justement qu'on ne s'en aperçoit pas de prime abord. Si mon outil peut m'aider à la prévenir, je l'utilise.


Ouaip... tu m'as convaincu. C'est vrai que je ne connais pas l'ensemble des globales de "stdio.h". Après-tout, on t'a offert un outil, autant l'utiliser. D'ailleurs, je me demande si je ne l'utilise pas moi aussi sans le savoir (comme M. Jourdain). L'option "-Wall" implique-t-elle de facto "-Wshadow" ???


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 16-04-2007 à 15:53:39    

Reply

Marsh Posté le 16-04-2007 à 15:59:34    

"all" ça veut pas dire "tous" ? [:magicbuzz]
 
t'ain le C c'est trop fort :D

Reply

Marsh Posté le 16-04-2007 à 16:20:45    

MagicBuzz a écrit :

"all" ça veut pas dire "tous" ? [:magicbuzz]
 
t'ain le C c'est trop fort :D


 
Tu es dev sur gcc, tu "invente" un nouveau warning et tu release la nouvelle version, les gens mettent à jour et certains utilisaient -Wall , est-ce une bonne idée de leur faire voir apparaitre de nouvelles choses inopinément (ou pire, de casser la compil si ils utilisaient -Werror), le tout pour un warning pas utile à tout le monde que la norme ne demande pas d'afficher ?


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 16-04-2007 à 17:12:40    

à ce moment, tu crées un nouveau flag, et tu n'utilises pas -Wshadow mais -WXshadow (avec X pour "eXtra" )
 
ça s'appelle de la rigueur.


Message édité par MagicBuzz le 16-04-2007 à 17:14:24
Reply

Marsh Posté le 16-04-2007 à 22:59:09    

MagicBuzz a écrit :

"all" ça veut pas dire "tous" ? [:magicbuzz]

 

t'ain le C c'est trop fort :D


Rien à voir avec le C. C'est un problème avec les options d'un certain compilateur. (gcc). -Wall avait un sens à un certain moment du développement de ce compilateur, puis, ceui-ci ayant évolué, d'autres 'flags' (options) sont apparues. On les a alors regroupées sous le nom de -W, puis -Wextra...

 

Ca peut encore évoluer. Ce qui est bien avec gcc, c'est que ça bouge... (on est est à la version 4.3)

 


Message cité 1 fois
Message édité par Emmanuel Delahaye le 16-04-2007 à 23:00:04

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 17-04-2007 à 00:37:16    

0x90 a écrit :

Tu es dev sur gcc, tu "invente" un nouveau warning et tu release la nouvelle version, les gens mettent à jour et certains utilisaient -Wall , est-ce une bonne idée de leur faire voir apparaitre de nouvelles choses inopinément


 
-Wall est en constante évolution ; en raisons de nouveau warning qui a un instant t, sont jugés bénéfiques à un utilisateur moyen, en raisons de warnings qui, progressivement, perdent toutes raisons d'être diagnostiqués, etc.
 

Citation :

(ou pire, de casser la compil si ils utilisaient -Werror)


ça, tout les utilisateurs de GCC savent bien que c'est difficilement utilisable lorsqu'on est amené à utiliser plusieurs versions de GCC.
 
 

Reply

Marsh Posté le 17-04-2007 à 00:43:21    

Emmanuel Delahaye a écrit :

Rien à voir avec le C. C'est un problème avec les options d'un certain compilateur. (gcc). -Wall avait un sens à un certain moment du développement de ce compilateur,


Je crois que l'objectif est de lui faire conserver son sens initial.
 

Emmanuel Delahaye a écrit :

Ca peut encore évoluer. Ce qui est bien avec gcc, c'est que ça bouge... (on est est à la version 4.3)


Côtés Warning, c'est assez actif. Il devrait y avoir pas mal d'améliorations pour 4.3 -- on en est pas encore là, 4.2 a déjà bien du mal à voir le jour.

Reply

Marsh Posté le 21-04-2007 à 19:51:35    

pour en revenir au sujet d'origine et pour répondre a l'auteur : utilise une variable globale !!
 
Il faut etre taré pour passer cette variable comme argument dans toutes les fonctions, d'autant plus que niveau maintenance du code c'est bien merdique quand meme.... alors OUI les variables globales sont a éviter généralement, mais c'est pas une raison pour les éviter a tous prix et dans le cas présent c'est plus que nécessaire...

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed