Melhor resposta
Não confunda um tipo (como int
) com outros aspectos das declarações (por exemplo, uma classe de armazenamento como static
).
Ou seja, em:
int x;
static int y;
x
e y
têm o mesmo tipo, int
(o termo “ tipo de dados ” é menos comumente usado em C e C ++; porém, não está errado).
A palavra-chave static
tem três significados diferentes em C. No exemplo acima, ela indica essa variável y
é “privada” para essa unidade de tradução específica (como unidade de tradução pode ser considerada como um arquivo de origem depois de todas as #include
diretivas foram processados). Portanto, uma variável y
declarada em outra unidade de tradução é diferente desta.
Aqui está um exemplo do segundo significado de static
em C:
void f() {
static int n = 2;
...
}
Isso estático significa que a variável n
é compartilhado entre todas as invocações de f()
e permanece existindo mesmo após f()
retornar (você poderia, por exemplo, retornar um ponteiro para ele). A inicialização de n
para 2
apenas ocorre antes da inicialização do programa em C (na primeira invocação de f()
em C ++). Assim, na segunda (e mais tarde) vez que f()
for invocado, n
manterá qualquer valor que tinha antes (até que o programa o modifique explicitamente novamente ).
O terceiro significado é menos comum (e, eu acho, menos conhecido):
void g(double x[static 5]) {
...
}
Isso indica que g()
só pode ser chamado com um ponteiro para o primeiro de pelo menos 5 double
valores na formação da matriz.
EDITAR: explicação corrigida do local inicialização estática como (veja o comentário de Jesse Pollard).
Resposta
Estático é o oposto de dinâmico. Hã? Isso significa que a memória alocada para essa variável não se move na memória. Isso também significa que em chamadas repetidas para funções que acessam essa variável, novas cópias de sombra da variável não são criadas; a variável original é usada e qualquer outra função que acesse essa variável naquele endereço pode modificá-la ou lê-la. Não é per se uma variável global; seu escopo permanece o mesmo de onde e como foi definido. Pode ser, no entanto. Seria um erro tentar definir outra variável estática com o mesmo nome no mesmo arquivo ou uma incluída em um aplicativo, no entanto.
considere uma função de adição C simples:
int add(int a, int b)
{
static int count = 0;
static int last = 0;
count++;
last = a + b;
printf( "a:\t\%d \t\t b:\t\%d\n", a, b );
printf( "count:\t\%d \t\t last:\t\%d\n", count, last)
return last;
}
contagem e última são definidas como estáticas. Isso significa que os valores colocados neles persistem em várias chamadas para adicionar. count e last são inicializados em zero, mas não zerados novamente a cada chamada. Observe que o escopo de count e last estão apenas dentro da função add. Eles não podem ser compartilhados com outras funções ou acessados fora de add, portanto, para acessá-los, você deve imprimi-los de dentro da função. Outras funções podem ter contagem idêntica e últimos vars estáticos e nunca interagirão.
Agora veja este programa de teste:
#include
static int count = 5;
static int last = 0;
int add(int a, int b)
{
static int count = 0;
static int last = 0;
count++;
last = a + b;
printf( "a:\t\%d \t\t b:\t\%d\n", a, b );
printf( "count:\t\%d \t\t last:\t\%d\n", count, last)
return last;
}
int main(int argc, char**argv )
{
static int count = 10;
static int last = 0;
int i;
int a=1, b=1;
for(i = 0 ; i < count ; i++)
{
a = add(a, b);
b = add(a, last);
last = add(a, b);
}
printf( "a:\t\%d \t\t b:\t\%d\n", a, b );
printf( "count:\t\%d \t\t last:\t\%d\n", count, last);
return 0;
}
Três são 3 conjuntos de variáveis estáticas contam e o último; todos eles são separados. Em primeiro lugar estão os globais, eles nunca são usados aqui. main
tem seu próprio conjunto que usa porque seus vars locais sombreiam os globais. add
tem seu próprio conjunto que sombreia o principal e os globais com o mesmo nome.
Definições de função estática são um tipo diferente de coisa. A palavra estático indica que a função é visível apenas no arquivo compilado da fonte onde a função está definida. Este é o arquivo de origem (“.c”) ou um cabeçalho (“.h) arquivo incluído nele. Isso pode ser necessário se os arquivos objeto que você está usando tiverem mais de uma versão de uma função com o mesmo nome, (como adicionar, imprimir, erro, ...) para que a combinação de arquivos objeto (“. O”) juntos como módulos não causa colisões de nomes.