Bästa svaret
Som vi vet att funktionerna som definieras i en fil kan nås i en annan fil. Om vi vill begränsa att funktioner inte får anropas i en annan fil kan vi göra dem statiska.
Därför statiska funktioner är de funktioner som kan kallas i samma fil där de definierar .
Vi kan definiera en funktion statisk genom att använda följande syntax
static return\_type function\_name(arguments)
{
function\_body;
}
Här är en funktion för att hitta kvadratroten av ett givet nummer
static long int getSquare(int num){
return (num*num);
}
Program för att visa exempel på statisk funktion i C-språk
#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;
}
Utdata
Enter an integer number: 36
Square of 36 is 1296.
Varför krävs de statiska funktionerna?
Eftersom funktioner används för att återanvända koden (dvs. koden som du har skrivit kan komma åt i en annan fil genom att placera dem i funktionerna ), men när du vill definiera några -funktioner som inte borde vara delbara (anropbara) i en annan fil .
Statiska funktioner är också användbara för att hantera konfliktfråga – om det finns två funktioner i två olika filer med samma namn kommer funktionsdeklarationen att vara i konflikt. Vi kan göra dem statiska.
För att uppfylla sådana krav kan vi göra dem statiska .
Svar
Kort svar: Det betyder att funktionsnamnet bara är synligt och kan kallas i filen som kompileras för närvarande. Andra filer som kompileras separat kommer inte att se funktionsnamnet eller kunna kalla det. Därefter kan de ha sina egna statiska funktioner med samma namn. Detta undviker namnkollisioner i filinkluderingar och vid länkning av objektfiler och binära bibliotek.
Det finns fyra olika lagringsklasser för lagring i C.
- auto (automatisk) detta är ”vanligt” (standard) och använder nyckelordet auto , men är brukar inte anges eftersom det är standard
- registret är en ”ledtråd” till kompilatorn att det kan optimera koden som skapats för att lagra värde i ett cpu-register för snabbare bearbetning. Kompilatorn försöker om den kan göra det, men om inte är det samma som vanligt.
- externt externt betyder att det finns endast en global variabel med det namnet och alla filer som förklarar den som extern kommer att använda den lagringen. En fil kommer att deklarera den globalt som en vanlig variabel, där den tilldelas vid sammanställning.
- statisk lagringsspecifikator i C-källfiler betyder några olika saker.
- Namnet och lagringen exporteras inte till andra filer som kompileras samtidigt. Detta gör att varje fil kan ha identiska namn som inte kolliderar.
- Lagringen som skapats för variabeln skapas i det statiska lagringsområdet och initialiseras till 0 vid programstart, eller med ett uttryckligt värde.
- Initialisering av en statisk variabel utförs bara en gång . (vid sammanställningstid). Därefter sparas tilldelade värden under programmets livstid eller tills de ändras av en uppgift.
- Statisk lagring som deklareras i funktioner har funktionsomfång, men statisk allokering. Detta innebär att lagringen är permanent under programmets livslängd och inte skapas när funktionsstackramen tilldelas för funktionsanropet. Det behåller sitt värde genom flera funktionssamtal. Lagringen kvarstår trots att kodblocket återställs från stacken efter att den återvänt.
int accumulate( unsigned int x)
{
static unsigned int acc = 0;
acc = acc + x;
return acc;
}
- Ovanstående skulle återvända en löpande summa av dess ingång, eftersom var acc skulle behålla värdet genom varje samtal. acc kommer att initialiseras till 0 vid programbelastning.
- statiska variabler har adresser i RAM, och du kan skicka dem till funktioner med referens eller värde.
- Variabler med mindre omfång (definierade inuti funktioner) som har samma namn som en statisk variabel utanför det omfånget skuggar den statiska variabeln, samma som alla andra.
- statiska variabler kanske inte är exporteras till externa filer, så värden kan gå förlorade över kompileringsdomäner om de inte uttryckligen skickas som parametrar efter värde. (gotcha!)
- Liksom 4 kan andra filer inte komma åt statiska variabler som extern som de kunde med automatiska (normala) variabler. Det kommer inte att fungera, du kommer att få buggy-program som kraschar, och kompilatorn kan luras och missa den.
- Statiska variabler kan initialiseras vid deras deklaration, men initialiseringsvärdet måste vara ett konstant uttryck, utvärderbart vid sammanställningstid, inte ett värde som inte kan beräknas vid sammanställningstid. Du kan inte initialisera en statisk variabel med ett okänt värde, såsom en parametervariabel, eller resultatet av ett funktionsanrop som inte har inträffat vid kompileringstidpunkten.
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;
}
Statiska funktioner
- En statisk funktion i C har filomfång . En statisk funktion kan inte vara anropas av en annan fil i samma översättningsenhet. En översättningsenhet är all källkod som går in i en kompilator efter förbehandling för att kompileras samtidigt. Statiska funktioner kan inte komma åt statiska variabler eller anropa statiska funktioner från andra filer. Så om du vill begränsa åtkomsten till en funktion till den aktuella filen kan du göra den statisk. Endast en funktion med det namnet kan existera i den filen (som också gäller för vanliga funktioner), så ofta sätts verktygsfunktioner i sidhuvudfiler för att ingå i flera sammanställningar och rubriken skyddas med förprocessorkommandon för att inte ingå i någon kompileringsenhet mer än en gång. Alla standard C-biblioteksrubriker är fulla av globala funktioner, och de skyddas så att de bara sammanställs en gång i en sammanställning och är globala funktioner. Inga statiska funktioner. Statiska funktioner sägs ha intern länk vilket innebär att de inte kan ses i andra kompilerade moduler, även om de är länkade till samma slutprogram eller bibliotek. Om en funktion inte är statisk är den funktionen i C en global funktion och kommer att finnas tillgänglig i hela programmet globalt. Det betyder att du bara kan ha en funktion som heter skriva ut i hela programmet . För att komma runt detta, gör dina funktioner och variabler statiska, så kommer du inte att kämpa med namn.
- Funktionerna är globala och externa som standard , förutom i filen de är definierade i. Så du ser inte ordet extern används i C-källa med funktioner, eftersom den redan finns där implicit. Det är därför du kan anropa normala funktioner från valfri fil i översättningsenheten. De sägs ha extern länk vilket betyder att när de väl är länkade är de synliga och kan kallas av alla filer i modulen eller någon annan modul i det länkade programmet.
- En funktionsprototypdeklaration är en ”preliminär definition”, som är implicit extern . Kod efter att prototypdeklarationen skannats för första gången kan anropa funktionen så länge den fullständiga definitionen finns i den slutliga koden. Det betyder att en ”faktisk definition” faktiskt måste finnas eller att länkningsfasen misslyckas. Det är därför rubriker i C vanligtvis inte innehåller källkoden för funktionerna, de behövs inte för att kompilera, men är i länkfasen.
- En prototypdeklaration för statisk funktion är en ”preliminär definition”, som uttryckligen inte är extern . Den fullständiga definitionen måste finnas i den aktuella översättningsenheten (sammanställs samtidigt) eller annars misslyckas samlingen. Moderna C-kompilatorer kommer att syntetisera prototypen från definitionen så länge den förekommer tidigare än ett faktiskt funktionsanrop. Så kallade ”framåtriktade deklarationer” tillåter användning av preliminära definitioner med den faktiska definitionen senare och har olika användningsområden i datastrukturer och i organiseringen av bibliotek.
- Den första definitionen av en filsignatur är den som används för hela programmet, inklusive statisk eller extern. När en funktion först har definierats, om den deklareras initialt som statisk, kommer den alltid att vara statisk, även om den omdefineras senare utan det statiska nyckelordet. Om deklareras initialt externt (standard) kan det inte omdefinieras som statiskt.
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"
- Funktioner som definierats i blockomfång kan inte förklaras statiska. Endast statiska funktionsdefinitioner för filomfång kan göras utanför vilket block som helst. Detta är vettigt ur ett logiskt perspektiv, eftersom filomfattningen inte kan göras mindre än hela filen. Så definiera en statisk funktion, eller åtminstone prototypen, mycket tidigt i filen.
- Statisk hänvisar till funktionen, inte returtypen . Du kan placera det statiska nyckelordet efter returtypen om du vill, men om du gör det är du konstig och du kommer att förvirra människor. Returvärdet är inte statiskt, funktionen är.
- En statisk funktionsdefinition åsidosätter inte en global definierad före den i samma fil eller i en inkluderad fil. Om det redan finns en funktion med det namnet definierat kan du inte omdefiniera den med en statisk funktion eller någon samma namnfunktion.
C byter inte namn på funktioner och variabler som C ++ gör, så det stöder inte överbelastning av funktioner. C ++ “manglar” funktionsnamnen med ett kodat namn som indikerar flera extra typer av data, till exempel om det är en del av en klass eller vad dess parametrar är osv. Så i C frånvarande det statiska nyckelordet kanske du bara har en funktion av varje unikt namn i ett program, oavsett hur många filer eller bibliotek det medför.
Så vad gör du om du vill ändra din funktion för en redan existerande föregående?
Tja vad smarta C-kodare gör är att komma med ett annat namn för sin funktion. Men det finns ett sätt att ”lura” kompilatorn genom att förebyggande ändra källtexten med förprocessorn.
Exempel: Någon idiot skrev en int sort( char** Array)
-funktion i sitt bibliotek och gjorde det globalt, och det är buggy och gör inte exakt vad du vill, för det gör att siffror kommer efter bokstäver eller något, och T-orden är alltid första, av någon anledning.
Du vill använd biblioteket men behöver fixa funktionen, och du har bara rubrikerna och det kompilerade biblioteket, inte källkoden.
OK> så en ”speciell” rubrik görs som ersätter all förekomst av ” sortera ”med” dåligt\_sort ”i rubriken, importerar sedan din kod och ersätter alla förekomster av” sortera ”med” god\_sort ”. “Good\_sort” definieras helt i good\_sort.h, men är markerat statiskt så det är bara känt i filen som det ingår i.
/* good\_sort.h */
#ifndef \_GOOD\_SORT\_H
#define \_GOOD\_SORT\_H
static int good\_sort(char** Array)
{
... //code here
return numsorted;
}
#endif
En definitionskonsol läggs till för att se till att den inte ingår två gånger.
/*-----------------------------------*/
/* 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 */
Lite skitfest men tanken är att ringa din funktion istället för den dåliga av renam ing den till “good\_sort” och kallar det istället. (men bara i den här filen – statisk ).