Legjobb válasz
Mint tudjuk, hogy a fájlban definiált funkciók egy másik fájlban is elérhetők. Ha korlátozni akarjuk, akkor a függvényeket nem szabad meghívni egy másik fájlban, statikussá tehetjük őket.
Ezért a statikus függvények azok a függvények, amelyek meghívhatók ugyanabban a fájlban, ahol definiálják .
A következő szintaxis használatával meghatározhatunk egy statikus függvényt
static return\_type function\_name(arguments)
{
function\_body;
}
Itt található egy függvény az adott szám négyzetgyökének megtalálásához
static long int getSquare(int num){
return (num*num);
}
Program a statikus funkció példájának bemutatására C nyelven
#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;
}
Kimenet
Enter an integer number: 36
Square of 36 is 1296.
Miért van szükség a statikus függvényekre?
Mivel a funkciókat a kód újrafelhasználására használják (azaz az általad írt kód egy másik fájlban férhet hozzá, ha beteszi őket a függvényekbe ), de ha meg akarsz határozni néhány olyan funkciók, amelyek nem lehetnek megoszthatók (hívhatók) egy másik fájlban .
A statikus függvények szintén hasznosak a deklarációs ütközési probléma kezelésében. – ha két függvény van két különböző fájlban, azonos névvel, akkor a funkció deklarációja ütközik. Statikussá tehetjük őket.
Az ilyen követelmények teljesítéséhez statikussá tehetjük őket .
Válasz
Rövid válasz: Ez azt jelenti, hogy a függvény neve csak a jelenleg összeállított fájlban látható és hívható. Más, külön összeállított fájlok nem látják a függvény nevét, és nem lesznek képesek meghívni. Ezt követően saját statikus funkcióik lehetnek ugyanazon a néven. Ez elkerüli a névütközéseket a fájlok zárványaiban, valamint az objektumfájlok és a bináris könyvtárak összekapcsolásában.
A C-ben 4 különböző tárolási osztály van tárolva.
- auto (automatikus) ez „rendes” (alapértelmezett) és a auto kulcsszót használja, de általában nincs megadva, mivel ez az alapértelmezett
- regisztráció „tipp” a fordító számára, hogy optimalizálhatja a létrehozott kódot a érték a CPU regiszterben a gyorsabb feldolgozás érdekében. A fordító megpróbálja megtenni, ha teheti, de ha nem, akkor megegyezik a normáléval.
- extern külső azt jelenti, hogy van csak egy globális változó ezen a néven, és az összes fájl, amely externek nyilvánítja, ezt a tárolót fogja használni. Az egyik fájl globálisan deklarálja reguláris változónak, ahol lefordításra kerül.
- statikus tároló specifikátor a C forrásfájlokban azt jelenti, hogy néhány különböző dolog.
- A nevet és a tárhelyet nem exportálják más, egyidejűleg fordított fájlokba. Ez lehetővé teszi minden fájl azonos nevét, amelyek nem ütköznek össze.
- A változó számára létrehozott tároló a statikus tárterületen jön létre, és a program indításakor 0-ra inicializálódik, vagy kifejezett értékkel.
- A statikus változó inicializálása csak egyszer történik . (összeállítási időpontban). Ezután a hozzárendelt értékeket a program élettartama alatt, vagy amíg egy hozzárendelés megváltoztatja.
- A függvényeken belül deklarált statikus tároló funkciók hatóköre, de statikus allokációval rendelkezik. Ez azt jelenti, hogy a tároló a program élettartama alatt állandó, és nem akkor jön létre, amikor a függvényköteg keretet lefoglalják a függvényhíváshoz. Több funkcióhívással megőrzi értékét. A tároló továbbra is fennáll, annak ellenére, hogy a kódblokk visszatérése után a veremből helyreáll.
int accumulate( unsigned int x)
{
static unsigned int acc = 0;
acc = acc + x;
return acc;
}
- A fentiek visszatérnek a bemenet futó összege, mivel a var acc minden híváson keresztül megőrzi az értékét. Az acc program nullára inicializálódik a program betöltésekor.
- A statikus változók címei a RAM-ban vannak, és hivatkozásként vagy értékként funkciókba küldhetjük őket.
- A kisebb hatókörű (a függvényeken belül definiált) változók, amelyeknek ugyanaz a neve, mint az ezen hatókörön kívül eső statikus változók, ugyanúgy árnyékolják a statikus változót, mint bármely más.
- Előfordulhat, hogy a statikus változók nem lehetnek külső fájlokba exportálva, így az értékek elveszhetnek a fordítási tartományokban, ha nem kifejezetten értékként küldik őket paraméterként. (gotcha!)
- A 4-hez hasonlóan más fájlok sem érhetik el a statikus változókat extern néven, mint a automatikus (normál) változók. Nem fog működni, hibás programokat kap, amelyek összeomlanak, és előfordulhat, hogy a fordító becsapja és elmulasztja.
- A statikus változókat inicializálhatjuk a deklarációjukkor, de az inicializáló értéknek állandó kifejezésnek kell lennie, értékelhetőnek kell lennie fordítási időben, nem pedig olyan érték, amely nem fordítható össze. Nem lehet inicializálni a statikus változót ismeretlen értékkel, például egy paraméterváltozóval, vagy egy olyan függvényhívás eredményével, amely nem fordítás idején következett be.
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;
}
Statikus függvények
- A C statikus függvényének fájlköre van . Statikus függvény nem lehet egy másik fájl hívja meg ugyanabban a fordítási egységben. A fordítási egység az összes forráskód, amely az egyszerre lefordítandó előfeldolgozás után kerül a fordítóba. A statikus függvények nem férhetnek hozzá a statikus változókhoz, vagy más fájlokból hívhatják meg a statikus függvényeket. Tehát, ha korlátozni szeretné a függvényekhez való hozzáférést az aktuális fájlhoz, statikussá teheti azt. Csak egy ilyen nevű függvény létezhet abban a fájlban (amely a szokásos funkciókra is vonatkozik), ezért gyakran a segédprogram függvények kerülnek a fejlécfájlokba, hogy több fordításban is szerepeljenek, és a fejlécet előfeldolgozó parancsokkal védik, hogy ne bármely összeállítási egységbe többször bele kell foglalni. Az összes szabványos C könyvtárfejléc tele van globális függvényekkel, és ezeket úgy őrzik, hogy egy fordításban csak egyszer állítsák össze őket, és globális függvények. Nincs statikus funkció. A statikus függvényekről azt mondják, hogy ’belső összekapcsolódás’ azt jelenti, hogy más fordított modulokban nem láthatók, még akkor sem, ha ugyanahhoz a végső programhoz vagy könyvtárhoz vannak kapcsolva. Ha egy függvény nem statikus , akkor C-ben ez a függvény globális függvény, és globálisan elérhető lesz az egész programban. Ez azt jelenti, hogy csak egy print nevű függvénye lehet az egész programban . Ennek kikerüléséhez tegye statikussá a függvényeit és a változóit, és így nem ütközik össze a név.
- A függvények globálisak, alapértelmezés szerint externek , kivéve a fájlban, amelyben definiálva vannak. Tehát nem látja a extern a C forrásban, függvényekkel használva, mert implicit módon már ott van. Ezért hívhatja meg a normál függvényeket a fordítóegység bármely fájljából. Állítólag külső összekapcsolás jelentése van, miután összekapcsolták őket, a modul bármely fájlja vagy a kapcsolt program bármely más modulja látható és meghívható.
- A függvény prototípus deklarációja „kísérleti meghatározás”, amely implicit módon extern . A prototípus deklaráció első beolvasása utáni kód meghívhatja a függvényt, amennyiben a teljes definíció megtalálható a végső kódban. Ez azt jelenti, hogy valóban léteznie kell egy „tényleges meghatározásnak”, különben a összekapcsolási szakasz meghiúsul. Éppen ezért a C fejlécei általában nem tartalmazzák a függvények forráskódját, nem szükségesek a fordításhoz, de összekapcsolási szakaszban vannak.
- A statikus függvény prototípus deklarációja „kísérleti meghatározás”, amely kifejezetten nem extern . A teljes definíciónak jelen kell lennie az aktuális fordítási egységben (egyidejűleg fordítva), különben az összeállítás sikertelen lesz. A modern C fordítók szintetizálják a prototípust a definícióból, amennyiben az korábban bekövetkezik, mint egy tényleges függvényhívás. Az úgynevezett „forward deklarációk” lehetővé teszik a tényleges definícióval történő későbbi definíciók használatát, és az adatstruktúrákban és a könyvtárak szervezésében különféle felhasználási lehetőségekkel rendelkeznek.
- A fájl aláírás első definíciója az egész program, beleértve a statikusat vagy az externt is. Ha egy függvényt először definiálnak, és ha azt kezdetben statikusnak nyilvánítják, akkor mindig statikus lesz, még akkor is, ha később a statikus kulcsszó nélkül definiálják újra. Ha eredetileg külsőnek van deklarálva (alapértelmezett), akkor nem lehet újból statikusként definiálni.
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"
- A blokk hatókörében definiált funkciók nem nyilváníthatók statikusnak. Csak a fájlok hatókörének statikus függvénydefiníciói készíthetők bármely blokkon kívül. Ennek logikai szempontból van értelme, mivel a fájlok hatóköre nem lehet kisebb, mint a teljes fájl. Tehát határozzon meg egy statikus függvényt, vagy legalábbis a prototípust a fájl elején.
- Statikus a függvényre vonatkozik, nem a visszatérés típusára . A statikus kulcsszót a return típus után helyezheti el, ha akarja, de ha igen, akkor furcsa vagy, és megzavarodod az embereket. A visszatérési érték nem statikus, a függvény az.
- A statikus függvénydefiníció nem fogja felülírni a globális, amelyet előtte definiáltak ugyanabban a fájlban vagy egy mellékelt fájlban. Ha már van definiálva egy ilyen nevű függvény, akkor nem definiálhatja újra egy statikus függvénnyel, vagy bármely más azonos nevű függvénnyel.
C nem nevezi át belsőleg a függvényeket és a változókat , mint a C ++, ezért nem támogatja a függvények túlterhelését. A C ++ a függvényneveket kódolt névvel többféle adattípust jelöli, például, ha egy osztály része, vagy milyen paraméterei vannak, stb. Tehát C-ben a statikus kulcsszó hiányában csak egy funkciója lehet: a program minden egyedi neve, függetlenül attól, hogy hány fájlt vagy könyvtárat tartalmaz.
Tehát mit tegyen, ha módosítani szeretné a funkcióját egy már létező korábbi számára?
Nos, amit az intelligens C kódolók csinálnak, az a funkciójuknak más nevet állít elő. De van egy módja annak, hogy „becsapja” a fordítót úgy, hogy megelőzően megváltoztatja a forrásszöveget az előfeldolgozóval.
Példa: Néhány idióta int sort( char** Array)
függvényt írt a könyvtárába. és globálissá tette, és hibás, és nem pontosan azt csinálja, amit akar, mert a számok betűk vagy valami után következnek, és a T szavak valamilyen oknál fogva mindig az elsők.
Szeretné használja a könyvtárat, de meg kell javítania a függvényt, és csak a fejlécek és a lefordított könyvtár van, a forráskód nem.
OK> tehát egy „speciális” fejléc készül, amely helyettesíti a „ sort ”helyett a„ bad\_sort ”kifejezést a fejlécben, majd importálja a kódot, és a„ sort ”összes példányát lecseréli a“ good\_sort ”kifejezésre. A „good\_sort” teljes egészében a good\_sort.h fájlban van definiálva, de statikusan van megjelölve, így csak abban a fájlban ismeretes, amelyben szerepel.
/* good\_sort.h */
#ifndef \_GOOD\_SORT\_H
#define \_GOOD\_SORT\_H
static int good\_sort(char** Array)
{
... //code here
return numsorted;
}
#endif
Meghatározású biztonsági zárójel kerül hozzáadásra, hogy megbizonyosodjon arról, hogy kétszer nem szerepel benne.
/*-----------------------------------*/
/* 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 */
Kicsit vacak, de az a cél, hogy meghívd a függvényed a rossz helyett átnevezéssel „jó\_sort” -nak adva, és inkább ezt hívva. (de csak ebben a fájlban – statikus ).