Cel mai bun răspuns
Nu confundați un tip (cum ar fi int
) cu alte aspecte ale declarațiilor (de exemplu, o clasă de stocare ca static
).
Adică, în:
int x;
static int y;
x
și y
au același tip, int
(termenul „ tip date” este mai puțin utilizat în C și C ++; totuși nu este greșit).
Cuvântul cheie static
are trei semnificații diferite în C. În exemplul de mai sus, indică acea variabilă y
este „privată” pentru acea unitate de traducere particulară (deoarece unitatea de traducere poate fi considerată ca un fișier sursă după toate #include
directive au fost procesate). Deci, o variabilă y
declarată într-o altă unitate de traducere este distinctă de aceasta.
Iată un exemplu de al doilea sens al static
în C:
void f() {
static int n = 2;
...
}
Această statică înseamnă variabila n
este partajat între toate invocațiile f()
și rămâne în existență chiar și după revenirea f()
(ați putea, de exemplu, întoarceți-i un indicator). Inițializarea n
la 2
numai are loc înainte de pornirea programului în C (pe prima invocare a f()
în C ++). Deci, a doua (și ulterior) dată f()
este invocată, n
va păstra orice valoare a avut înainte (până când programul o modifică în mod explicit din nou ).
Al treilea sens este mai puțin comun (și, cred, mai puțin cunoscut):
void g(double x[static 5]) {
...
}
Acest lucru indică faptul că poate fi apelat numai cu un pointer la prima dintre cel puțin 5 double
în formarea matricei.
EDIT: S-a remediat explicația locală inițializare statică ca (vezi comentariul lui Jesse Pollard).
Răspuns
Static este opusul dinamic. Huh? Înseamnă că memoria alocată pentru acea variabilă nu se mișcă în memorie. De asemenea, înseamnă că în apelurile repetate către funcții care accesează acea variabilă, nu se creează noi copii shadow ale variabilei; este utilizată variabila originală și orice altă funcție care accesează acea variabilă la adresa respectivă o poate modifica sau citi. Nu este în sine o variabilă globală; scopul său rămâne același cu locul și modul în care a fost definit. Ar putea fi, totuși. Ar fi o eroare să încercați să definiți o altă variabilă statică cu același nume în același fișier sau una inclusă într-o aplicație.
Luați în considerare o funcție simplă C add:
int add(int a, int b)
{
static int count = 0;
static int last = 0;
count++;
last = a + b;
printf( "a:\t\%d \t\t b:\t\%d\n", a, b );
printf( "count:\t\%d \t\t last:\t\%d\n", count, last)
return last;
}
numărul și ultimele sunt definite statice. Asta înseamnă că valorile puse în ele persistă pe mai multe apeluri de adăugat. count și last sunt inițializate la zero, dar apoi nu sunt resetate la zero la fiecare apel. Observați că sfera numărării și a ultimului se află numai în funcția add. Este posibil să nu fie partajate cu alte funcții sau să fie accesate în afara adăugării, așa că pentru a ajunge la ele trebuie să le imprimați din interiorul funcției. Alte funcții ar putea avea număr identic și ultimele varuri statice și nu ar interacționa niciodată.
Acum uitați-vă la acest program de testare:
#include
static int count = 5;
static int last = 0;
int add(int a, int b)
{
static int count = 0;
static int last = 0;
count++;
last = a + b;
printf( "a:\t\%d \t\t b:\t\%d\n", a, b );
printf( "count:\t\%d \t\t last:\t\%d\n", count, last)
return last;
}
int main(int argc, char**argv )
{
static int count = 10;
static int last = 0;
int i;
int a=1, b=1;
for(i = 0 ; i < count ; i++)
{
a = add(a, b);
b = add(a, last);
last = add(a, b);
}
printf( "a:\t\%d \t\t b:\t\%d\n", a, b );
printf( "count:\t\%d \t\t last:\t\%d\n", count, last);
return 0;
}
Trei sunt 3 seturi de variabile statice număr și ultim; toate sunt separate. Mai întâi sunt globali, nu sunt folosiți niciodată aici. main
are propriul set pe care îl folosește, deoarece varurile sale locale umbresc globurile. add
are propriul său set care umbrește atât principalul, cât și globurile cu același nume.
Definiții ale funcțiilor statice sunt un alt tip de lucruri. Cuvântul static indică faptul că funcția este vizibilă numai în fișierul care este compilat de la sursa unde funcția este definită. Acesta este fie fișierul sursă („.c”) , fie un antet („.h) fișier inclus în acesta. Acest lucru poate fi necesar dacă fișierele obiect pe care le utilizați au mai multe versiuni ale unei funcții cu același nume, (cum ar fi adăugare, tipărire, eroare, ...), astfel încât combinarea fișierelor obiect („. O”) împreună ca module nu provoacă coliziuni de denumire.