algumas notas de computação e tecnologia
Classes de armazenamento em C
Recentemente precisei pesquisar sobre funções do tipo static em C, que são funções acessíveis exclusivamente de dentro do arquivo onde foram declaradas (algo próximo ao private no Java). Pesquisando, encontrei também textos sobre Storage Class (classes de armazenamento), algo que achei bem interessante e por isso decidi compartilhar com vocês!
Na linguagem C, quando criamos uma variável ou uma função, podemos indicar a sua classe de armazenamento (Storage Classes), que define como e onde esta variável e/ou função será gravada e acessada na memória do computador.
As classes de armazenamento disponíveis são:
- auto
- extern
- register
- static
Vamos ver um pouco sobre cada uma delas.
auto
Esta é a classe de armazenamento padrão das variáveis locais (isto é, ela só pode ser utilizada dentro de funções). Por exemplo:
void exemplo()
{
int tamanho;
auto int vezes;
}
As duas variáveis acima possuem a classe de armazenamento auto e são visíveis apenas dentro da função exemplo(). Elas serão alocadas quando a função for chamada e suas áreas de memória serão liberadas no fim da função (ou quando o return for chamado).
extern
Esta classe de armazenamento indica que queremos referenciar uma variável e/ou função definida em algum outro arquivo do projeto. Ela não aloca nada na memória, apenas aponta para a variável/função definida com o mesmo nome em algum outro arquivo visível do projeto. Por exemplo:
Arquivo: imprimir.c
extern int contador;
void imprimir()
{
printf("Contador vale: %d\n", contador);
}
Arquivo: main.c
int contador = 10;
void main()
{
imprimir();
}
O arquivo main.c define a variável contador, que é utilizada dentro do arquivo imprimir.c, que faz referência a ela através do extern. Ao compilarmos este programa, por exemplo, usando o GCC: gcc imprimir.c main.c -o programa.exe, e o executarmos, a saída será:
Contador vale: 10
register
Esta classe define que desejamos que nossa variável seja alocada dentro de um registrador, ao invés de na memória RAM, como de costume.
Um registrador é um espaço de memória situado dentro do processador. Ele é pequeno, extremamente rápido e é comumente utilizado para alocar variáveis que terão muito acesso durante um processamento. Isto significa que o tamanho da variável dependerá do tamanho do registrador, o que varia de acordo com a arquitetura do processador.
É importante notar que, estando uma variável alocada no registrador da máquina, não é possível utilizar o operador ‘&’ nesta variável (este operador retorna o endereço de memória onde uma variável está alocada), já que a variável não está na memória e sim no registrador. Isto é, o seguinte código não faz sentido:
void main()
{
register int idade;
printf("Digite sua idade: ");
scanf("%d", &idade);
printf("Sua idade é: %d\n", idade);
}
Outra coisa importante é que: quando declaramos uma variável como register, indicamos a nossa vontade de que ela seja alocada em um registrador, porém ela não necessariamente o será, dependendo isto da implementação e do hardware.
static
Esta é a classe de armazenamento padrão para variáveis globais. Variáveis da classe static são inicializadas no carregamento do programa e são visíveis de qualquer função presente no mesmo arquivo de sua declaração. Vejamos um exemplo:
Arquivo main.c
void imprimir();
int chamadas = 5;
void main()
{
for(; chamadas > 0; chamadas--)
imprimir();
}
void imprimir()
{
static int contador = 0;
contador++;
printf("Contador vale: %d e chamadas vale: %d\n", contador, chamadas);
}
A variável chamadas é da classe static (padrão para globais) e é visível de qualquer função do arquivo. A variável contador, dentro da função imprimir(), é do tipo static, portanto é inicializada (valendo zero) no carregamento do programa e é visível apenas dentro da função onde foi declarada. A saída deste programa será:
Contador vale: 1 e chamadas vale: 5 Contador vale: 2 e chamadas vale: 4 Contador vale: 3 e chamadas vale: 3 Contador vale: 4 e chamadas vale: 2 Contador vale: 5 e chamadas vale: 1
É importante sempre inicializar as variáveis da classe static com constantes!
Outro uso importante da classe static:
char *gera_texto();
void main()
{
char *texto1;
texto1 = gera_texto();
}
char *gera_texto()
{
char texto2[10] = "algum texto";
return(texto2);
}
A variável texto1 receberá a referência para a área antes referenciada pela variável texto2. Como a variável texto2 é local, ao sair da função gera_texto() sua área de memória será liberada para uso, podendo ser sobrescrita a qualquer momento pelo programa. Uma forma de resolver este problema é declarar a variável texto2 como static:
static char texto2[10] = "algum texto";
Desta forma esta área de memória será alocada na inicialização do programa e ficará lá até o fim de sua execução.
Referências
| Imprimir artigo | Este artigo foi escrito por Thiago Carvalho em 17 de maio de 2010 às 14h25min, e está arquivado em C, Programação. Siga quaisquer respostas a este artigo através do RSS 2.0. Você pode deixar uma resposta ou fazer um trackback do seu próprio site. |