Mi a statikus függvény a C-ben?

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.

  1. 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.
  2. 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.
  3. 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.
  4. 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;

}

  1. 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.
  2. 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.
  3. 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.
  4. 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!)
  5. 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.
  6. 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

  1. 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.
  2. 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ó.
  3. 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.
  4. 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.
  5. 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"

  1. 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.
  2. 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.
  3. 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 ).

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük