A diferença mais básica é de escopo.
No primeiro caso, você está declarando uma variável global. É uma variável que é acessível em todos os escopos após sua definição.
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;
};
No segundo caso, você está declarando uma variável estática com escopo local. A variável persistirá para que o programa inteiro seja executado de maneira semelhante às variáveis globais, mas estará acessível apenas no bloco de código em que está declarado. Este é o mesmo exemplo, com apenas uma alteração. count
agora é declarado como uma variável estática dentro loop
.
void inc();
void loop()
{
static int count = 0;
Serial.println(count);
count++;
inc();
delay(500);
}
Isso não será compilado, pois a função inc()
não tem acesso count
.
As variáveis globais, por mais úteis que sejam, vêm com algumas armadilhas. Eles podem até causar danos quando se trata de escrever programas que podem interagir com o ambiente físico. Este é um exemplo muito básico de algo que provavelmente acontecerá, assim que os programas começarem a ficar maiores. Uma função pode alterar inadvertidamente o estado de uma variável 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;
}
Esses casos são muito difíceis de depurar. Esse tipo de problema, no entanto, pode ser facilmente detectado, simplesmente usando uma variável 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 as variáveis são estáticas - elas persistem por toda a sessão de execução. O global é visível para qualquer função se declarar - não define - o global, ou se a função seguir a definição na mesma unidade de compilação (arquivo + inclui).
Mover a definição de
count
para dentro de uma função limita seu escopo de visibilidade ao conjunto de{}
es envolvente mais próximo e fornece a vida útil da chamada de função (ela é criada e destruída à medida que a função é inserida e encerrada). A declaraçãostatic
também fornece a vida útil da sessão de execução, que existe desde o início até o final da sessão de execução, persistindo nas invocações de funções.BTW: tenha cuidado ao usar estática inicializada em uma função, como já vi algumas versões do compilador gnu entenderem isso errado. Uma variável automática com um inicializador deve ser criada e inicializada em cada entrada de função. Uma estática com um inicializador deve ser inicializada apenas uma vez, durante a configuração de execução, antes que main () tenha controle (da mesma forma que uma global seria). Eu tive a estatística local sendo reinicializada em cada entrada de função como se fossem automáticas, o que está incorreto. Teste seu próprio compilador para ter certeza.
fonte
extern
?De acordo com a documentação da Atmel: "Se uma variável global for declarada, um endereço exclusivo na SRAM será atribuído a essa variável no momento do link do programa".
A documentação completa está aqui (Dica nº 2 para variáveis globais): http://www.atmel.com/images/doc8453.pdf
fonte