La différence la plus fondamentale concerne la portée.
Dans le premier cas, vous déclarez une variable globale. Il s'agit d'une variable accessible dans toutes les étendues après sa définition.
void setup()
{
Serial.begin(9600);
}
void inc();
int count = 0;
void loop()
{
Serial.println(count);
count++;
inc();
delay(500);
}
void inc() //Can edit the value of count
{
count=count+1;
};
Dans le second cas, vous déclarez une variable statique avec une portée locale. La variable persistera pour l'ensemble du programme exécuté de la même manière que les variables globales, mais ne sera accessible que dans le bloc de code dans lequel elle est déclarée. Il s'agit du même exemple, avec une seule modification. count
est maintenant déclaré comme une variable statique à l'intérieur loop
.
void inc();
void loop()
{
static int count = 0;
Serial.println(count);
count++;
inc();
delay(500);
}
Cela ne sera pas compilé car la fonction inc()
n'y a pas accès count
.
Les variables globales, bien qu'apparemment utiles, comportent certains écueils. Ceux-ci peuvent même causer des dommages lorsqu'il s'agit d'écrire des programmes qui peuvent interagir avec l'environnement physique. Ceci est un exemple très basique de quelque chose qui est susceptible de se produire, dès que les programmes commencent à s'agrandir. Une fonction peut modifier par inadvertance l'état d'une variable globale.
void setup()
{
Serial.begin(9600);
}
void another_function();
int state=0;
void loop()
{
//Keep toggling the state
Serial.println(state);
delay(250);
state=state?0:1;
//Some unrelated function call
another_function();
}
void another_function()
{
//Inadvertently changes state
state=1;
}
De tels cas sont très difficiles à déboguer. Ce type de problème peut cependant être facilement détecté, simplement en utilisant une variable statique.
void setup()
{
Serial.begin(9600);
}
void another_function();
void loop()
{
static int state=0;
//Keep toggling the state
Serial.println(state);
delay(250);
state=state?0:1;
//Some unrelated function call
another_function();
}
void another_function()
{
//Results in a compile time error. Saves time.
state=1;
}
Les deux variables sont statiques - elles persistent pendant toute la session d'exécution. Le global est visible par n'importe quelle fonction s'il déclare - et non définit - le global, ou si la fonction suit la définition dans la même unité de compilation (fichier + inclut).
Le déplacement de la définition de
count
à l'intérieur d'une fonction à la fois limite son champ de visibilité au jeu d'{}
es englobant le plus proche et lui confère une durée de vie d'invocation de fonction (elle est créée et détruite lorsque la fonction est entrée et sortie). Le déclarer luistatic
donne également la durée de vie de la session d'exécution, il existe du début à la fin de la session d'exécution, persistant à travers les appels de fonction.BTW: soyez prudent sur l'utilisation de la statique initialisée dans une fonction, car j'ai vu certaines versions du compilateur gnu se tromper. Une variable automatique avec un initialiseur doit être créée et initialisée à chaque entrée de fonction. Un statique avec un initialiseur ne doit être initialisé qu'une seule fois, pendant la configuration de l'exécution, avant que main () ne reçoive le contrôle (tout comme le serait un global). J'ai fait réinitialiser la statique locale sur chaque entrée de fonction comme s'il s'agissait d'automatique, ce qui est incorrect. Testez votre propre compilateur pour en être sûr.
la source
extern
?Selon la documentation d'Atmel: "Si une variable globale est déclarée, une adresse unique dans la SRAM sera attribuée à cette variable au moment de la liaison du programme."
La documentation complète est ici (Astuce # 2 pour les variables globales): http://www.atmel.com/images/doc8453.pdf
la source