O que é uma função estática em C?

Melhor resposta

Como sabemos que as funções definidas em um arquivo podem ser acessadas em outro arquivo. Se quisermos restringir que as funções não devem ser chamadas em outro arquivo, podemos torná-las estáticas.

Portanto, funções estáticas são aquelas que podem ser chamadas no mesmo arquivo onde definem .

Podemos definir uma função estática usando a seguinte sintaxe

static return\_type function\_name(arguments)

{

function\_body;

}

Aqui está uma função para encontrar a raiz quadrada de um determinado número

static long int getSquare(int num){

return (num*num);

}

Programa para demonstrar exemplo de função estática na linguagem C

#include

//static function definition

static long int getSquare(int num){

return (num*num);

}

int main()

{

int num;

printf("Enter an integer number: ");

scanf("\%d",&num);

printf("Square of \%d is \%ld.\n",num,getSquare(num));

return 0;

}

Saída

Enter an integer number: 36

Square of 36 is 1296.

Por que as funções estáticas são necessárias?

Visto que as funções são usadas para reutilizar o código (ie o código que você escreveu pode acessar em outro arquivo, colocando-os nas funções ), mas quando você quiser definir alguns funções que não devem ser compartilháveis ​​(chamáveis) em outro arquivo .

funções estáticas também são úteis para lidar com problema de conflito de declaração – se houver duas funções em dois arquivos diferentes com o mesmo nome, a declaração da função entrará em conflito. Podemos torná-los estáticos.

Para cumprir esse tipo de requisito, podemos torná-los estáticos .

Resposta

Resposta curta: Significa que o nome da função só é visível e pode ser chamado no arquivo que está sendo compilado atualmente. Outros arquivos compilados separadamente não verão o nome da função nem poderão chamá-la. Posteriormente, eles podem ter suas próprias funções estáticas com o mesmo nome. Isso evita conflitos de nome em inclusões de arquivos e na vinculação de arquivos de objetos e bibliotecas binárias.

Existem 4 classes de armazenamento diferentes para armazenamento em C.

  • auto (automático) isto é “regular” (padrão) e usa a palavra-chave auto , mas é geralmente não especificado, pois é o padrão
  • registrar é uma “dica” para o compilador de que pode otimizar o código criado para armazenar o valor em um registro de cpu para processamento mais rápido. O compilador tentará se puder fazer isso, mas se não for o mesmo que regular.
  • extern externo significa que há apenas uma variável global com esse nome e todos os arquivos que a declaram como externa usarão esse armazenamento. Um arquivo irá declará-lo globalmente como uma variável regular, onde será alocado na compilação.
  • especificador de armazenamento estático em arquivos de origem C significa algumas coisas diferentes.

  1. O nome e o armazenamento não são exportados para outros arquivos sendo compilados ao mesmo tempo. Isso permite que cada arquivo tenha nomes idênticos que não entrem em conflito.
  2. O armazenamento criado para a variável é criado na área de armazenamento estático e inicializado em 0 no início do programa ou com um valor explícito.
  3. A inicialização de uma variável estática é realizada apenas uma vez . (em tempo de compilação). Daí em diante, os valores atribuídos são mantidos durante a vida do programa ou até serem alterados por uma atribuição.
  4. o armazenamento estático declarado dentro das funções tem escopo de função, mas alocação estática. Isso significa que o armazenamento é permanente durante a vida útil do programa e não é criado quando o quadro de pilha de funções é alocado para a chamada de função. Ele retém seu valor por meio de várias chamadas de função. O armazenamento persiste mesmo que o bloco de código seja recuperado da pilha depois de retornar.

int accumulate( unsigned int x)

{

static unsigned int acc = 0;

acc = acc + x;

return acc;

}

  1. O acima retornaria uma contagem contínua de sua entrada, pois o var acc reteria o valor em cada chamada. acc será inicializado em 0 no carregamento do programa.
  2. variáveis ​​estáticas têm endereços na RAM, e você pode enviá-las para funções por referência ou valor.
  3. Variáveis ​​de escopo menor (definidas dentro de funções) que têm o mesmo nome de uma variável estática fora desse escopo sombreiam a variável estática, como qualquer outra.
  4. variáveis ​​estáticas podem não ser exportados para arquivos externos, portanto, os valores podem ser perdidos nos domínios de compilação se não forem enviados explicitamente como parâmetros por valor. (peguei!)
  5. Como 4, outros arquivos não podem acessar variáveis ​​estáticas como extern como poderiam com variáveis ​​automáticas (normais). Não funcionará, você obterá programas com erros que travam, e o compilador pode ser enganado e perdê-lo.
  6. Variáveis ​​estáticas podem ser inicializadas em sua declaração, mas o valor de inicialização deve ser uma expressão constante, avaliável em tempo de compilação, não um valor que não seja calculável em tempo de compilação. Você não pode inicializar uma variável estática com um valor desconhecido, como uma variável de parâmetro ou o resultado de uma chamada de função que não ocorreu em tempo de compilação.

int accumulate( unsigned int x)

{

/* ERROR x is not a compile-time constant. */

static unsigned int acc = x;

static unsigned int acc = 0; /* OK */

acc = acc + x;

return acc;

}

Funções estáticas

  1. Uma função estática em C tem escopo de arquivo . Uma função estática não pode ser chamado por outro arquivo na mesma unidade de tradução. Uma unidade de tradução é todo o código-fonte que vai para um compilador após o pré-processamento para ser compilado de uma vez. As funções estáticas não podem acessar variáveis ​​estáticas ou chamar funções estáticas de outros arquivos. Portanto, se você quiser limitar o acesso a uma função ao arquivo atual, pode torná-lo estático. Apenas uma função com esse nome pode existir nesse arquivo (que vale para funções regulares também), então muitas vezes as funções de utilitário são colocadas em arquivos de cabeçalho, para serem incluídas em várias compilações, e o cabeçalho é protegido por comandos de pré-processador para não ser incluído em qualquer unidade de compilação mais de uma vez. Todos os cabeçalhos da biblioteca C padrão estão cheios de funções globais, e esses são protegidos para que sejam compilados apenas uma vez em uma compilação e são funções globais. Sem funções estáticas. Diz-se que as funções estáticas têm ‘ligação interna’ , o que significa que não podem ser vistas em outros módulos compilados, mesmo que estejam ligados ao mesmo programa ou biblioteca final. Se uma função não for estática , então em C essa função é uma função global e estará disponível em todo o programa globalmente. Isso significa que você só pode ter uma função chamada imprimir em todo o programa . Para contornar isso, torne suas funções e variáveis ​​estáticas e você não terá um conflito de nomes.
  2. As funções são globais e externas por padrão , exceto no arquivo em que são definidas. Portanto, você não vê a palavra extern usado no código C com funções, porque já está lá implicitamente. É por isso que você pode chamar funções normais de qualquer arquivo na unidade de tradução. Diz-se que eles têm ligação externa , o que significa que, uma vez vinculados, eles são visíveis e podem ser chamados por qualquer arquivo no módulo ou qualquer outro módulo no programa vinculado.
  3. Uma declaração de protótipo de função é uma “definição provisória”, que é implicitamente externa . O código após a declaração do protótipo ser varrido pela primeira vez pode chamar a função, desde que a definição completa exista no código final. Isso significa que uma “definição real” deve realmente existir ou a fase de vinculação falhará. É por isso que os cabeçalhos em C geralmente não contêm o código-fonte das funções, eles não são necessários para compilar, mas estão em fase de vinculação.
  4. Uma declaração de protótipo de função estática é uma “definição provisória”, que é explicitamente não externa . A definição completa deve estar presente na unidade de tradução atual (compilada ao mesmo tempo) ou a compilação falhará. Os compiladores C modernos sintetizam o protótipo a partir da definição, desde que ocorra antes de uma chamada de função real. As chamadas “declarações diretas” permitem o uso de definições provisórias com a definição real posterior e têm vários usos em estruturas de dados e na organização de bibliotecas.
  5. A primeira definição de uma assinatura de arquivo é aquela usada para todo o programa, incluindo estático ou externo. Uma vez que uma função é definida pela primeira vez, se ela for declarada inicialmente como estática, ela sempre será estática, mesmo se redefinida posteriormente sem a palavra-chave static. Se for inicialmente declarado extern (padrão), não pode ser redefinido como estático.

static void f(int); /* Function is always static */

...

void f(int x) { ….} /* static , not exported, no error */

void f(int); /* Function is always global */

...

static void f(int x) { ….} /*ERROR NOT STATIC */

clang: "error: static declaration of "f" follows non-static declaration"

  1. As funções definidas no escopo do bloco não podem ser declaradas estáticas. Apenas as definições de função estática do escopo do arquivo podem ser feitas fora de qualquer bloco. Isso faz sentido de uma perspectiva lógica, pois o escopo do arquivo não pode ser menor do que o arquivo inteiro. Portanto, defina uma função estática, ou pelo menos o protótipo, bem no início do arquivo.
  2. Estático refere-se à função, não ao tipo de retorno . Você pode colocar a palavra-chave estática após o tipo de retorno se desejar, mas se o fizer, ficará estranho e confundirá as pessoas. O valor de retorno não é estático, a função é.
  3. Uma definição de função estática não substituirá um global aquele definido antes dele no mesmo arquivo ou em um arquivo incluído. Se já existe uma função com esse nome definida, você não pode redefini-la com uma função estática ou qualquer função com o mesmo nome.

C não renomeia funções e variáveis ​​internamente como o C ++ faz, portanto, não suporta sobrecarga de função. C ++ “confunde” os nomes de função com um nome codificado indicando vários tipos extras de dados, como se faz parte de uma classe ou quais são seus parâmetros, etc. Portanto, em C sem a palavra-chave estática, você pode ter apenas uma função cada nome exclusivo em um programa, não importa quantos arquivos ou bibliotecas ele envolve.

Então, o que você faz se quiser mudar sua função por uma já existente?

Bem, o que os codificadores inteligentes C fazem é criar um nome diferente para sua função. Mas existe uma maneira de enganar o compilador alterando preventivamente o texto fonte com o pré-processador.

Exemplo: Algum idiota escreveu uma função int sort( char** Array) em sua biblioteca e o tornou global, tem bugs e não faz exatamente o que você quer, porque faz os números virem depois das letras ou algo assim, e as palavras T estão sempre em primeiro lugar, por algum motivo.

Você quer use a biblioteca, mas precisa corrigir a função, e você só tem os cabeçalhos e a biblioteca compilada, não o código-fonte.

OK> então um cabeçalho “especial” é feito que substitui todas as instâncias de ” sort ”com“ bad\_sort ”no cabeçalho, então importa seu código e substitui todas as instâncias de“ sort ”por“ good\_sort ”. “Good\_sort” é definido completamente em good\_sort.h, mas é marcado como estático, portanto, só é conhecido no arquivo em que está incluído.

/* good\_sort.h */

#ifndef \_GOOD\_SORT\_H

#define \_GOOD\_SORT\_H

static int good\_sort(char** Array)

{

... //code here

return numsorted;

}

#endif

Um colchete de proteção de definição é adicionado para garantir que não seja incluído duas vezes.

/*-----------------------------------*/

/* program.c */

#include "Trumpsort.h" /* The buggy library header */

...

#ifdef sort

#undef sort /* undefine the sort function name as reserved */

#define sort bad\_sort /* replace the name */

#include "good\_sort.h" /* your fixed version */

#endif

#define sort good\_sort /* replace the name in this file */

/* rest of file */

Um pouco de merda, mas a ideia é chamar sua função em vez do ruim por renomear ligando-o para “good\_sort” e chamando-o. (mas apenas neste arquivo – estático ).

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *