C'de “statik” ne demektir?


1135

staticC kodu farklı yerlerde kullanılan kelimeyi gördüm ; (uygulama nesneler arasında paylaşılır) C # statik bir işlev / sınıf gibi mi?



15
"Bir C programında" başlığını @Lundin'den kaldırmanın nedeni nedir? C etiketinin varlığında biraz gereksizdir , ancak etiketleri incelemeden sınıflandırmayı daha hızlı görmeme izin verir. Bu fazlalık, soruna, statik veya Google arama gibi diğer diller hakkında da sorular içerebilecek bir yönden ulaştığımda çok rahat .
Palec

5
@Palec Etiket listesinde bulunan öğelerin başlıkta gereksiz olduğu bir SO politikası vardır. Site, gerçek web sitesine otomatik olarak C ekleyecektir. "C statik" için bir Google, bu yanıtı en iyi hit olarak verir. Bunun değiştirilmesinin nedeni, bu sorunun artık SO C dili SSS'sinin bir parçası olması ve eklenen tüm gönderilerin biraz parlatılmasıdır.
Lundin

1
@Lundin "C" başlığında kalmayı tercih ederim, çünkü SO başlığa sadece bir etiket ekler (en yaygın olan?). Ya bir gün "sözdizimi" C'den daha fazla soruya ulaşırsa (bu, diller arası bir şey olduğu için)? Ben açık davranış kullanmak istiyorum :-) Düzenleme: ah ama aksi söyleyerek bir meta soru var: meta.stackexchange.com/questions/19190/…
Ciro Santilli at 病毒 审查 六四 事件 法轮功

1
Bu Quora'da bulduğum bir açıklama. Kesinlikle okumaya değer!
nalzok

Yanıtlar:


1519
  1. Bir işlevin içindeki statik değişken, değerini çağrımlar arasında tutar.
  2. Statik global değişken veya işlev yalnızca bildirildiği dosyada "görülür"

(1) bir acemi iseniz daha yabancı bir konudur, işte bir örnek:

#include <stdio.h>

void foo()
{
    int a = 10;
    static int sa = 10;

    a += 5;
    sa += 5;

    printf("a = %d, sa = %d\n", a, sa);
}


int main()
{
    int i;

    for (i = 0; i < 10; ++i)
        foo();
}

Bu yazdırır:

a = 15, sa = 15
a = 15, sa = 20
a = 15, sa = 25
a = 15, sa = 30
a = 15, sa = 35
a = 15, sa = 40
a = 15, sa = 45
a = 15, sa = 50
a = 15, sa = 55
a = 15, sa = 60

Bu, bir işlevin çağrılar arasında bir durum tutması gerektiğinde ve genel değişkenleri kullanmak istemediğiniz durumlarda kullanışlıdır. Ancak, bu özellik çok az kullanılmalıdır - kodunuzu iş parçacığı açısından güvenli ve anlaşılmasını zorlaştırır.

(2) Yaygın olarak "erişim kontrolü" özelliği olarak kullanılır. Bazı işlevleri uygulayan bir .c dosyanız varsa, bu genellikle kullanıcılara yalnızca birkaç "genel" işlevi gösterir. Diğer işlevler static, kullanıcının bunlara erişemeyeceği şekilde yapılmalıdır. Bu kapsülleme, iyi bir uygulama.

Wikipedia alıntısı :

C programlama dilinde, kapsamlarını içeren dosyaya ayarlamak için global değişkenler ve işlevlerle statik kullanılır. Yerel değişkenlerde statik, değişkeni otomatik olarak ayrılan bellek yerine statik olarak ayrılan bellekte saklamak için kullanılır. Dil, her iki bellek türünün uygulanmasını gerektirmezken, otomatik olarak ayrılan bellek normalde geçici bir çağrı yığını olarak uygulanırken, statik olarak ayrılan bellek genellikle programın veri bölümünde ayrılır.

Ve ikinci sorunuza cevap vermek için C # 'daki gibi değil.

Ancak C ++ ' staticda sınıf özniteliklerini (aynı sınıftaki tüm nesneler arasında paylaşılan) ve yöntemleri tanımlamak için de kullanılır. C'de sınıf yoktur, bu nedenle bu özellik önemsizdir.


179
Pax, OP statik hakkında bilmiyor, bu yüzden onu derleme birimleri ve dosyalar arasındaki farka batırmayı mı öneriyorsun? :-)
Eli Bendersky

138
Derleme birimi, derleyicinin gördüğü tek bir dosyadır. .C dosyanız başka .c dosyaları içerebilir, ancak önişlemci kapsamları sıraladıktan sonra derleyici sonunda yalnızca tek bir "derleme birimi" görür.
Eli Bendersky

81
@robUK: derleyici .h dosyalarını bile bilmiyor - bunlar ön işlemcideki .c dosyalarıyla birleştiriliyor. Yani evet, tüm başlıkları içeren .c dosyasının tek bir derleme birimi olduğunu söyleyebilirsiniz.
Eli Bendersky

6
@TonyD belki kafa karıştırıcı, ama derleme böyle çalışır. Genellikle bir .cve bir grup başlık dosyası olabilir, ancak şeytan her zaman tipik olmayan şeydedir.
peterph

7
@TonyD Derleyici derleme yapar. Önişlemci önişlem yapar. Takım zincirini 'derleyici' olarak adlandırmak ne olduğunu ya da ne yaptığını değiştirmez.
Miles Rout

231

Burada ele alınmayan bir kullanım daha vardır ve bu, bir işleve bağımsız değişken olarak dizi türü bildiriminin bir parçası olarak kullanılır:

int someFunction(char arg[static 10])
{
    ...
}

Bu bağlamda, bu işleve iletilen bağımsız değişkenlerin, chariçinde en az 10 öğe bulunan bir tür dizi olması gerektiğini belirtir . Daha fazla bilgi için soruma buradan bakın .


3
C'nin dizi argümanları olduğunu düşünmedim mi? Linus Torvalds bunu yapan insanlar hakkında öfkeyle sıralanıyor.
suprjami

13
@jamieb: C dizi bağımsız değişkeni değil, fonksiyon beklediği bu spesifik sözdizimi aracı arg[0]üzerine arg[9](aynı zamanda fonksiyon bir boş işaretçisi kabul etmez anlamına gelir) değerlerine sahip. Derleyiciler bu bilgileri bir şekilde optimizasyon için kullanabilirler ve statik analizörler bu bilgiyi, işleve hiçbir zaman boş bir işaretçi (ya da söyleyebiliyorsa belirtilenden daha az öğeye sahip bir dizi) verilmesini sağlamak için bu bilgileri kullanabilir.
dreamlax

19
@Qix - Bu, staticC99'da verilen yeni aşırı yüklenmiş bir anlamdı . On yıldan fazla bir süredir, ancak tüm derleyici yazarları tüm C99 özelliklerini benimsemedi - bu yüzden C99 bir bütün olarak bilinmemektedir.
Happy Green Kid Naps

@suprjami "dizi bağımsız değişkenleri" ile ne demek istediğinizden% 100 emin değilim , ama demek isterseniz int arr[n];, o zaman C99'da eklenen bir VLA (değişken uzunluklu dizi) . Demek istediğin bu muydu?
RastaJedi

170

Kısa cevap ... duruma göre değişir.

  1. Statik tanımlı yerel değişkenler, işlev çağrıları arasındaki değerlerini kaybetmez. Başka bir deyişle, bunlar küresel değişkenlerdir, ancak tanımlandıkları yerel işleve dahil edilirler.

  2. Statik global değişkenler, tanımlandıkları C dosyasının dışında görünmez.

  3. Statik işlevler, tanımlandıkları C dosyasının dışında görünmez.


8
Peki "statik fonksiyon" ve "özel fonksiyon" aynı anlama geliyor mu? Benzer şekilde "statik global değişkenler" ve "özel global değişkenler" aynı şey midir?
user1599964

40
Bu C hakkındadır. C.'de özel / kamu yoktur
chris

19
@ user1599964 Her ne kadar privateC de yok , benzetmeniz iyi: statik belirli bir dosya için "özel" yapar. Ve C'deki dosyalar genellikle C ++ 'daki sınıflarla eşlenir.
Ciro Santilli 法轮功 病毒 审查 六四 事件 法轮功

67

Çok dosyalı değişken kapsam örneği

Burada statikin birden fazla dosyadaki fonksiyon tanımlarının kapsamını nasıl etkilediğini göstereceğim.

AC

#include <stdio.h>

/*
Undefined behavior: already defined in main.
Binutils 2.24 gives an error and refuses to link.
/programming/27667277/why-does-borland-compile-with-multiple-definitions-of-same-object-in-different-c
*/
/*int i = 0;*/

/* Works in GCC as an extension: https://stackoverflow.com/a/3692486/895245 */
/*int i;*/

/* OK: extern. Will use the one in main. */
extern int i;

/* OK: only visible to this file. */
static int si = 0;

void a() {
    i++;
    si++;
    puts("a()");
    printf("i = %d\n", i);
    printf("si = %d\n", si);
    puts("");
}

main.c

#include <stdio.h>

int i = 0;
static int si = 0;

void a();    

void m() {
    i++;
    si++;
    puts("m()");
    printf("i = %d\n", i);
    printf("si = %d\n", si);
    puts("");
}

int main() {
    m();
    m();
    a();
    a();
    return 0;
}

GitHub akış yukarı .

Derleyin ve çalıştırın:

gcc -c a.c -o a.o
gcc -c main.c -o main.o
gcc -o main main.o a.o

Çıktı:

m()
i = 1
si = 1

m()
i = 2
si = 2

a()
i = 3
si = 1

a()
i = 4
si = 2

yorumlama

  • siher dosya için bir tane olmak üzere iki ayrı değişken vardır
  • için tek bir paylaşılan değişken var i

Her zamanki gibi, kapsam ne kadar küçük olursa, o kadar iyidir, bu yüzden her zaman değişkenleri staticbildirebilirsiniz.

C programlamasında, dosyalar genellikle "sınıfları" temsil etmek için kullanılır ve staticdeğişkenler sınıfın özel statik üyelerini temsil eder.

Standartlar bunun hakkında ne diyor

C99 N1256 taslak 6.7.1 "Depolama sınıfı belirteçleri" static, bunun "depolama sınıfı belirleyicisi" olduğunu söylüyor .

6.2.2 / 3 "tanımlayıcıları Linkages" diyor staticima internal linkage:

Bir nesne veya işlev için dosya kapsamı tanımlayıcısının bildirimi, depolama sınıfı belirteci statik içeriyorsa, tanımlayıcı iç bağlantıya sahiptir.

ve 6.2.2 / 2 internal linkageörneğimizdeki gibi davrandığını söylüyor :

Bir programın tamamını oluşturan çeviri birimleri ve kitaplıklar kümesinde, dış bağlantıya sahip belirli bir tanımlayıcının her bildirimi aynı nesneyi veya işlevi gösterir. Bir çeviri biriminde, iç bağlantıya sahip bir tanımlayıcının her bildirimi aynı nesneyi veya işlevi gösterir.

Burada "çeviri birimi, önişlemeden sonra bir kaynak dosyasıdır.

GCC bunu ELF (Linux) için nasıl uygular?

İle STB_LOCALbağlanması.

Derlersek:

int i = 0;
static int si = 0;

ve sembol tablosunu şunlarla sökün:

readelf -s main.o

çıktı şunları içerir:

Num:    Value          Size Type    Bind   Vis      Ndx Name
  5: 0000000000000004     4 OBJECT  LOCAL  DEFAULT    4 si
 10: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    4 i

yani aralarındaki tek önemli fark bağlanmadır. Valueyalnızca .bssbölüme kaydırıldıklarından farklı olmasını bekliyoruz.

STB_LOCALhttp://www.sco.com/developers/gabi/2003-12-17/ch4.symtab.html adresindeki ELF spesifikasyonunda belgelenmiştir :

STB_LOCAL Yerel semboller, tanımlarını içeren nesne dosyasının dışında görünmez. Aynı ada sahip yerel semboller, birbirlerini etkilemeden birden fazla dosyada bulunabilir

temsil etmek için mükemmel bir seçimdir static.

Statik olmayan değişkenler STB_GLOBALve spesifikasyon şöyle diyor:

Bağlantı düzenleyicisi birkaç yeniden yerleştirilebilir nesne dosyasını birleştirdiğinde, aynı ada sahip birden çok STB_GLOBAL sembol tanımına izin vermez.

birden fazla statik olmayan tanımdaki bağlantı hataları ile uyumludur.

Optimizasyonu ile kranklarsak -O3, sisembol tamamen sembol tablosundan kaldırılır: yine de dışarıdan kullanılamaz. Neden optimizasyon olmadığında statik değişkenleri sembol tablosunda tutmalıyım? Herhangi bir şey için kullanılabilirler mi? Belki hata ayıklamak için.

Ayrıca bakınız

C ++ anonim ad alanları

C ++ 'da, statik yerine anonim ad alanlarını kullanmak isteyebilirsiniz, bu da benzer bir etki yaratır, ancak tür tanımlarını daha da gizler: Adsız / anonim ad alanları ve statik işlevler


39

Değişir:

int foo()
{
   static int x;
   return ++x;
}

İşlev 1, 2, 3, vb. Döndürür --- değişken yığın üzerinde değildir.

AC:

static int foo()
{
}

Bu, bu işlevin yalnızca bu dosyada kapsamı olduğu anlamına gelir. Yani ac ve bc farklı s'lere sahip olabilir foo()ve foo paylaşılan nesnelere maruz kalmaz. Bu yüzden ac'ta foo tanımladıysanız, ona b.cbaşka bir yerden veya başka bir yerden erişemezdiniz .

Çoğu C kütüphanesinde tüm "özel" işlevler statiktir ve çoğu "genel" değildir.


18
Yığında veya yığınta x'ten bahsettiği için +1. Statik bellek alanında.
Gob00st

1
@ Gob00st statik bellek alanı? "Veri Segmenti" demek istediniz ...?
Yousha Aleayoub

24

İnsanlar C'deki 'statik' ifadesinin iki anlamı olduğunu söylüyorlar. Tek bir anlam veren alternatif bir görüntüleme yöntemi sunuyoruz:

  • Bir öğeye 'statik' uygulamak, öğeyi iki özelliğe sahip olmaya zorlar: (a) Geçerli kapsamın dışında görünmez; (b) Kalıcıdır.

İki anlamı olduğu için, C'de, 'statik' uygulanabilecek her öğenin zaten bu iki özellikten birine sahip olması, bu nedenle bu özel kullanım sadece diğerini içeriyor gibi görünüyor .

Örneğin, değişkenleri düşünün. İşlevlerin dışında bildirilen değişkenlerin zaten kalıcılığı vardır (veri segmentinde), bu nedenle 'statik' uygulamak yalnızca geçerli kapsamın (derleme birimi) dışında görünmemelerini sağlayabilir. Aksine, işlevler içinde bildirilen değişkenler zaten geçerli kapsam (işlev) dışında görünmezliğe sahiptir, bu nedenle 'statik' uygulamak yalnızca onları kalıcı hale getirebilir.

Fonksiyonlara 'statik' uygulamak, onu global değişkenlere uygulamak gibidir - kod mutlaka kalıcıdır (en azından dil içinde), bu nedenle yalnızca görünürlük değiştirilebilir.

NOT: Bu yorumlar yalnızca C için geçerlidir. C ++ 'da, sınıf yöntemlerine' statik 'uygulamak anahtar kelimeye gerçekten farklı bir anlam vermektedir. Benzer şekilde C99 dizi bağımsız değişkeni uzantısı için.


(A) 'nız en iyi ihtimalle yedeklidir. Kapsamı dışında hiçbir değişken görünmez. Bu sadece kapsamın tanımıdır. Ne demek C Standardında bağlantı olarak adlandırılır . bir tanımlayıcıya iç bağlantıstatic verir .
Jens

16

Wikipedia'dan:

C programlama dilinde, kapsamlarını içeren dosyaya ayarlamak için global değişkenler ve işlevlerle statik kullanılır. Yerel değişkenlerde statik, değişkeni otomatik olarak ayrılan bellek yerine statik olarak ayrılan bellekte saklamak için kullanılır. Dil, her iki bellek türünün uygulanmasını gerektirmezken, otomatik olarak ayrılan bellek normalde geçici bir çağrı yığını olarak uygulanırken, statik olarak ayrılan bellek genellikle programın veri bölümünde ayrılır.


16

static farklı bağlamlarda farklı şeyler ifade eder.

  1. C işlevinde statik bir değişken bildirebilirsiniz. Bu değişken yalnızca işlevde görülebilir, ancak yalnızca bir kez başlatıldığı ve değerini koruduğu için bir global gibi davranır. Bu örnekte, her aradığınızda foo()artan bir sayı yazdırılır. Statik değişken yalnızca bir kez başlatılır.

    void foo ()
    {
    static int i = 0;
    printf("%d", i); i++
    }
  2. Statik bir başka kullanım, bir .c dosyasına bir işlev veya genel değişken uyguladığınız ancak sembolünün .objdosya tarafından oluşturulanın dışında görünmesini istemediğiniz durumdur . Örneğin

    static void foo() { ... }

8

Bir değişkeni statik işlevde bildirirseniz, değeri işlev çağrısı yığınında depolanmaz ve işlevi yeniden çağırdığınızda kullanılabilir olmaya devam eder.

Genel bir değişken statik bildirirseniz, kapsamı bildirdiğiniz dosya içinde kısıtlanır. Bu, tüm programınız boyunca okunabilen ve değiştirilebilen normal bir küreselden biraz daha güvenlidir.


8

Eski bir soruyu cevaplamaktan nefret ediyorum, ancak hiç kimsenin K&R'nin "C Programlama Dili" nin A4.1 bölümünde nasıl açıkladığını söylemediğini sanmıyorum.

Kısacası, statik kelimesi iki anlamla kullanılır :

  1. Statik iki depolama sınıfından biridir (diğeri otomatiktir). Statik bir nesne, çağrımlar arasında değerini korur. Tüm blokların dışında bildirilen nesneler her zaman statiktir ve otomatik hale getirilemez.
  2. Ancak, static anahtar kelime (kodda anahtar kelime olarak kullanılmasına büyük önem verilir) bir bildirimle kullanıldığında, nesnenin iç bağlantısını verir, böylece yalnızca o çeviri biriminde kullanılabilir. Ancak anahtar kelime bir işlevde kullanılırsa, nesnenin depolama sınıfını değiştirir (nesne yine de bu işlev içinde görünür olur). Statikin tersi, externbir nesneye harici bağlantı sağlayan anahtar kelimedir.

Peter Van Der Linden "Uzman C Programlama" da şu iki anlamı vermektedir:

  • Bir işlevin içinde, çağrılar arasındaki değerini korur.
  • İşlev düzeyinde, yalnızca bu dosyada görünür.

Üçüncü bir depolama sınıfı var, kayıt ol . Bazı insanlar , malloc ve arkadaşlarının geri verdiği depolama için ayrılan dördüncü bir depolama sınıfı için de dava açar.
Jens

@Jens 'register' derleyiciye sadece bir ipucu; kayıt deposu C kaynağından zorlanamaz. Bu yüzden onu bir depolama sınıfı olarak görmezdim.
Alman Nerd

1
@GermanNerd Korkarım ISO C Standardı, açıkça registerbir depolama sınıfı belirleyicisi (C99 6.7.1 Depolama sınıfı belirleyicileri) yaptığı için görüşünüze katılmıyor . Ve bu sadece bir ipucundan daha fazlasıdır, örneğin derleyicinin bir kayıt ayırıp ayırmamasına bakılmaksızın operatör adresini &depolama sınıfına sahip bir nesneye uygulayamazsınız register.
Jens

@Jens Bana hatırlattığınız için teşekkürler &. Ben çok fazla C ++ yapmış olabilir ..... Her neyse, 'kayıt' bir depolama sınıfı belirleyicisi olsa da, gerçekte derleyici 'kayıt' için 'işe yaramaz' otomatik 'belirteç için aynı makine kodu yaratacaktır 'belirteci. Yani geriye kalan tek şey, adres alamamak için kaynak kodu seviyesi kısıtlamasıdır. BTW, bu küçük tartışma beni Netbeans'de bir hata bulmaya itti; en son güncellememden bu yana, varsayılan olarak yeni C projelerinde g ++ takım zincirini kullanıyor!
GermanNerd

6

C dilinde, statik, kullanım kapsamına bağlı olarak iki anlama sahiptir. Genel kapsamda, bir nesne dosya düzeyinde bildirildiğinde, o nesnenin yalnızca o dosya içinde görünür olduğu anlamına gelir.

Başka bir kapsamda, belirli bir kapsamın girildiği farklı zamanlar arasında değerini koruyacak bir nesne bildirir. Örneğin, bir prosedür içinde int çıkarılırsa:

void procedure(void)
{
   static int i = 0;

   i++;
}

'i' değeri yordama yapılan ilk çağrıda sıfıra başlatılır ve değer, yordam her çağrıldığında korunur. 'i' basılmışsa, 0, 1, 2, 3, ...


5

Fonksiyonlardaki statik değişkenlerin, o fonksiyonun ilk girişinde başlatıldığını ve çağrıları bittikten sonra bile devam ettiğini not etmek önemlidir; özyinelemeli işlevlerde statik değişken yalnızca bir kez başlatılır ve tüm özyinelemeli çağrılarda ve hatta işlev çağrısı bittikten sonra da devam eder.

Değişken bir fonksiyonun dışında oluşturulmuşsa, programcının sadece değişkeni bildirdiği kaynak dosyada değişkeni kullanabileceği anlamına gelir.


5

Bunu bir mytest.cdosyada bildirirseniz :

static int my_variable;

Sonra bu değişken sadece bu dosyadan görülebilir. Değişken başka bir yere aktarılamaz.

Bir işlevin içinde bildirirseniz, değişken her işlev çağrıldığında değerini korur.

Statik bir işlev dosyanın dışından dışa aktarılamaz. Yani bir *.cdosyada, fonksiyonları ve değişkenleri statik olarak bildirirseniz gizlersiniz.


4

C'deki statik değişkenler programın ömrüne sahiptir.

Bir işlevde tanımlanırlarsa, yerel kapsamları vardır, yani yalnızca bu işlevlerin içinden erişilebilirler. Statik değişkenlerin değeri, fonksiyon çağrıları arasında korunur.

Örneğin:

void function()
{
    static int var = 1;
    var++;
    printf("%d", var);
}

int main()
{
    function(); // Call 1
    function(); // Call 2
}

Yukarıdaki programda, varveri segmentinde saklanır. Kullanım ömrü tüm C programıdır.

İşlev çağrısı 1'den varsonra 2 varolur. İşlev çağrısı 2'den sonra 3 olur.

varİşlev çağrıları arasında değeri yok edilmez.

Eğer varsigara statik ve yerel değişkeni arasındaki vardı, C programında yığın segmentinde saklanır. İşlev döndükten sonra işlevin yığın çerçevesi yok edildiğinden, değeri varde yok edilir.

Başlatılan statik değişkenler C programının veri segmentinde, başlatılmamış olan değişkenler BSS segmentinde saklanır.

Statik hakkında başka bir bilgi: Değişken genel ve statik ise, C programının yaşam süresi vardır, ancak dosya kapsamı vardır. Yalnızca bu dosyada görünür.

Bunu denemek için:

file1.c

static int x;

int main()
{
    printf("Accessing in same file%d", x):
}

file2.c

    extern int x;
    func()
    {
        printf("accessing in different file %d",x); // Not allowed, x has the file scope of file1.c
    }

run gcc -c file1.c

gcc -c file2.c

Şimdi bunları kullanarak bağlanmaya çalışın:

gcc -o output file1.o file2.o

X, dosya1.c dosya kapsamına sahip olduğundan ve bağlayıcı, file2.c dosyasında kullanılan x değişkenine yapılan başvuruyu çözümleyemeyeceği için bir bağlayıcı hatası verir.

Referanslar:

  1. http://en.wikipedia.org/wiki/Translation_unit_(programming)
  2. http://en.wikipedia.org/wiki/Call_stack

Verilerin kalıcı olduğunu anlıyorum, yani her işlev çağrısından sonra kaybolmayacak, ancak neden static int var = 1;değeri her seferinde bire geri değiştirmiyor
Eames

3

Statik değişken, bir işlevde kullanabileceğiniz özel bir değişkendir ve verileri aramalar arasında kaydeder ve aramalar arasında silmez. Örneğin:

void func(){
    static int count; // If you don't declare its value, the value automatically initializes to zero
    printf("%d, ", count);
    ++count;
}

void main(){
    while(true){
        func();
    }
}

Çıktı:

0, 1, 2, 3, 4, 5, ...


Sen değiştirebilirsiniz printf("%d, ", count); count++;printf ( "% d", sayım ++) (: P mühim değil) `ile.
RastaJedi

2

Statik değişken değeri, farklı işlev çağrıları arasında kalır ve kapsamı, statik değişkenin her zaman 0 değeriyle başlattığı yerel blokla sınırlıdır


2

2 vaka var:

(1) staticBelirtilen yerel değişkenler : Yığın yerine veri segmentine ayrılmıştır. İşlevi tekrar çağırdığınızda değeri korunur.

(2) Genel değişkenler veya beyan edilen fonksiyonlar static: Derleme ünitesi dışında görünmez (örn. Bağlantı sırasında sembol tablosundaki yerel sembollerdir).


1

Statik değişkenler kendi kapsamları dışında olduklarında bile değerlerini koruma özelliğine sahiptirler , dolayısıyla statik değişkenler önceki değerlerinde önceki değerlerini korurlar ve yeni kapsamda yeniden başlatılmazlar.

Örneğin buna bakın - Program çalışırken statik bir int değişkeni bellekte kalır. Değişkenin bildirildiği bir işlev çağrısı bittiğinde normal veya otomatik değişken yok edilir.

#include<stdio.h> 
int fun() 
{ 
  static int count = 0; 
  count++; 
  return count; 
} 

int main() 
{ 
  printf("%d ", fun()); 
  printf("%d ", fun()); 
  return 0; 
}

Bu çıktı: 1 2

Statik olarak bildirildiği için 1 bellekte kaldığı için

Statik değişkenler (global değişkenler gibi), açıkça başlatılmazsa 0 olarak başlatılır. Örneğin, aşağıdaki programda, x değeri 0 olarak yazdırılırken, y değeri çöptür. Daha fazla ayrıntı için buna bakın.

#include <stdio.h> 
int main() 
{ 
    static int x; 
    int y; 
    printf("%d \n %d", x, y); 
}

Bu çıktı: 0 [some_garbage_value]

Bunlar, bir acemi için yukarıda açıklanmayan bulduğum en önemli olanlar!


-1

C programlamasında, staticgörünürlüğü olduğu kadar yaşam süresini de kontrol eden ayrılmış bir anahtar kelimedir. Bir değişkeni bir işlev içinde statik olarak bildirirsek, yalnızca bu işlev boyunca görünür olur. Bu kullanımda, bu statik değişkenin ömrü bir işlev çağrıldığında başlar ve bu işlevin yürütülmesinden sonra yok olur. aşağıdaki örneği görebilirsiniz:

#include<stdio.h> 
int counterFunction() 
{ 
  static int count = 0; 
  count++; 
  return count; 
} 

int main() 
{ 
  printf("First Counter Output = %d\n", counterFunction()); 
  printf("Second Counter Output = %d ", counterFunction()); 
  return 0; 
}

Yukarıdaki program bize bu Çıktıyı verecektir:

First Counter Output = 1 
Second Counter Output = 1 

Çünkü fonksiyonu çağırır çağırmaz başlayacaktır count = 0. Ve biz yürütürken counterFunctionsayım değişkenini yok edecektir.


2
> Yukarıdaki program bize bu Çıkışı verecektir: İlk Sayıcı Çıkışı = 1 Saniye Sayıcı Çıkışı = 1 <Doğru değil. Statik değişkenler sadece bir kez başlatılır. Böylece çıktı 1, sonra 2 ve benzeri olacaktır.
Alman Nerd
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.