Programar em C/Mais sobre variáveis: diferenças entre revisões

[edição verificada][edição não verificada]
Conteúdo apagado Conteúdo adicionado
Abacaxi (discussão | contribs)
Linha 186:
}
</source>
 
==Especificadores de Classe de Armazenamento==
 
<b>auto:</b> O especificador de classe de armazenamento auto define variáveis automáticas, isto é, variáveis locais. Raramente usado pois todas as variáveis locais do C são auto por definição. <br>
<b>static:</b> O funcionamento das variáveis declaradas como static depende se estas são globais ou locais.
Variáveis globais static funcionam como variáveis globais dentro de um módulo, ou seja, são variáveis globais que não são conhecidas em outros modulos. Isto é util se quisermos isolar pedaços de um programa para evitar mudanças acidentais em variáveis globais.<br>
<b>Exemplo:</b>
 
<source lang="C">
 
 
#include <stdio.h>
void f(void)
{
static int i = 0; /* só sera inicializada a 0 na primeira chamada de f */
int j = 0; /* j sera inicializada a cada vez */;
i++;
j++;
printf("i vale %d e j vale %d.\n", i, j);
}
int main(void)
{
f();
f();
f();
return 0;
}
</source>
resultado da execução do código:
 
i vale 1 e j vale 1.
i vale 2 e j vale 1.
i vale 3 e j vale 1.
 
 
<b>extern</b> :Define variáveis que serão usadas em um arquivo apesar de terem sido declaradas em outro.Todas as variáveis e funções globais que não são definidas como static são extern por omissão.<br>
 
<b>register</b>:Essa classe indica que a variável deve ser estocada em um registro do processador.Isso permite um ganho de tempo comparado a variáveis estocada na memoria viva que sao executadas com menos rapidez.O numero de registros do processador é limitado então é inútil definir toda uma estrutura com a classe register.<br>
As variáveis estocadas dentro de um registro são obrigatoriamente local não podemos definir variáveis globais.
<source lang="C">
#include <stdio.h>
int main(void)
{
register short i, j;
for (i = 1; i < 1000; ++i)
{
for(j = 1; j < 1000; ++j)
{
printf("\n %d %d", i, j);
}
}
system("pause");
return 0;
}
</source>
 
<b>auto</b>: Essa classe é uma herança da linguagem B. Ela serve para indicar que as variáveis locais de uma função não são estáticas. Mas na linguagem C quando uma variável local não usa o especificador static é automatic essa palavra reservada é inútil .
 
== Atributos das variáveis ==
Linha 231 ⟶ 291:
 
Um uso importante de variáveis <tt>volatile</tt> é em aplicações com várias ''threads'' (linhas de execução), onde a memória é compartilhada por vários pedaços de código que são executados simultaneamente.
===restrict===
 
Introduzido no C99.Com esse atributo o programador afirma ao compilador que um ponteiro é o único a apontar para uma determinada área da memoria.
=== extern ===
 
O modificador '''<tt>extern</tt>''' diz ao compilador que a variável indicada foi declarada em outro arquivo que não podemos incluir diretamente, por exemplo o código de uma biblioteca padrão. Isso é importante pois, se não colocarmos o modificador '''extern''', o compilador irá declarar uma nova variável com o nome especificado, "ocultando" a variável que realmente desejamos usar. E se simplesmente não declarássemos a variável, já sabemos que o compilador não saberia o tamanho da variável.
 
Quando o compilador encontra o modificador '''extern''', ele marca a variável como não resolvida, e o montador se encarregará de substituir o endereço correto da variável.
 
extern float sum;
extern int count;
float returnSum (void)
{
count++;
return sum;
}
 
Neste exemplo, o compilador irá saber que <var>count</var> e <var>sum</var> estão sendo usados no arquivo mas que foram declarados em outro.
 
Uma variável externa frequentemente usada é a variável <var>errno</var> (declarada no arquivo-cabeçalho errno.h), que indica o último código de erro encontrado na execução de uma função da biblioteca padrão ou do sistema.
 
=== static ===
 
O funcionamento das variáveis declaradas como '''<tt>static</tt>''' depende de se estas são globais ou locais.
 
* Variáveis globais <tt>static</tt> funcionam como variáveis globais dentro de um módulo, ou seja, são variáveis globais que não são (e nem podem ser) conhecidas em outros módulos (arquivos). Isto é util se quisermos isolar pedaços de um programa para evitar mudanças acidentais em variáveis globais. Isso é um tipo de ''encapsulamento'' &mdash; que é, simplificadamente, o ato de não permitir que uma variável seja modificada diretamente, mas apenas por meio de uma função.
* Variáveis locais estáticas são variáveis cujo valor é mantido de uma chamada da função para a outra. Veja o exemplo:
 
int count (void)
{
static int num = 0;
num++;
return num;
}
 
A função count() retorna o número de vezes que ela já foi chamada. Veja que a variável local int é inicializada. Esta inicialização só vale para a primeira vez que a função é chamada pois num deve manter o seu valor de uma chamada para a outra. O que a função faz é incrementar num a cada chamada e retornar o seu valor. A melhor maneira de se entender esta variável local static é implementando. Veja por si mesmo, executando seu próprio programa que use este conceito.
 
=== register ===
 
O computador pode guardar dados na memória (RAM) e nos registradores internos do processador. As variáveis (assim como o programa como um todo) costumam ser armazenadas na memória. O modificador <tt>register</tt> diz ao compilador que a variável em questão deve ser, se possível, guardada em um registrador da CPU.
 
Vamos agora ressaltar vários pontos importantes:
 
* '''Porque usar <tt>register?</tt>''' Variáveis nos registradores da CPU vão ser acessadas em um tempo muito menor pois os registradores são muito mais rápidos que a memória. No entanto, a maioria dos compiladores otimizantes atuais usa registradores da CPU para variáveis, então o uso de <tt>register</tt> é freqüentemente desnecessário.
* '''Em que tipo de variável podemos usar o <tt>register</tt>?''' Antes da criação do padrão ANSI C, <tt>register</tt> aplicava-se apenas aos tipos <tt>int</tt> e <tt>char</tt>, mas o padrão atual permite o uso de <tt>register</tt> para qualquer um dos quatro tipos fundamentais. É claro que seqüências de caracteres, arrays e estruturas também não podem ser guardadas nos registradores da CPU por serem grandes demais.
* '''<tt>register</tt> é um ''pedido'' que o programador faz ao compilador.''' Este não precisa ser atendido necessariamente, e alguns compiladores até ignoram o modificador ''register'', o que é permitido pelo padrão C.
* '''<tt>register</tt> não pode ser usado em variáveis globais''', pois isto implicaria em um registrador da CPU ficar o tempo todo ocupado por essa variável.
 
Um exemplo do uso do register é dado a seguir:
 
int main (void)
{
register int count;
for (count = 0; count < 10; count++)
{
...
}
return 0;
}
 
O loop acima, em compiladores que não guardam variáveis em registradores por padrão, deve ser executado mais rapidamente do que seria se não usássemos o ''register''. Este é o uso mais recomendável para o ''register'': uma variável que será usada muitas vezes em seguida.
 
{{Esboço/Informática}}