Beste svaret
Som vi vet at funksjonene som er definert i en fil, kan nås i en annen fil. Hvis vi vil begrense at funksjoner ikke må kalles i en annen fil, kan vi gjøre dem statiske.
Derfor er statiske funksjoner de funksjonene som kan kalles i samme fil der de definerer .
Vi kan definere en funksjon statisk ved å bruke følgende syntaks
static return\_type function\_name(arguments)
{
function\_body;
}
Her er en funksjon for å finne kvadratrot av et gitt tall
static long int getSquare(int num){
return (num*num);
}
Program for å demonstrere eksempel på statisk funksjon 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;
}
Utgang
Enter an integer number: 36
Square of 36 is 1296.
Hvorfor er de statiske funksjonene nødvendige?
Siden funksjoner brukes til å gjenbruke koden (dvs koden du har skrevet kan få tilgang til i en annen fil ved å sette dem i funksjonene ), men når du vil definere noen funksjoner som ikke skal kunne deles (kalles) i en annen fil .
Statiske funksjoner er også nyttige for å håndtere problem med erklæringskonflikt – hvis det er to funksjoner i to forskjellige filer med samme navn, vil funksjonserklæringen være i konflikt. Vi kan gjøre dem statiske.
For å oppfylle slike krav kan vi gjøre dem statiske .
Svar
Kort svar: Det betyr at funksjonsnavnet bare er synlig og kan kalles i filen som kompileres for øyeblikket. Andre filer som er samlet separat, vil ikke se funksjonsnavnet eller kunne ringe det. Deretter kan de ha sine egne statiske funksjoner med samme navn. Dette unngår navnekollisjon i filinneslutninger, og i innkobling av objektfiler og binære biblioteker.
Det er fire forskjellige lagringsklasser for lagring i C.
- auto (automatisk) dette er «vanlig» (standard) og bruker nøkkelordet auto , men er vanligvis ikke spesifisert da det er standard
- register er et «hint» til kompilatoren at det kan optimalisere koden som er opprettet for å lagre verdi i et CPU-register for raskere behandling. Kompilatoren vil prøve om den kan gjøre det, men hvis ikke er det det samme som vanlig.
- ekstern ekstern betyr at det er bare én global variabel med det navnet, og alle filer som erklærer den som ekstern, vil bruke den lagringen. Én fil vil erklære den globalt som en vanlig variabel, der den tildeles ved kompilering.
- statisk lagringsspesifikator i C-kildefiler betyr noen forskjellige ting.
- Navnet og lagringen eksporteres ikke til andre filer som blir samlet samtidig. Dette gjør at hver fil kan ha identiske navn som ikke kolliderer.
- Lagringen som er opprettet for variabelen, opprettes i det statiske lagringsområdet og initialiseres til 0 ved programstart, eller med en eksplisitt verdi.
- Initialisering av en statisk variabel utføres bare en gang . (ved samlingstidspunktet). Deretter holdes verdier som tildeles hele livet eller til de endres av en oppgave.
- Statisk lagring deklarert i funksjoner har funksjonsomfang, men statisk tildeling. Dette betyr at lagringen er permanent i løpet av programmet, og ikke opprettes når funksjonsstakrammen er allokert til funksjonsanropet. Den beholder verdien gjennom flere funksjonsanrop. Lagringen vedvarer selv om kodeblokken gjenopprettes fra bunken etter at den kommer tilbake.
int accumulate( unsigned int x)
{
static unsigned int acc = 0;
acc = acc + x;
return acc;
}
- Ovennevnte ville returnere en løpende oversikt over inngangen, da var acc vil beholde verdien gjennom hver samtale. acc vil initialiseres til 0 ved programbelastning.
- statiske variabler har adresser i RAM, og du kan sende dem til funksjoner ved referanse eller verdi.
- Variabler med mindre omfang (definert i funksjoner) som har samme navn som en statisk variabel utenfor det omfanget, skygger for den statiske variabelen, samme som alle andre.
- statiske variabler er kanskje ikke eksportert til eksterne filer, slik at verdier kan gå tapt på tvers av kompileringsdomener hvis de ikke eksplisitt sendes som parametere etter verdi. (gotcha!)
- Som 4 kan andre filer ikke få tilgang til statiske variabler som extern som de kunne med automatiske (normale) variabler. Det vil ikke fungere, du vil få buggyprogrammer som krasjer, og kompilatoren kan bli lurt og savne den.
- Statiske variabler kan initialiseres ved erklæringen, men initialiseringsverdien må være et konstant uttrykk, evaluerbart ved kompileringstid, ikke en verdi som ikke kan beregnes på kompileringstid. Du kan ikke initialisere en statisk variabel med en ukjent verdi, for eksempel en parametervariabel, eller resultatet av en funksjonsanrop som ikke har skjedd på kompileringstidspunktet.
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;
}
Statiske funksjoner
- En statisk funksjon i C har filomfang . En statisk funksjon kan ikke være kalt av en annen fil i samme oversettelsesenhet. En oversettelsesenhet er all kildekode som går inn i en kompilator etter forhåndsbehandling for å bli kompilert samtidig. Statiske funksjoner kan ikke få tilgang til statiske variabler eller ringe statiske funksjoner fra andre filer. Så hvis du vil begrense tilgangen til en funksjon til den nåværende filen, kan du gjøre den statisk. Bare en funksjon med det navnet kan eksistere i den filen (som også gjelder for vanlige funksjoner), så ofte settes verktøyfunksjoner i topptekstfiler, for å inkluderes i flere samlinger, og toppteksten beskyttes med kommandoer for prosessoren for å ikke inkluderes i en hvilken som helst kompilasjonsenhet mer enn en gang. Alle standard C-bibliotekets overskrifter er fulle av globale funksjoner, og de er bevoktet slik at de bare blir samlet en gang i en samling, og er globale funksjoner. Ingen statiske funksjoner. Statiske funksjoner sies å ha ‘intern kobling’ , noe som betyr at de ikke kan sees i andre kompilerte moduler, selv om de er koblet til det samme endelige programmet eller biblioteket. Hvis en funksjon ikke er statisk , er C-funksjonen en global funksjon og vil være tilgjengelig i hele programmet globalt. Dette betyr at du bare kan ha en funksjon kalt utskrift i hele programmet . For å komme deg rundt dette, gjør funksjonene og variablene dine statiske, så får du ikke et sammenstøt med navn.
- Funksjonene er globale og eksterne som standard , bortsett fra i filen de er definert i. Så du ser ikke ordet extern brukt i C-kilde med funksjoner, fordi den allerede er der implisitt. Dette er grunnen til at du kan ringe normale funksjoner fra hvilken som helst fil i oversettelsesenheten. De sies å ha ekstern kobling som betyr at når de først er koblet inn, er de synlige og kan kalles av en hvilken som helst fil i modulen, eller en hvilken som helst annen modul i det koblede programmet.
- En funksjonsprototypedeklarasjon er en “foreløpig definisjon”, som er implisitt ekstern . Kode etter at prototypedeklarasjonen er skannet for første gang, kan ringe til funksjonen så lenge den fulle definisjonen finnes i den endelige koden. Det betyr at en «faktisk definisjon» faktisk må eksistere, ellers vil koblingsfasen mislykkes. Dette er grunnen til at overskrifter i C vanligvis ikke inneholder kildekoden for funksjonene, de er ikke nødvendige for å kompilere, men er i koblingsfasen.
- En prototypedeklarasjon for statisk funksjon er en «foreløpig definisjon», som eksplisitt ikke er ekstern . Fullstendig definisjon må være til stede i den gjeldende oversettelsesenheten (samlet samtidig), ellers vil kompilering mislykkes. Moderne C-kompilatorer vil syntetisere prototypen fra definisjonen så lenge den forekommer tidligere enn en faktisk funksjonsanrop. Såkalte «forward declarations» tillater bruk av foreløpige definisjoner med den faktiske definisjonen senere, og har forskjellige bruksområder i datastrukturer og i organisering av biblioteker.
- Den første definisjonen av en filsignatur er den som brukes for hele programmet, inkludert statisk eller ekstern. Når en funksjon først er definert, hvis den først blir erklært som statisk, vil den alltid være statisk, selv om den blir definert senere uten det statiske nøkkelordet. Hvis er opprinnelig erklært ekstern (standard), kan den ikke omdefineres som statisk.
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"
- Funksjoner definert i blokkomfang kan ikke erklæres statisk. Bare definisjoner for statisk funksjon for filomfang kan gjøres utenfor en hvilken som helst blokk. Dette gir mening fra et logisk perspektiv, ettersom filomfanget ikke kan gjøres mindre enn hele filen. Så definer en statisk funksjon, eller i det minste prototypen, veldig tidlig i filen.
- Statisk refererer til funksjonen, ikke returtypen . Du kan plassere det statiske nøkkelordet etter returtypen hvis du ønsker det, men hvis du gjør det, er du rar, og du vil forvirre folk. Returverdien er ikke statisk, funksjonen er.
- En definisjon av statisk funksjon overstyrer ikke en global definert før den i samme fil eller i en inkludert fil. Hvis det allerede er en funksjon med dette navnet definert, kan du ikke definere den på nytt med en statisk funksjon eller en hvilken som helst funksjon med samme navn.
C omdøper ikke funksjoner og variabler internt slik C ++ gjør, så den støtter ikke overbelastning av funksjoner. C ++ “mangler” funksjonsnavnene med et kodet navn som indikerer flere ekstra typer data, for eksempel om det er en del av en klasse eller hva parametrene er osv. Så i C fraværende det statiske nøkkelordet, har du kanskje bare en funksjon av hvert unike navn i et program, uansett hvor mange filer eller biblioteker det innebærer.
Så hva gjør du hvis du vil endre funksjonen din for en allerede eksisterende tidligere?
Vel, hva smarte C-kodere gjør er å komme opp med et annet navn for deres funksjon. Men det er en måte å lure kompilatoren ved forebyggende å endre kildeteksten med forprosessoren.
Eksempel: En eller annen idiot skrev en int sort( char** Array)
-funksjon i biblioteket sitt og gjorde det globalt, og det er buggy og gjør ikke akkurat det du vil, fordi det får tall til å komme etter bokstaver eller noe, og T-ordene er alltid først, av en eller annen grunn.
Du vil bruk biblioteket, men trenger å fikse funksjonen, og du har bare overskriftene og det kompilerte biblioteket, ikke kildekoden.
OK> så det blir laget en «spesiell» overskrift som erstatter all forekomst av » sorter «med» bad\_sort «i overskriften, importerer deretter koden din og erstatter alle forekomster av» sort «med» good\_sort «. “Good\_sort” er definert fullstendig i good\_sort.h, men er markert statisk, så det er bare kjent i filen den er inkludert i.
/* good\_sort.h */
#ifndef \_GOOD\_SORT\_H
#define \_GOOD\_SORT\_H
static int good\_sort(char** Array)
{
... //code here
return numsorted;
}
#endif
En definisjonsbrakett legges til for å sikre at den ikke er inkludert to ganger.
/*-----------------------------------*/
/* 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 */
Litt av en crapfest, men ideen er å ringe din funksjon i stedet for den dårlige av renam ing den til “good\_sort” og kaller det i stedet. (men bare i denne filen – statisk ).