Partilhar via


Storage-Class Especificadores para declarações External-Level

Variáveis externas são variáveis no escopo do arquivo. Eles são definidos fora de qualquer função, e eles estão potencialmente disponíveis para muitas funções. As funções só podem ser definidas no nível externo e, portanto, não podem ser aninhadas. Por padrão, todas as referências a variáveis externas e funções com o mesmo nome são referências ao mesmo objeto, o que significa que elas têm ligação externa. (Você pode usar a static palavra-chave para substituir esse comportamento.)

As declarações de variáveis a nível externo são definições de variáveis (declarações definidoras) ou referências a variáveis definidas noutro local (declarações de referência).

Uma declaração de variável externa que também inicializa a variável (implícita ou explicitamente) é uma declaração definidora da variável. Uma definição a nível externo pode assumir várias formas:

  • Uma variável que você declara com o static especificador de classe de armazenamento. Você pode inicializar explicitamente a static variável com uma expressão constante, conforme descrito em Inicialização. Se você omitir o inicializador, a variável será inicializada como 0 por padrão. Por exemplo, estas duas afirmações são ambas consideradas definições da variável k.

    static int k = 16;
    static int k;
    
  • Uma variável que você inicializa explicitamente no nível externo. Por exemplo, int j = 3; é uma definição da variável j.

Em declarações de variáveis no nível externo (ou seja, fora de todas as funções), você pode usar o static especificador de classe de armazenamento ou extern omitir totalmente o especificador de classe de armazenamento. Você não pode usar os auto terminais e registerstorage-class-specifier no nível externo.

Uma vez que uma variável é definida no nível externo, ela é visível em todo o resto da unidade de tradução. A variável não é visível antes de sua declaração no mesmo arquivo de origem. Além disso, não é visível em outros arquivos de origem do programa, a menos que uma declaração de referência o torne visível, conforme descrito abaixo.

As regras relativas incluem static :

  • As variáveis declaradas fora de todos os blocos sem a static palavra-chave sempre mantêm seus valores ao longo do programa. Para restringir o seu acesso a uma determinada unidade de tradução, deve utilizar a static palavra-chave. Isto dá-lhes uma ligação interna. Para torná-los globais para um programa inteiro, omita a classe de armazenamento explícita ou use a palavra-chave extern (consulte as regras na próxima lista). Isto dá-lhes ligações externas. As ligações internas e externas também são discutidas em Linkage.

  • Você pode definir uma variável no nível externo apenas uma vez dentro de um programa. Você pode definir outra variável com o mesmo nome e o static especificador de classe de armazenamento em uma unidade de tradução diferente. Uma vez que cada static definição é visível apenas dentro da sua própria unidade de tradução, não ocorre qualquer conflito. Ele fornece uma maneira útil de ocultar nomes de identificadores que devem ser compartilhados entre funções de uma única unidade de tradução, mas não visíveis para outras unidades de tradução.

  • O static especificador de classe de armazenamento também pode ser aplicado a funções. Se você declarar uma função static, seu nome será invisível fora do arquivo no qual ela é declarada.

As regras de utilização extern são:

  • O extern especificador de classe de armazenamento declara uma referência a uma variável definida em outro lugar. Você pode usar uma extern declaração para tornar visível uma definição em outro arquivo de origem ou para tornar uma variável visível antes de sua definição no mesmo arquivo de origem. Depois de declarar uma referência à variável no nível externo, a variável é visível em todo o restante da unidade de tradução na qual a referência declarada ocorre.

  • Para que uma extern referência seja válida, a variável a que se refere deve ser definida uma vez, e apenas uma vez, a nível externo. Esta definição (sem a extern classe de armazenamento) pode estar em qualquer uma das unidades de tradução que compõem o programa.

Exemplo

O exemplo abaixo ilustra as declarações externas:

/******************************************************************
                      SOURCE FILE ONE
*******************************************************************/
#include <stdio.h>

extern int i;                // Reference to i, defined below
extern void other ( void );  // Reference to other(), defined in second source file
void next( void );           // Function prototype

int main()
{
    i++;
    printf_s( "%d\n", i );   // i equals 4
    next();
}

int i = 3;                  // Definition of i

void next( void )
{
    i++;
    printf_s( "%d\n", i );  // i equals 5
    other();
}

/******************************************************************
                      SOURCE FILE TWO
*******************************************************************/
#include <stdio.h>

extern int i;              // Reference to i in
                           // first source file
void other( void )
{
    i++;
    printf_s( "%d\n", i ); // i equals 6
}

Os dois arquivos de origem neste exemplo contêm um total de três declarações externas de i. Apenas uma declaração é uma "declaração definidora". Essa declaração,

int i = 3;

define a variável i global e a inicializa com o valor inicial 3. A declaração de "referência" de na parte superior do primeiro arquivo de origem usando extern torna a variável global visível antes de i sua declaração definidora no arquivo. A declaração de referência do segundo arquivo de origem também torna a variável visível nesse arquivo de i origem. Se uma instância definidora para uma variável não é fornecida na unidade de tradução, o compilador assume que há um

extern int x;

declaração de referência e que constitui uma referência definidora

int x = 0;

aparece em outra unidade de tradução do programa.

Todas as três funções, main, , e other, executam a mesma tarefa: aumentam inexte imprimem. Os valores 4, 5 e 6 são impressos.

Se a variável i não tivesse sido inicializada, ela teria sido definida como 0 automaticamente. Neste caso, os valores 1, 2 e 3 teriam sido impressos. Consulte Inicialização para obter informações sobre inicialização de variáveis.

Ver também

Classes de armazenamento C