variable scope

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
case
Messages : 1546
Inscription : lun. 10/sept./2007 11:13

variable scope

Message par case »

salut, juste une question est-ce le fonctionnement attendu ?
j'ai besoin d'avoir une variable globale pour ce que je veux faire mais je dois la modifier dans des procédures
il me semblait que le code suivant était possible

Code : Tout sélectionner

Global mavar
Procedure dec()
  mavar =mavar-1
  Debug mavar
EndProcedure
Procedure dostuff(mavar)
Repeat 
    dec()   
  Debug mavar
Until mavar =0
EndProcedure
dostuff(80)
mais ca me crée une variable locale et une globale avec le meme nom oO

du coup je fais comme ça

Code : Tout sélectionner

Global mavar
Procedure dec()
  mavar =mavar-1
  Debug mavar
EndProcedure
Procedure dostuff(variab)
  mavar=variab
Repeat 
    dec()   
  Debug mavar
Until mavar =0
EndProcedure
dostuff(80)
ImageImage
Avatar de l’utilisateur
Zorro
Messages : 2186
Inscription : mar. 31/mai/2016 9:06

Re: variable scope

Message par Zorro »

en fait il faut utiliser ProcedureReturn dans ton cas !!
car tu fait appel a une procedure sans parametre !! ( dec() )
donc tout ce qui se trouve dedans est local , meme si ça a le meme nom qu'une variable global !

il te faut donc ressortir cette variable .. pour la "globaliser" en quelque sorte

comme ceci :

Code : Tout sélectionner


Declare dec()
Declare dostuff(mavar)

Global mavar=80


calldebugger

dostuff(mavar)


Procedure dec()		
		mavar =mavar-1		
		ProcedureReturn mavar ; <<<<< ici on "delocalise" la variable en la ressortant de la procedure
EndProcedure

Procedure dostuff(mavar)		
		Repeat
				 mavar=dec()   ; <<<<<< ici on recupere la variable ressortie
				Debug mavar
		Until mavar =0
EndProcedure
Avatar de l’utilisateur
case
Messages : 1546
Inscription : lun. 10/sept./2007 11:13

Re: variable scope

Message par case »

ca semble normal donc
que si j'ai une variable globale toto je ne puisse pas y acceder dans une procedure
procedure test(toto)

Code : Tout sélectionner

Global toto.s="zorro plus zorro"

Procedure test(toto.s)
  Debug toto
  toto="la tete a toto"
  Debug toto
EndProcedure

Debug toto
test(toto)
Debug toto
je pensais qu'une variable globale était entre guillemet prioritaire sur une locale :)
mais je me trompais

d'un autre coté cela peut se comprendre comme garde fou.

et non je peux pas utiliser la syntaxe
mavar=test(mavar)
dans ce cas car j'ai déjà d'autre retours je voulais me simplifier un peu l’existence mais c'est pas dramatique ^^
ImageImage
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: variable scope

Message par falsam »

Code : Tout sélectionner

Procedure test(toto.s)
La variable toto.s en paramètre de ta procédure sera private et interne à ta procédure.

Dans ce cas tu traites le passage de paramètre de cette manière.

Code : Tout sélectionner

Global toto.s="zorro plus zorro"

Procedure test(buffer.s)
  Debug toto
  toto=buffer
  Debug toto
EndProcedure

Debug toto
test("la tete à toto")
Debug toto
La variable toto est bien globale.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: variable scope

Message par falsam »

Et effectivement ce que tu fais avec ce code présent dans le premier message et la bonne façon de coder.

Code : Tout sélectionner

Global mavar
Procedure dec()
  mavar =mavar-1
  Debug mavar
EndProcedure
Procedure dostuff(variab)
  mavar=variab
Repeat 
    dec()   
  Debug mavar
Until mavar =0
EndProcedure
dostuff(80)
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Mesa
Messages : 1126
Inscription : mer. 14/sept./2011 16:59

Re: variable scope

Message par Mesa »

On peut aussi utiliser les pointeurs:

Code : Tout sélectionner

; Global x
; Define.i x
; Note: Par défaut, une variable non déclarée est une variable de type INTEGER.

Procedure dec(*mavar.INTEGER)
  
  *mavar\i =*mavar\i-1
  ; 	Debug *mavar\i
EndProcedure

Procedure dostuff(*mavar.INTEGER)
  
  Repeat 
    dec(*mavar.INTEGER)   
    Debug *mavar\i
    ; 		Delay(500)
  Until *mavar\i =0
EndProcedure

x=80
dostuff(@x)
Il y a peut-être une façon de faire aussi avec le mot clé STATIC (?)

[Edit] Oups,Non, pas STATIC, Je voulais dire SHARED
M.
Dernière modification par Mesa le sam. 01/juil./2017 10:53, modifié 1 fois.
Avatar de l’utilisateur
Zorro
Messages : 2186
Inscription : mar. 31/mai/2016 9:06

Re: variable scope

Message par Zorro »

Je pense que Case a raison , il y a un probleme !!!


exemple :

Code : Tout sélectionner



Declare proc()
calldebugger

Global variable_global=10

debug  variable_global
proc() ; appel de la procedure

debug  variable_global ; ne devrai pas etre a 0 !!!!!


Procedure proc()
variable_global=0 ; variable implicitement local a la procedure
debug  "local a la procedure = "+ str(variable_global)
EndProcedure

au retour de la procedure, la variable "variable_global" ne devrai pas etre a 0 !!!

car la copie de "variable_global" dans la procedure, est Local a la procedure !!
pour que la valeur fut changé dans la procedure et transmise a la variable clone en dehors de la procedure
il aurai fallu que j'utilisasse "Shared" , hors ici, que neni, point de shared
donc la variable "variable_global" dans la procedure, ne devrai pas etre confondu avec la variable "variable_global" se trouvant en dehors !!!

pour moi , c'est un bug !!
Avatar de l’utilisateur
Zorro
Messages : 2186
Inscription : mar. 31/mai/2016 9:06

Re: variable scope

Message par Zorro »

ha non quel ane !!

il faut ajouter "Protected" !!!

Code : Tout sélectionner



Declare proc()
calldebugger

Global variable_global=10

debug  variable_global
proc() ; appel de la procedure

debug  variable_global ; ne devrai pas etre a 0 !!!!!


Procedure proc()
	Protected	variable_global=0 ; variable  local a la procedure grace a Protected !!
		debug  "local a la procedure = "+ str(variable_global)
EndProcedure
Marc56
Messages : 2198
Inscription : sam. 08/févr./2014 15:19

Re: variable scope

Message par Marc56 »

Pour mémoire, car on oublie à nos ages 8)
Les 4 formes de déclarations de variables (voir les exemples)

Global (partout)
Protected (locale à la procédure)
Static (protected qui reste entre chaque appel)
Shared

Les deux premières sont les plus utilisées.

:idea: Par habitude on déclare les variables globales en tête de code, mais il est possible de les déclarer depuis l’intérieur des procédures.
:arrow: C'est intéressant par exemple pour des flags si ceux-ci ne sont utilisés que dans certains cas.

:wink:
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: variable scope

Message par djes »

Ces petits rappels sont utiles... Falsam a parfaitement expliqué le problème de case, un paramètre de procédure est toujours local.

C'est vrai que c'est une source d'erreur et de confusion, l'une des ces petites choses du BASIC qui, en plus, sont difficiles à gérer pour le compilateur ! Une variable globale, c'est juste un peu d'espace mémoire bien défini ; un paramètre, ça peut être un registre, quand il en reste, pour aller plus vite, un espace sur la pile, et là, attention aux dépassements... Avec le source en assembleur, on voit très bien la différence, et la difficulté du truc.
Marc56
Messages : 2198
Inscription : sam. 08/févr./2014 15:19

Re: variable scope

Message par Marc56 »

Cela dit, j'ai du mal à comprendre même en lançant les exemples l’utilité de Shared ?
(à priori cela fait la même chose que de déclarer une globale depuis l'intérieur d'une procédure ?)

:?:
Avatar de l’utilisateur
Zorro
Messages : 2186
Inscription : mar. 31/mai/2016 9:06

Re: variable scope

Message par Zorro »

djes a écrit :l'une des ces petites choses du BASIC .
non, de PureBasic !!

car en basic "traditionnel" une variable dans une procedure, meme si elle porte le meme nom qu'une variable Global
reste local a la procedure !

elle n’interfère jamais avec son homonyme ...

d'ailleurs je ne comprends pas vraiment pourquoi c'est different avec Purebasic, et qu'il faille utiliser "Protected" pour retrouver le comportement
"normal" d'un basic .. mais bon , il doit y avoir une raison :)


@Marc : Shared permet de partager une variable declaré dans une procedure , un partage seulement, pas un changement de statut ... :)
Mesa
Messages : 1126
Inscription : mer. 14/sept./2011 16:59

Re: variable scope

Message par Mesa »

Marc56 a écrit :Cela dit, j'ai du mal à comprendre même en lançant les exemples l’utilité de Shared ?
(à priori cela fait la même chose que de déclarer une globale depuis l'intérieur d'une procédure ?)

:?:
Apparement, il y a un bug dans la doc. Je vais changer la doc.

La doc dit que Shared permet de rendre une variable non global accessible depuis une procédure.
En fait, ça marche qu'elle soit globale ou non et même si elle n'est pas déclarée avant d'être shared sauf dans ton cas ! ! !


Code : Tout sélectionner

Global mavar = 80 ; Marche
; mavar = 80 ; marche pas
; si les 2 sont commentées, ça ne marche pas non plus

Procedure dec()
	mavar =mavar-1
	Debug mavar
EndProcedure
Procedure dostuff(mavar2)
  Shared mavar
  mavar = mavar2
Repeat 
		dec()   
	Debug mavar
Until mavar =0
EndProcedure
dostuff(80)

Debug mavar
Par contre :

Code : Tout sélectionner

Global mavar = 10 ; Marche
; mavar = 10 ; marche aussi
 
Procedure Change()
;   Debug a ; interdit car le compilo  crée une variable locale
  Shared a
  Debug a ; =10
    a = 20 
  EndProcedure 
  

  Change()
  Debug a   ; =20

Code : Tout sélectionner

; si les 2 sont commentées, ça marche  aussi
Procedure Change()
;   Debug a ; interdit car le compilo  crée une variable locale
  Shared a ; La variable n'existe pas alors elle est créee et partagée
  Debug a ; = 0
    a = 20 
  EndProcedure 
  

  Change()
  Debug a   ; =20
M.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: variable scope

Message par djes »

Zorro a écrit :
djes a écrit :l'une des ces petites choses du BASIC .
non, de PureBasic !!

car en basic "traditionnel" une variable dans une procedure, meme si elle porte le meme nom qu'une variable Global
reste local a la procedure !

elle n’interfère jamais avec son homonyme ...

d'ailleurs je ne comprends pas vraiment pourquoi c'est different avec Purebasic, et qu'il faille utiliser "Protected" pour retrouver le comportement
"normal" d'un basic .. mais bon , il doit y avoir une raison :)


@Marc : Shared permet de partager une variable declaré dans une procedure , un partage seulement, pas un changement de statut ... :)
Oui, je n'aurais pas dû faire de généralités, même s'il n'y a pas de BASIC «traditionnel» comme tu le dis, et que je n'ai pas le courage d'aller voir les quelques versions normalisées ANSI et autres pour te contredire :wink:
Je rappelle quand même pour faire avancer le schmilblick qu'il ne s'agit pas de variables, mais de paramètres. Ce n'est pas tout à fait la même chose, perso je fais la distinction et je vous encourage à le faire, même si ça ne va pas changer le monde...
Avatar de l’utilisateur
Zorro
Messages : 2186
Inscription : mar. 31/mai/2016 9:06

Re: variable scope

Message par Zorro »

djes a écrit :Oui, je n'aurais pas dû faire de généralités, même s'il n'y a pas de BASIC «traditionnel» comme tu le dis,
c'est pourquoi j'ai mis entre guillemets !
Je rappelle quand même pour faire avancer le schmilblick qu'il ne s'agit pas de variables, mais de paramètres. Ce n'est pas tout à fait la même chose, perso je fais la distinction et je vous encourage à le faire, même si ça ne va pas changer le monde...
on parle bien de variables ... qui se trouve dans la procedure ...
le parametres c'est une variable qu'on passe en parametre (par les parentheses) de la fonction ... on va pas jouer sur les mots ..


et que je n'ai pas le courage d'aller voir les quelques versions normalisées ANSI et autres pour te contredire :wink:
ben j'ai recherché pour toi

en VisualBasic
1.2 Portée des variables
L’existence d’une variable peut se dérouler sur trois niveaux :
Niveau Procédure : cela veut dire que la variable est locale. Dès que l’on quitte la procédure en question, la variable disparaît, et son contenu avec elle.
en GFABAsic , il fallait preciser qu'une variable etait Local , avec la directive "Local"

exemple : (ici en GFABasic 32 bits )

Code : Tout sélectionner

Proc WndProc(hWnd As Handle, msg As Int, _
  wParam As Int, lParam As Int) Naked
  Local RetVal
  '... Code ...
  Asm mov eax, [RetVal]
EndProc
en BlitzBasic 3D
les variable dans les procedures sont automatiquement en Local exemple :

Code : Tout sélectionner

function Machin()
  var#=9.0
end function
print Var => affichera '0.0'
en DarkBasic Pro , page 31 du manuel il est ecrit
Les variables et tableau sont idépendants du reste du programme
Ainsi, une variable FRED dans une fonction n'affectera pas une autre variable FRED
qui serai déclaré dans le programme principal ni
qui serai déclarée dans une autre fonction .....
en OMIKRON Basic
On peut définir des variables locales par LOCAL V$=, W$=, qui n'interféreront pas avec les variables globales de même nom,
je ne parlerai bien sur pas des anciens basic, qui ne geraient pas le concept de fonctions (procedures)
je pense au ZX81 Basic (basic Spaghettis a base de Goto )

mais pour ma part mis a part quelques uns (rare) ou il faut preciser qu'une variable est Local dans une procedure (GFA Basic , L'Omikron ; et d'une certaine façon le Purebasic avec son "Protected" )
la plupart considerent que c'est Local par defaut lorsque c'est dans une procedure ou une fonction .....
mais dans tout les cas, une variable Local, n’interfère pas avec son homonyme Global !!
Répondre