La diferencia más básica es de alcance.
En el primer caso, estás declarando una variable global. Es una variable accesible en todos los ámbitos después de su definición.
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;
};
En el segundo caso, está declarando una variable estática con alcance local. La variable persistirá para todo el programa ejecutado de manera similar a las variables globales, pero será accesible solo en el bloque de código en el que se declara. Este es el mismo ejemplo, con solo un cambio. count
ahora se declara como una variable estática dentro loop
.
void inc();
void loop()
{
static int count = 0;
Serial.println(count);
count++;
inc();
delay(500);
}
Esto no se compilará ya que la función inc()
no tiene acceso count
.
Las variables globales, aunque aparentemente útiles, vienen con algunas trampas. Incluso pueden causar daños cuando se trata de escribir programas que puedan interactuar con el entorno físico. Este es un ejemplo muy básico de algo que es probable que suceda, tan pronto como los programas comiencen a crecer. Una función puede cambiar inadvertidamente el estado de una variable global.
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;
}
Tales casos son muy difíciles de depurar. Sin embargo, este tipo de problema se puede detectar fácilmente, simplemente usando una variable estática.
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;
}
Ambas variables son estáticas: persisten durante toda la sesión de ejecución. El global es visible para cualquier función si declara, no define, el global, o si la función sigue la definición en la misma unidad de compilación (archivo + incluye).
Mover la definición de
count
dentro de una función limita su alcance de visibilidad al conjunto de{}
es circundantes más cercano y le otorga una vida útil de invocación de función (se crea y destruye a medida que se ingresa y sale de la función). Declararlostatic
también le da una duración de la sesión de ejecución que existe desde el principio hasta el final de la sesión de ejecución, persistiendo en las invocaciones de funciones.Por cierto: tenga cuidado con el uso de estadísticas inicializadas dentro de una función, ya que he visto que algunas versiones del compilador gnu se equivocan. Se debe crear e inicializar una variable automática con un inicializador en cada entrada de función. Una estática con un inicializador solo debe inicializarse una vez, durante la configuración de la ejecución, antes de que main () tenga el control (tal como lo haría un global). He reiniciado las estadísticas locales en cada entrada de función como si fueran automáticas, lo cual es incorrecto. Prueba tu propio compilador para estar seguro.
fuente
extern
?Según la documentación de Atmel: "Si se declara una variable global, se asignará una dirección única en la SRAM a esta variable en el momento del enlace del programa".
La documentación completa está aquí (Consejo # 2 para variables globales): http://www.atmel.com/images/doc8453.pdf
fuente