O que será impresso? 6 6 ou 6 7? E porque?
void foo()
{
static int x = 5;
x++;
printf("%d", x);
}
int main()
{
foo();
foo();
return 0;
}
O que será impresso? 6 6 ou 6 7? E porque?
void foo()
{
static int x = 5;
x++;
printf("%d", x);
}
int main()
{
foo();
foo();
return 0;
}
Respostas:
Existem duas questões aqui, vida útil e escopo.
O escopo da variável é onde o nome da variável pode ser visto. Aqui, x é visível apenas dentro da função foo ().
O tempo de vida de uma variável é o período durante o qual ela existe. Se x fosse definido sem a palavra-chave static, o tempo de vida seria da entrada em foo () até o retorno de foo (); então ele seria reinicializado para 5 em cada chamada.
A palavra-chave static atua para estender o tempo de vida de uma variável para o tempo de vida do programa; por exemplo, a inicialização ocorre apenas uma vez e então a variável retém seu valor - seja lá o que for - em todas as chamadas futuras para foo ().
Produto : 6 7
Motivo : a variável estática é inicializada apenas uma vez (ao contrário da variável automática) e a definição posterior da variável estática seria ignorada durante o tempo de execução. E se não for inicializado manualmente, é inicializado pelo valor 0 automaticamente. Assim,
void foo() {
static int x = 5; // assigns value of 5 only once
x++;
printf("%d", x);
}
int main() {
foo(); // x = 6
foo(); // x = 7
return 0;
}
6 7
o compilador faz com que a inicialização da variável estática não aconteça cada vez que a função é inserida
Isso é o mesmo que ter o seguinte programa:
static int x = 5;
void foo()
{
x++;
printf("%d", x);
}
int main()
{
foo();
foo();
return 0;
}
Tudo o que a palavra-chave estática faz nesse programa é dizer ao compilador (essencialmente) 'ei, eu tenho uma variável aqui que não quero que ninguém mais acesse, não diga a ninguém que ela existe'.
Dentro de um método, a palavra-chave estática diz ao compilador o mesmo que acima, mas também, 'não diga a ninguém que isso existe fora desta função, só deve estar acessível dentro desta função'.
Eu espero que isso ajude
x
no principal; é global. No exemplo original, x
era local para foo, visível apenas enquanto dentro desse bloco, o que geralmente é preferível: se foo existe para manter de x
maneiras previsíveis e visíveis, então deixar que outros cutuquem é geralmente perigoso. Como outro benefício de mantê-lo dentro do escopo, foo()
ele também é foo()
portátil.
c
, portanto, neste contexto, seu exemplo seria ilegal em âmbito global. (C requer inicializadores constantes para globais, C ++ não).
Uma variável estática dentro de uma função tem uma vida útil enquanto seu programa é executado. Ele não será alocado sempre que sua função for chamada e desalocada quando sua função retornar.
A declaração de x
está dentro, foo
mas a x=5
inicialização ocorre fora de foo
!
O que precisamos entender aqui é que
static int x = 5;
não é o mesmo que
static int x;
x = 5;
Outras respostas usaram as palavras importantes aqui, escopo e tempo de vida, e apontaram que o escopo de x
é do ponto de sua declaração na função foo
até o fim da função foo
. Por exemplo, eu verifiquei movendo a declaração para o final da função, e isso torna x
não declarado na x++;
declaração.
Portanto, a parte static int x
(escopo) da instrução realmente se aplica onde você a lê, em algum lugar DENTRO da função e apenas a partir daí, não acima dela dentro da função.
No entanto, a parte x = 5
(vitalícia) da instrução é a inicialização da variável e ocorrendo FORA da função como parte do carregamento do programa. A variável x
nasce com um valor de5
quando o programa é carregado.
Eu li isso em um dos comentários: " Além disso, isso não resolve a parte realmente confusa, que é o fato de que o inicializador é ignorado nas chamadas subsequentes. " Ele é ignorado em todas as chamadas. A inicialização da variável está fora do código de função adequado.
O valor de 5 é teoricamente definido independentemente de foo ser ou não chamado, embora um compilador possa otimizar a função se você não a chamar em qualquer lugar. O valor 5 deve estar na variável antes de foo ser chamado.
Dentro de foo
, a declaraçãostatic int x = 5;
é improvável que gere qualquer código.
Eu descobri o endereço x
usado quando coloquei uma função foo
em um programa meu e então (corretamente) adivinhei que o mesmo local seria usado se eu executasse o programa novamente. A captura de tela parcial abaixo mostra que x
tem o valor 5
mesmo antes da primeira chamada para foo
.
A saída será 6 7
. Uma variável estática (dentro de uma função ou não) é inicializada exatamente uma vez, antes de qualquer função nessa unidade de tradução ser executada. Depois disso, ele mantém seu valor até ser modificado.
Vadiklk,
Por quê ...? A razão é que a variável estática é inicializada apenas uma vez e mantém seu valor em todo o programa. significa que você pode usar a variável estática entre as chamadas de função. também pode ser usado para contar "quantas vezes uma função é chamada"
main()
{
static int var = 5;
printf("%d ",var--);
if(var)
main();
}
e a resposta é 5 4 3 2 1 e não 5 5 5 5 5 5 .... (loop infinito) como você está esperando. novamente, o motivo pelo qual a variável estática é inicializada uma vez, na próxima vez que main () for chamado, ela não será inicializada em 5 porque já foi inicializada no programa. Portanto, podemos alterar o valor, mas não podemos reinicializar. É assim que funciona a variável estática.
ou você pode considerar como por armazenamento: variáveis estáticas são armazenadas na seção de dados de um programa e variáveis que são armazenadas na seção de dados são inicializadas uma vez. e antes da inicialização, eles são mantidos na seção BSS.
Por sua vez, as variáveis Auto (locais) são armazenadas na pilha e todas as variáveis na pilha são reinicializadas o tempo todo quando a função é chamada, pois um novo FAR (registro de ativação da função) é criado para isso.
ok para mais compreensão, faça o exemplo acima sem "estático" e deixe você saber qual será o resultado. Isso faz você entender a diferença entre os dois.
Obrigado Javed
Vamos apenas ler o artigo da Wikipedia sobre variáveis estáticas ...
Variáveis locais estáticas: as variáveis declaradas como estáticas dentro de uma função são alocadas estaticamente, embora tenham o mesmo escopo das variáveis locais automáticas. Portanto, quaisquer valores que a função coloque em suas variáveis locais estáticas durante uma chamada ainda estarão presentes quando a função for chamada novamente.
Você obterá 6 7 impresso como, como é facilmente testado, e aqui está o motivo: Quando foo
é chamada pela primeira vez, a variável estática x é inicializada para 5. Em seguida, é incrementada para 6 e impressa.
Agora para a próxima chamada para foo
. O programa pula a inicialização da variável estática e, em vez disso, usa o valor 6 que foi atribuído ax da última vez. A execução prossegue normalmente, fornecendo o valor 7.
6 e 7 Como a variável estática inicializa apenas uma vez, So 5 ++ torna-se 6 na 1ª chamada 6 ++ torna-se 7 na 2ª chamada Nota - quando ocorre a 2ª chamada, o valor de x é 6 em vez de 5 porque x é a variável estática.
No C ++ 11, pelo menos, quando a expressão usada para inicializar uma variável estática local não é um 'constexpr' (não pode ser avaliada pelo compilador), então a inicialização deve acontecer durante a primeira chamada para a função. O exemplo mais simples é usar diretamente um parâmetro para inicializar a variável estática local. Portanto, o compilador deve emitir código para adivinhar se a chamada é a primeira ou não, o que, por sua vez, requer uma variável booleana local. Compilei esse exemplo e verifiquei se isso é verdade, vendo o código do assembly. O exemplo pode ser assim:
void f( int p )
{
static const int first_p = p ;
cout << "first p == " << p << endl ;
}
void main()
{
f(1); f(2); f(3);
}
é claro, quando a expressão é 'constexpr', então isso não é necessário e a variável pode ser inicializada no carregamento do programa usando um valor armazenado pelo compilador no código assembly de saída.