Ce este o funcție statică în C?

Cel mai bun răspuns

Știm că funcțiile definite într-un fișier pot fi accesate într-un alt fișier. Dacă dorim să restricționăm faptul că funcțiile nu trebuie să fie apelate într-un alt fișier, le putem face statice.

Prin urmare, funcțiile statice sunt acele funcții care pot fi apelate în același fișier în care definesc .

Putem defini o funcție statică utilizând următoarea sintaxă

static return\_type function\_name(arguments)

{

function\_body;

}

Iată o funcție pentru a găsi rădăcina pătrată a unui număr dat

static long int getSquare(int num){

return (num*num);

}

Program pentru a demonstra un exemplu de funcție statică în limbajul 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;

}

Ieșire

Enter an integer number: 36

Square of 36 is 1296.

De ce sunt necesare funcțiile statice?

Deoarece funcțiile sunt utilizate pentru refolosirea codului (adică codul pe care l-ați scris poate accesa într-un alt fișier punându-le în funcții ), dar când doriți să definiți câteva funcțiile care nu ar trebui să poată fi partajate (apelabile) într-un alt fișier .

Funcțiile statice sunt, de asemenea, utile pentru a gestiona problema conflictului de declarație – dacă există două funcții în două fișiere diferite cu același nume, declarația funcției va fi conflictuală. Le putem face statice.

Pentru a îndeplini astfel de cerințe, le putem să le facă statice .

Răspuns

Răspuns scurt: Înseamnă că numele funcției este vizibil și apelabil numai în fișierul care este compilat în prezent. Alte fișiere compilate separat nu vor vedea numele funcției și nici nu o vor putea apela. Ulterior, pot avea propriile funcții statice cu același nume. Acest lucru evită ciocnirile de nume în incluziunile de fișiere și în conectarea fișierelor obiect și a bibliotecilor binare.

Există 4 clase de stocare diferite pentru stocare în C.

  • auto (automat) acesta este „regulat” (implicit) și folosește cuvântul cheie auto , dar este de obicei nu este specificat deoarece este implicit
  • register este un „indiciu” pentru compilator că poate optimiza codul creat pentru a stoca valoare într-un registru CPU pentru procesare mai rapidă. Compilatorul va încerca dacă poate să facă acest lucru, dar dacă nu, este la fel ca în mod obișnuit.
  • extern extern înseamnă că există doar o singură variabilă globală cu acest nume și toate fișierele care o declară ca externă vor folosi acea stocare. Un fișier îl va declara global ca o variabilă obișnuită, unde va fi alocat la compilare.
  • static specificator de stocare în fișiere sursă C câteva lucruri diferite.

  1. Numele și stocarea nu sunt exportate în alte fișiere care sunt compilate în același timp. Acest lucru permite fiecărui fișier să aibă nume identice care nu se confruntă.
  2. Spațiul de stocare creat pentru variabilă este creat în zona de stocare statică și inițializat la 0 la începutul programului sau cu o valoare explicită.
  3. Inițializarea unei variabile statice se efectuează o singură dată . (la momentul compilării). Ulterior, valorile alocate sunt păstrate pe toată durata programului sau până când sunt modificate printr-o atribuire.
  4. stocarea statică declarată în interiorul funcțiilor are sfera funcției, dar alocarea statică. Aceasta înseamnă că stocarea este permanentă pe toată durata de viață a programului și nu este creată atunci când cadrul alocării funcției este alocat pentru apelul funcțional. Își păstrează valoarea prin apeluri cu funcții multiple. Stocarea persistă chiar dacă blocul de cod este recuperat din stivă după ce revine.

int accumulate( unsigned int x)

{

static unsigned int acc = 0;

acc = acc + x;

return acc;

}

  1. Cele de mai sus ar reveni o sumă de rulare a intrării sale, deoarece var acc ar păstra valoarea prin fiecare apel. acc va fi inițializat la 0 la încărcarea programului.
  2. variabilele statice au adrese în RAM și le puteți trimite în funcții prin referință sau valoare.
  3. Variabilele cu un domeniu mai mic (definite în interiorul funcțiilor) care poartă același nume ca o variabilă statică în afara acelei zone de acoperire umbrează variabila statică, la fel ca oricare alta.
  4. variabilele statice pot să nu fie exportate în fișiere externe, astfel încât valorile pot fi pierdute în toate domeniile de compilare dacă nu sunt trimise în mod explicit ca parametri în funcție de valoare. (gotcha!)
  5. La fel ca 4, alte fișiere nu pot accesa variabile statice ca extern așa cum ar putea cu variabile automate (normale). Nu va funcționa, veți obține programe buggy care se blochează, iar compilatorul ar putea fi păcălit și ratat.
  6. Variabilele statice pot fi inițializate la declarația lor, dar valoarea de inițializare trebuie să fie o expresie constantă, evaluabilă în timpul compilării, nu o valoare care nu poate fi calculată în timpul compilării. Nu puteți inițializa o variabilă statică cu o valoare necunoscută, cum ar fi o variabilă de parametru sau rezultatul unui apel de funcție care nu a avut loc la momentul compilării.

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;

}

Funcții statice

  1. O funcție statică în C are domeniul de aplicare al fișierului . O funcție statică nu poate fi apelat de un alt fișier din aceeași unitate de traducere. O unitate de traducere este tot codul sursă care intră într-un compilator după preprocesare pentru a fi compilat simultan. Funcțiile statice nu pot accesa variabile statice sau pot apela funcții statice din alte fișiere. Deci, dacă doriți să limitați accesul la o funcție la fișierul curent, îl puteți face static. Numai o funcție cu acel nume poate exista în acel fișier (care se menține și pentru funcțiile obișnuite), așa că deseori funcțiile utilitare sunt plasate în fișiere antet, pentru a fi incluse în mai multe compilații, iar antetul este protejat cu comenzi pre-procesor pentru a nu să fie inclus în orice unitate de compilare de mai multe ori. Toate anteturile standard ale bibliotecii C sunt pline de funcții globale, iar acestea sunt păstrate astfel încât să fie compilate o singură dată într-o compilație și să fie funcții globale. Fără funcții statice. Se spune că funcțiile statice au ‘linkage intern’ ceea ce înseamnă că nu pot fi văzute în alte module compilate, chiar dacă sunt conectate în același program final sau bibliotecă. Dacă o funcție nu este statică , atunci în C acea funcție este o funcție globală și va fi disponibilă în întregul program la nivel global. Aceasta înseamnă că puteți avea o singură funcție numită print în întregul program . Pentru a rezolva această problemă, faceți funcțiile și variabilele statice și nu veți avea o ciocnire de nume.
  2. Funcțiile sunt globale și externe în mod implicit , cu excepția fișierului în care sunt definite. Deci, nu vedeți cuvântul extern utilizat în sursa C cu funcții, deoarece este deja implicit acolo. Acesta este motivul pentru care puteți apela funcții normale din orice fișier din unitatea de traducere. Se spune că au „legătură externă” , adică odată conectate, acestea sunt vizibile și apelabile de orice fișier din modul sau de orice alt modul din programul conectat.
  3. O declarație prototip de funcție este o „definiție provizorie”, care este implicit externă . Codul după ce declarația prototipului este scanată pentru prima dată poate apela funcția atâta timp cât definiția completă există în codul final. Asta înseamnă că trebuie să existe o „definiție reală” sau că faza de legătură va eșua. Acesta este motivul pentru care anteturile din C nu conțin de obicei codul sursă pentru funcții, nu sunt necesare pentru a compila, dar sunt în faza de conectare.
  4. O declarație prototip de funcție statică este o „definiție provizorie”, care nu este în mod explicit externă . Definiția completă trebuie să fie prezentă în unitatea de traducere curentă (compilată în același timp) sau compilarea va eșua. Compilatoarele moderne C vor sintetiza prototipul din definiție, atâta timp cât acesta apare mai devreme decât un apel funcțional efectiv. Așa-numitele „declarații directe” permit utilizarea definițiilor provizorii cu definiția actuală ulterior și au diverse utilizări în structurile de date și în organizarea bibliotecilor.
  5. Prima definiție a semnăturii unui fișier este cea utilizată pentru întregul program, inclusiv static sau extern. Odată ce o funcție este definită pentru prima dată, dacă este declarată inițial ca statică, va fi întotdeauna statică, chiar dacă este redefinită ulterior fără cuvântul cheie static. Dacă inițial este declarat extern (implicit) nu poate fi redefinit ca static.

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. Funcțiile definite în domeniul blocurilor nu pot fi declarate statice. Numai definițiile funcției statice ale sferei fișierelor pot fi făcute în afara oricărui bloc. Acest lucru are sens dintr-o perspectivă logică, deoarece domeniul de aplicare al fișierului nu poate fi redus decât întregul fișier. Deci, definiți o funcție statică sau cel puțin prototipul, foarte devreme în fișier.
  2. Static se referă la funcție, nu la tipul de returnare . Puteți plasa cuvântul cheie static după tipul de returnare, dacă doriți, dar dacă faceți acest lucru, sunteți ciudat și veți încurca oamenii. Valoarea returnată nu este statică, funcția este.
  3. O definiție a funcției statice nu va suprascrie un unul global definit înainte de acesta în același fișier sau într-un fișier inclus. Dacă există deja o funcție cu acel nume definită, nu o puteți redefini cu o funcție statică sau cu orice funcție cu același nume.

C nu redenumește intern funcțiile și variabilele așa cum face C ++, deci nu acceptă supraîncărcarea funcției. C ++ „gestionează” numele funcțiilor cu un nume codat care indică mai multe tipuri suplimentare de date, cum ar fi dacă face parte dintr-o clasă sau care sunt parametrii săi etc. Deci, în C absent cuvântul cheie static, este posibil să aveți doar o funcție de fiecare nume unic dintr-un program, indiferent câte fișiere sau biblioteci ar presupune.

Deci, ce faceți dacă doriți să vă schimbați funcția pentru una anterioară deja existentă?

Ei bine, ceea ce fac coderii C inteligenți este să vină cu un nume diferit pentru funcția lor. Dar există o modalitate de a „păcăli” compilatorul schimbând preventiv textul sursă cu preprocesorul.

Exemplu: Un idiot a scris o funcție int sort( char** Array) în biblioteca sa și a făcut-o globală, și este buggy și nu face exact ceea ce doriți, deoarece face ca numerele să vină după litere sau ceva, iar cuvintele T sunt întotdeauna primele, dintr-un anumit motiv.

utilizați biblioteca, dar trebuie să remediați funcția și aveți doar anteturile și biblioteca compilată, nu codul sursă.

OK> deci se face un antet „special” care înlocuiește toată instanța de „ sortează ”cu„ bad\_sort ”în antet, apoi importă codul tău și înlocuiește toate instanțele de„ sort ”cu„ good\_sort ”. „Good\_sort” este definit complet în good\_sort.h, dar este marcat static, deci este cunoscut doar în fișierul în care este inclus.

/* good\_sort.h */

#ifndef \_GOOD\_SORT\_H

#define \_GOOD\_SORT\_H

static int good\_sort(char** Array)

{

... //code here

return numsorted;

}

#endif

Se adaugă o paranteză de protecție pentru definiție pentru a vă asigura că nu este inclusă de două ori.

/*-----------------------------------*/

/* 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 */

Un pic de crapfest, dar ideea este să vă apelați funcția în locul celui rău de renam introducându-l la „good\_sort” și apelând la asta. (dar numai în acest fișier – static ).

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *