Acesso de variável estática de um arquivo para outro arquivo
-
20-12-2019 - |
Pergunta
Recentemente me deparei com a questão de como acessar uma variável declarada estática no arquivo1.c para outro arquivo2.c?
É possível acessar variável estática?
Meu entendimento sobre palavras-chave estáticas em C é,
static
é "ligação interna", portanto são acessíveis apenas a partir de uma unidade de compilação - aquela onde foram definidos.Os objetos declarados com ligação interna são privados para um único módulo.
Como um dos meus amigos me sugeriu a solução abaixo.
Em file1.c
#include <stdio.h>
int main()
{
int b=foo();
printf("%d",b);
return 0;
}
em file2.c
static int a=25;
int foo()
{
return a;
}
compilado por gcc file1.c file2.c -o file
Se eu fizer acima, posso acessar a variável.
Então minhas perguntas são:
O programa acima viola regras de variáveis estáticas?
Se não, por que isso acontece e existe alguma outra maneira de acessar a variável estática, exceto incluindo o arquivo (
#include <…>
) Assim não.Como posso acessar uma variável estática de outro arquivo?
Em C, como faço para restringir o escopo de uma variável global ao arquivo em que ela é declarada?
Corrija-me se estiver errado com o conceito de variável estática e se houver soluções melhores disponíveis para acessar a variável estática?
Solução
1) o programa acima viola regras de variáveis estáticas?
Não, você não está violando nenhuma regra.Aqui a função foo cria uma cópia do valor daquela variável estática e usada em outro arquivo.Está bem.
2) Se não, por que isso acontece, e existe alguma outra maneira de acessar uma variável estática, exceto incluindo o arquivo (#include<>), não assim. Como posso acessar uma variável estática de outro arquivo?
Variáveis estáticas devem ser usadas apenas nesse arquivo.
Você não pode usar essa variável tornando-as externas em outros arquivos.
Outro truque sujo é obter o ponteiro dessa variável estática e torná-la um ponteiro global e torná-la externa em outro arquivo, você pode usar essa variável estática.
arquivo1.c
#include<stdio.h>
static int a=25;
int* ptr = &a;
arquivo2.c
#include<stdio.h>
extern int *ptr;
int main()
{
printf("%d",*ptr);
return 0;
}
Corrija-me se estiver errado com o conceito de variável estática e se houver soluções melhores disponíveis?
Uma variável estática tem um tempo de vida que se estende por toda a execução do programa
Se você não inicializar a variável estática com algum valor, seu valor padrão será 0.
Uma variável estática tem escopo limitado apenas ao seu arquivo.Você não pode acessá-lo pelo nome de um arquivo diferente.
Você tem temp1.c e temp2.c sendo compilados juntos, então você também pode ter variáveis estáticas de mesmo nome em ambos os arquivos - e elas são variáveis separadas.
Em C, como faço para restringir o escopo de uma variável global ao arquivo em que ela é declarada?
Tornando essa variável global estática.
Outras dicas
O que comumente chamamos de variável em C é na verdade duas coisas:um objeto, a memória alocada para a variável interpretada com um determinado tipo e um identificador, uma maneira de acessar esse objeto.
Não há problema em acessar um static
objeto ou seu valor de outra unidade de compilação.Sua função foo
promove o valor para outra unidade, tudo bem, mas pode até promover o endereço de a
sem problemas.
Ter ligação interna diz respeito apenas ao identificador, ao nome a
.Este só é visível dentro file2.c
.
Com o static int a=25;
a variável a
terá vínculo interno;o que significa que o vinculador não pode ver a
em qualquer lugar fora do file2.c
TU.
Quando você está ligando foo()
em file2.c
, você recebe uma cópia de a
, é a cópia que você imprime;mas isso não significa que você tenha acesso ao real a
definido em file2.c
Quando você precisar de um acesso onde a mesma variável seja visível em diferentes TUs, você poderá fazer isso
Definindo arquivo
Este arquivo declara e define a variável;além disso, inicializa-o também com 1, sem o qual será inicializado por padrão com 0.
// (non-static) global variable with external linkage and thus visible across TUs
int var_across = 0;
void use()
{
var_across = 1;
}
Usando arquivo
// just a declaration to tell that it's defined elsewhere; not a definition
extern int var_across;
void use_here()
{
var_across = 2;
}
Atribuir o endereço da variável estática ao ponteiro disponibilizará a variável estática para os subarquivos.
Nos subarquivos, temos que usar a palavra-chave extern para o ponteiro.
Mas não é necessário fazer isso.