Nejlepší odpověď
Jak víme, k funkcím definovaným v souboru lze přistupovat v jiném souboru. Pokud chceme omezit, že funkce nesmí být volány v jiném souboru, můžeme je udělat statickými.
Proto statické funkce jsou ty funkce, které lze volat ve stejném souboru, kde definují .
Funkci statickou můžeme definovat pomocí následující syntaxe
static return\_type function\_name(arguments)
{
function\_body;
}
Toto je funkce pro vyhledání druhé odmocniny daného čísla
static long int getSquare(int num){
return (num*num);
}
Program pro demonstraci příkladu statické funkce v jazyce 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;
}
Výstup
Enter an integer number: 36
Square of 36 is 1296.
Proč jsou statické funkce vyžadovány?
Protože funkce jsou používány k opětovnému použití kódu (tj kód, který jste napsali, může přistupovat do jiného souboru jejich vložením do funkcí ), ale když chcete definovat některé funkce, které by neměly být sdíleny (lze volat) v jiném souboru .
statické funkce jsou také užitečné při řešení problému konfliktu deklarací – pokud existují dvě funkce ve dvou různých souborech se stejným názvem, deklarace funkce bude konfliktní. Můžeme je učinit statickými.
Abychom splnili tento druh požadavku, můžeme je staticky .
Odpovědět
Krátká odpověď: To znamená, že název funkce je viditelný a lze jej vyvolat pouze v aktuálně kompilovaném souboru. Ostatní soubory zkompilované samostatně neuvidí název funkce nebo ji budou moci volat. Následně mohou mít své vlastní statické funkce se stejným názvem. Tím se zabrání střetům názvů v inkluzích souborů a při propojování souborů objektů a binárních knihoven.
V úložišti C jsou 4 různé třídy úložiště.
- auto (automatické) toto je „běžné“ (výchozí) a používá klíčové slovo auto , ale je obvykle není specifikováno, protože se jedná o výchozí
- registr je „nápovědou“ kompilátoru, že může optimalizovat kód vytvořený pro uložení hodnota v registru CPU pro rychlejší zpracování. Kompilátor to zkusí, pokud to dokáže, ale pokud ne, je to stejné jako běžné.
- extern externí znamená, že existuje pouze jedna globální proměnná s tímto názvem a všechny soubory, které ji deklarují jako externí, toto úložiště použijí. Jeden soubor jej globálně deklaruje jako běžnou proměnnou, kde bude přidělen při kompilaci.
- statický specifikátor úložiště ve zdrojových souborech C znamená několik různých věcí.
- Název a úložiště se neexportují do jiných souborů, které se kompilují současně. To umožňuje každému souboru mít shodná jména, která se neshodují.
- Úložiště vytvořené pro proměnnou se vytvoří ve statické oblasti úložiště a inicializuje se na 0 při spuštění programu nebo s explicitní hodnotou. li>
- Inicializace statické proměnné se provádí pouze jednou . (v době kompilace). Poté jsou přiřazené hodnoty uchovány po celou dobu životnosti programu nebo do změny v přiřazení.
- statické úložiště deklarované uvnitř funkcí má rozsah funkcí, ale statické přidělení. To znamená, že úložiště je trvalé po celou dobu životnosti programu a není vytvořeno, když je rámec zásobníku funkcí přidělen pro volání funkce. Zachovává svou hodnotu prostřednictvím několika volání funkcí. Úložiště přetrvává, i když se blok kódu po jeho návratu ze zásobníku obnoví.
int accumulate( unsigned int x)
{
static unsigned int acc = 0;
acc = acc + x;
return acc;
}
- Výše uvedené by se vrátilo průběžný záznam jeho vstupu, protože var acc by si uchoval hodnotu při každém volání. acc bude inicializován na 0 při načtení programu.
- statické proměnné mají adresy v RAM a můžete je posílat do funkcí pomocí odkazu nebo hodnoty.
- Proměnné menšího rozsahu (definované uvnitř funkcí), které mají stejný název jako statická proměnná mimo tento obor, stínují statickou proměnnou stejně jako ostatní.
- statické proměnné nemusí být exportovány do externích souborů, takže hodnoty mohou být ztraceny napříč doménami kompilace, pokud nebudou explicitně odeslány jako parametry podle hodnoty. (gotcha!)
- Stejně jako 4, ani jiné soubory nemají přístup ke statickým proměnným jako extern , jako by to bylo s automatické (normální) proměnné. Nebude to fungovat, narazíte na buggy programy, které se zhroutí, a kompilátor by se mohl zmást a chybět.
- Statické proměnné mohou být inicializovány při jejich deklaraci, ale inicializační hodnota musí být konstantní výraz, který lze vyhodnotit v době kompilace, nikoli hodnota, kterou nelze vypočítat v době kompilace. Statickou proměnnou nemůžete inicializovat s neznámou hodnotou, jako je proměnná parametru, nebo výsledek volání funkce, ke kterému nedošlo v době kompilace.
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;
}
Statické funkce
- Statická funkce v jazyce C má rozsah souboru . Statickou funkci nelze volaný jiným souborem ve stejné překladové jednotce. Překladová jednotka je veškerý zdrojový kód směřující do kompilátoru po předzpracování, které má být zkompilováno najednou. Statické funkce nemají přístup ke statickým proměnným ani nemohou volat statické funkce z jiných souborů. Pokud tedy chcete omezit přístup k funkci na aktuální soubor, můžete jej nastavit jako statický. V daném souboru může existovat pouze jedna funkce s tímto názvem (která platí i pro běžné funkce), takže často jsou obslužné funkce vkládány do souborů záhlaví, které mají být zahrnuty do více kompilací, a záhlaví je chráněno příkazy před zpracováním být zahrnuty v jakékoli kompilační jednotce více než jednou. Všechny standardní záhlaví knihovny C jsou plné globálních funkcí a ty jsou chráněny, takže jsou kompilovány pouze jednou v kompilaci a jsou globálními funkcemi. Žádné statické funkce. O statických funkcích se říká, že mají „interní propojení“ , což znamená, že je nelze vidět v jiných kompilovaných modulech, i když jsou propojeny do stejného konečného programu nebo knihovny. Pokud funkce není statická , pak v C je tato funkce globální funkcí a bude k dispozici v celém programu globálně. To znamená, že v celém programu můžete mít pouze jednu funkci nazvanou tisk . Chcete-li to obejít, nastavte své funkce a proměnné statické a nebudete mít střet názvů.
- Funkce jsou globální a ve výchozím nastavení jsou externí , kromě souboru, ve kterém jsou definovány. Slovo extern použitý ve zdroji C s funkcemi, protože tam již implicitně je. Proto můžete volat normální funkce z libovolného souboru v překladové jednotce. Říká se, že mají externí propojení , což znamená, že jakmile jsou propojeny, jsou viditelné a lze je vyvolat jakýmkoli souborem v modulu nebo jakýmkoli jiným modulem v propojeném programu.
- Deklarace prototypu funkce je „předběžná definice“, která je implicitně externí . Kód po prvním naskenování deklarace prototypu může volat funkci, pokud v konečném kódu existuje úplná definice. To znamená, že skutečně musí existovat „skutečná definice“, jinak fáze propojení selže. To je důvod, proč záhlaví v C obvykle neobsahují zdrojový kód pro funkce, nejsou potřeba ke kompilaci, ale jsou ve fázi propojení.
- Deklarace prototypu statické funkce je „předběžná definice“, která výslovně není extern . Úplná definice musí být v aktuální překladové jednotce (zkompilovaná současně), jinak se kompilace nezdaří. Moderní překladače jazyka C syntetizují prototyp z definice, pokud k němu dojde dříve než skutečné volání funkce. Takzvaná „dopředná prohlášení“ umožňují pozdější použití předběžných definic se skutečnou definicí a mají různá použití v datových strukturách a v organizaci knihoven.
- První definice podpisu souboru je definice použitá pro celý program, včetně statické nebo externí. Jakmile je funkce poprvé definována, je-li původně deklarována jako statická, bude statická vždy, i když bude později definována bez statického klíčového slova. Pokud je původně deklarován jako externí (výchozí), nelze jej znovu definovat jako statický.
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"
- Funkce definované v oboru bloku nelze prohlásit za statické. Pouze statické funkce rozsahu souboru lze definovat mimo jakýkoli blok. To dává smysl z logické perspektivy, protože rozsah souboru nelze zmenšit na menší než celý soubor. Definujte tedy statickou funkci nebo alespoň prototyp velmi brzy v souboru.
- Statické odkazuje na funkci, nikoli na návratový typ . Můžete umístit statické klíčové slovo za návratový typ, pokud si přejete, ale pokud to uděláte, jste divní a budete matou lidi. Návratová hodnota není statická, funkce je.
- Definice statické funkce nepřepíše a globální před ním definované ve stejném souboru nebo v zahrnutém souboru. Pokud již existuje funkce pod tímto názvem definovaná, nemůžete ji předefinovat statickou funkcí nebo jakoukoli funkcí stejného jména.
C interně nepřejmenovává funkce a proměnné jako C ++, takže nepodporuje přetížení funkcí. C ++ „mění“ názvy funkcí s kódovaným názvem, který označuje několik dalších druhů dat, například pokud je součástí třídy nebo jaké jsou její parametry atd. Takže v jazyce C chybí statické klíčové slovo, můžete mít pouze jednu funkci každý jedinečný název v programu, bez ohledu na to, kolik souborů nebo knihoven to obnáší.
Co tedy dělat, pokud chcete změnit svou funkci pro jeden již existující předchozí?
Co však inteligentní kodéry C dělají, je vymyslet pro svou funkci jiný název. Existuje však způsob, jak kompilátora „oklamat“ preventivním změnou zdrojového textu s preprocesorem.
Příklad: Některý idiot napsal do své knihovny funkci int sort( char** Array)
a udělalo to globální a je to buggy a nedělá přesně to, co chcete, protože to dělá čísla přicházející za písmeny nebo tak něco, a slova T jsou vždy z nějakého důvodu první.
Chcete použijte knihovnu, ale potřebujete opravit tuto funkci a máte pouze záhlaví a kompilovanou knihovnu, ne zdrojový kód.
OK> takže je vytvořeno „speciální“ záhlaví, které nahradí všechny instance „ třídit “s„ bad\_sort “v záhlaví, poté importovat váš kód a nahradit všechny výskyty„ sort “výrazem„ good\_sort “. „Good\_sort“ je definován úplně v good\_sort.h, ale je označen jako statický, takže je znám pouze v souboru, ve kterém je obsažen.
/* good\_sort.h */
#ifndef \_GOOD\_SORT\_H
#define \_GOOD\_SORT\_H
static int good\_sort(char** Array)
{
... //code here
return numsorted;
}
#endif
Přidá se ochranný držák definice, aby se zajistilo, že nebude zahrnut dvakrát.
/*-----------------------------------*/
/* 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 */
Trochu crapfest, ale myšlenka je zavolat vaši funkci místo špatného přejmenováním to na „good\_sort“ a místo toho to zavolat. (ale pouze v tomto souboru – statický ).