Migliore risposta
Come sappiamo che le funzioni definite in un file sono accessibili da un altro file. Se vogliamo limitare che le funzioni non debbano essere chiamate in un altro file, possiamo renderle statiche.
Quindi, funzioni statiche sono quelle funzioni che sono richiamabili nello stesso file in cui definiscono .
Possiamo definire una funzione statica utilizzando la seguente sintassi
static return\_type function\_name(arguments)
{
function\_body;
}
Ecco una funzione per trovare la radice quadrata di un dato numero
static long int getSquare(int num){
return (num*num);
}
Programma per dimostrare esempi di funzioni statiche in linguaggio 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;
}
Risultato
Enter an integer number: 36
Square of 36 is 1296.
Perché sono necessarie le funzioni statiche?
Poiché le funzioni sono utilizzate per riutilizzare il codice (es il codice che hai scritto può accedere a un altro file inserendolo nelle funzioni ), ma quando vuoi definirne alcuni funzioni che non dovrebbero essere condivisibili (richiamabili) in un altro file .
le funzioni statiche sono utili anche per gestire problema di conflitto di dichiarazione – se ci sono due funzioni in due file diversi con lo stesso nome, la dichiarazione della funzione sarà in conflitto. Possiamo renderli statici.
Per soddisfare questo tipo di requisito, possiamo renderli statici .
Risposta
Risposta breve: Significa che il nome della funzione è visibile e richiamabile solo nel file attualmente compilato. Altri file compilati separatamente non vedranno il nome della funzione né potranno chiamarlo. Successivamente, possono avere le proprie funzioni statiche con lo stesso nome. Ciò evita conflitti di nome nelle inclusioni di file e nel collegamento di file oggetto e librerie binarie.
Ci sono 4 diverse classi di archiviazione per larchiviazione in C.
- auto (automatico) è “normale” (impostazione predefinita) e utilizza la parola chiave auto , ma è di solito non specificato in quanto è il valore predefinito
- register è un “suggerimento” per il compilatore che può ottimizzare il codice creato per memorizzare il valore in un registro della cpu per unelaborazione più rapida. Il compilatore proverà a farlo, se possibile, ma in caso contrario è uguale al normale.
- extern esterno significa che cè solo una variabile globale con quel nome e tutti i file che la dichiarano extern useranno quella memoria. Un file lo dichiarerà globalmente come una variabile regolare, dove verrà allocato durante la compilazione.
- statico specificatore di archiviazione nei file sorgente C significa alcune cose diverse.
- Il nome e larchiviazione non vengono esportati in altri file che vengono compilati contemporaneamente. Ciò consente a ciascun file di avere nomi identici che non entrano in conflitto.
- Lo spazio di archiviazione creato per la variabile viene creato nellarea di archiviazione statica e inizializzato a 0 allavvio del programma o con un valore esplicito.
- Linizializzazione di una variabile statica viene eseguita solo una volta . (al momento della compilazione). Successivamente i valori assegnati vengono conservati per la vita del programma o fino a quando non vengono modificati da unassegnazione.
- la memoria statica dichiarata allinterno delle funzioni ha lambito della funzione, ma lallocazione statica. Ciò significa che la memoria è permanente per la durata del programma e non viene creata quando lo stack frame della funzione viene allocato per la chiamata di funzione. Mantiene il suo valore attraverso più chiamate di funzione. La memorizzazione persiste anche se il blocco di codice viene recuperato dallo stack dopo essere tornato.
int accumulate( unsigned int x)
{
static unsigned int acc = 0;
acc = acc + x;
return acc;
}
- Quanto sopra ritornerebbe un conteggio progressivo del suo input, poiché var acc manterrebbe il valore per ogni chiamata. acc verrà inizializzato a 0 al caricamento del programma.
- le variabili statiche hanno indirizzi nella RAM e puoi inviarle a funzioni per riferimento o valore.
- Variabili di ambito più piccolo (definite allinterno di funzioni) che hanno lo stesso nome di una variabile statica al di fuori di tale ambito ombreggiano la variabile statica, come qualsiasi altra.
- Le variabili statiche potrebbero non essere esportati in file esterni, quindi i valori potrebbero andare persi tra i domini di compilazione se non inviati esplicitamente come parametri in base al valore. (gotcha!)
- Come 4, altri file non possono accedere a variabili statiche come extern come potrebbero fare con variabili automatiche (normali). Non funzionerà, si otterranno programmi difettosi che si bloccano e il compilatore potrebbe essere ingannato e perderlo.
- Le variabili statiche possono essere inizializzate alla loro dichiarazione, ma il valore di inizializzazione deve essere unespressione costante, valutabile in fase di compilazione, non un valore che non è calcolabile in fase di compilazione. Non è possibile inizializzare una variabile statica con un valore sconosciuto come una variabile di parametro o il risultato di una chiamata di funzione che non si è verificata in fase di compilazione.
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;
}
Funzioni statiche
- Una funzione statica in C ha un ambito di file . Una funzione statica non può essere chiamato da un altro file nella stessa unità di traduzione. Ununità di traduzione è tutto il codice sorgente che entra in un compilatore dopo la pre-elaborazione per essere compilato in una sola volta. Le funzioni statiche non possono accedere a variabili statiche o chiamare funzioni statiche da altri file. Quindi, se vuoi limitare laccesso a una funzione al file corrente, puoi renderlo statico. Solo una funzione con quel nome può esistere in quel file (che vale anche per le funzioni normali), quindi spesso le funzioni di utilità vengono inserite nei file di intestazione, per essere incluse in più compilazioni e lintestazione è protetta con i comandi del pre-processore per non farlo essere incluso in qualsiasi unità di compilazione più di una volta. Tutte le intestazioni delle librerie C standard sono piene di funzioni globali, e quelle sono protette in modo da essere compilate solo una volta in una compilazione e sono funzioni globali. Nessuna funzione statica. Si dice che le funzioni statiche abbiano “collegamento interno” , il che significa che non possono essere viste in altri moduli compilati, anche se sono collegati allo stesso programma o libreria finale. Se una funzione non è statica allora in C quella funzione è una funzione globale e sarà disponibile globalmente nellintero programma. Ciò significa che potresti avere solo una funzione chiamata print nellintero programma . Per aggirare il problema, rendi statiche le tue funzioni e variabili e non avrai uno scontro di nomi.
- Le funzioni sono globali ed esterne per impostazione predefinita , tranne nel file in cui sono definite. Quindi non vedi la parola extern usato nei sorgenti C con funzioni, perché è già implicitamente presente. Questo è il motivo per cui puoi chiamare le normali funzioni da qualsiasi file nellunità di traduzione. Si dice che abbiano collegamento esterno che significa che una volta collegati sono visibili e richiamabili da qualsiasi file nel modulo o da qualsiasi altro modulo nel programma collegato.
- Una dichiarazione di prototipo di funzione è una “definizione provvisoria”, che è implicitamente esterna . Il codice dopo che la dichiarazione del prototipo è stata analizzata per la prima volta può chiamare la funzione purché la definizione completa esista nel codice finale. Ciò significa che una “definizione effettiva” deve esistere effettivamente o la fase di collegamento fallirà. Questo è il motivo per cui le intestazioni in C di solito non contengono il codice sorgente delle funzioni, non sono necessarie per la compilazione, ma sono in fase di collegamento.
- Una dichiarazione di prototipo di funzione statica è una “definizione provvisoria”, che non è esplicitamente esterna . La definizione completa deve essere presente nellunità di traduzione corrente (compilata allo stesso tempo) altrimenti la compilazione fallirà. I moderni compilatori C sintetizzeranno il prototipo dalla definizione fintanto che si verifica prima di una chiamata di funzione effettiva. Le cosiddette “dichiarazioni anticipate” consentono luso di definizioni provvisorie con la definizione effettiva in un secondo momento e hanno vari usi nelle strutture di dati e nellorganizzazione delle biblioteche.
- La prima definizione di una firma di file è quella usata per lintero programma, incluso statico o esterno. Una volta che una funzione è stata definita per la prima volta, se viene dichiarata inizialmente come statica, sarà sempre statica, anche se ridefinita in seguito senza la parola chiave statica. Se inizialmente è dichiarato extern (impostazione predefinita) non può essere ridefinito come statico.
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"
- Le funzioni definite nellambito del blocco non possono essere dichiarate statiche. È possibile creare solo definizioni di funzioni statiche con ambito file al di fuori di qualsiasi blocco. Ciò ha senso da una prospettiva logica, poiché lambito del file non può essere ridotto rispetto allintero file. Quindi definisci una funzione statica, o almeno il prototipo, molto presto nel file.
- Statico si riferisce alla funzione, non al tipo restituito . Puoi inserire la parola chiave statica dopo il tipo restituito, se lo desideri, ma se lo fai sei strano e confonderai le persone. Il valore restituito non è statico, la funzione lo è.
- Una definizione di funzione statica non sovrascriverà una quello globale definito prima di esso nello stesso file o in un file incluso. Se esiste già una funzione definita con quel nome, non puoi ridefinirla con una funzione statica o con qualsiasi funzione con lo stesso nome.
C non rinomina internamente funzioni e variabili come fa C ++, quindi non supporta il sovraccarico di funzioni. Il C ++ “manipola” i nomi delle funzioni con un nome in codice che indica diversi tipi di dati extra, come se fa parte di una classe o quali sono i suoi parametri, ecc. Quindi in C assente la parola chiave statica, potresti avere solo una funzione di ogni nome univoco in un programma, indipendentemente dal numero di file o librerie che comporta.
Quindi cosa fai se vuoi cambiare la tua funzione con una già esistente prima?
Bene, quello che fanno i programmatori C intelligenti è inventare un nome diverso per la loro funzione. Ma cè un modo per “ingannare” il compilatore cambiando preventivamente il testo sorgente con il preprocessore.
Esempio: un idiota ha scritto una funzione int sort( char** Array)
nella sua libreria e lo ha reso globale, è bacato e non fa esattamente quello che vuoi, perché fa sì che i numeri vengano dopo le lettere o qualcosa del genere, e le parole T sono sempre per prime, per qualche motivo.
Lo vuoi usa la libreria ma devi correggere la funzione e hai solo le intestazioni e la libreria compilata, non il codice sorgente.
OK> quindi viene creata unintestazione “speciale” che sostituisce tutte le istanze di ” sort “con” bad\_sort “nellintestazione, quindi importa il codice e sostituisce tutte le istanze di” sort “con” good\_sort “. “Good\_sort” è definito completamente in good\_sort.h, ma è contrassegnato come statico quindi è noto solo nel file in cui è incluso.
/* good\_sort.h */
#ifndef \_GOOD\_SORT\_H
#define \_GOOD\_SORT\_H
static int good\_sort(char** Array)
{
... //code here
return numsorted;
}
#endif
Viene aggiunta una parentesi di protezione della definizione per assicurarsi che non sia inclusa due volte.
/*-----------------------------------*/
/* 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 */
Un po schifoso, ma lidea è di chiamare la tua funzione invece di quello cattivo di renam chiamandolo “good\_sort” e chiamandolo invece. (ma solo in questo file – statico ).