[100] = {0} dizisi tüm diziyi nasıl 0'a ayarlar?


140

Derleyici değerleri nasıl doldurur char array[100] = {0}; ? Arkasındaki sihir nedir?

Derleyicinin nasıl başlatılacağını bilmek istedim.


1
C veya C ++ ile mi? Bunlar iki ayrı sorudur.
Toby Speight

Yanıtlar:


163

Sihir değil.

Bu kodun C'deki davranışı, C spesifikasyonunun 6.7.8.21 bölümünde (C spesifikasyonunun çevrimiçi taslağı) açıklanmaktadır. : belirli bir değere sahip olmayan elemanlar için, derleyici NULL'a ve aritmetik türleri sıfıra ( ve bunu topaklara yinelemeli olarak uygular).

C ++ 'da bu kodun davranışı, C ++ spesifikasyonunun (C ++ spesifikasyonunun çevrimiçi taslağı ) bölüm 8.5.1.7'sinde açıklanmıştır : derleyici, belirli bir değere sahip olmayan elemanları ilklendirir.

Ayrıca, C ++ 'da (C değil) boş bir başlatıcı listesi kullanabileceğinizi ve derleyicinin dizideki tüm öğeleri toplamasına neden olduğunu unutmayın:

char array[100] = {};

Bunu yaparken derleyicinin ne tür bir kod üretebileceğine gelince, şu soruya bir göz atın: 0 başlatma dizisinden garip montaj


Tüm C derleyicileri bunu yapıyor mu? Sadece Visual Studio'nun bunu yaptığına inanmaya başladım.
JFA

1
c ++ özellikleri çevrimiçi taslak kırık, kimse yeni bağlantı var?
Behrooz Karjoo

35

Uygulama derleyici geliştiricilerine bağlıdır.

Sorunuz "bu tür bir bildirimle ne olacak" ise - derleyici, ilk dizi öğesini verdiğiniz değere ayarlar (0) ve diğerleri, atlanan dizi öğeleri için varsayılan bir değer olduğu için sıfıra ayarlanır.


Ben bir kaynak yok, ama ben bir yerde dizi bildirimleri için varsayılan bir değer olduğunu okumak eminim; zaten orada olan çöpleri alırsın. Yine de bunların üzerine yazmanız muhtemel olduğunda bu değerleri ayarlamak için zaman kaybetmenin bir anlamı yoktur.
Ryan Fox

10
Ryan, ilk dizi için tüm dizinin başlatılmadığı ve gerçekten de çöp içerdiği bir değer ayarlamazsanız, ancak en az bir öğesi için bir değer ayarlarsanız, tüm dizi başlatılır, böylece belirtilmemiş öğeler örtük olarak başlatılır 0.
qrdl

1
C ++ için sınırlı bir dizi için boş bir başlatıcı listesi varsayılan olarak tüm öğeleri başlatır.
dalle

2
@NatanYellin Bunun tanımsız olduğunu nereden söyledim? Lütfen yorum yapmadan ve indirmeden önce cevabın tamamını okuyun.
qrdl

1
@qrdl Haklısın. Uygulama hakkındaki yorumunuzu yanlış anladım. Ne yazık ki, şimdi oyumu değiştiremiyorum.
Natan Yellin

27

Derleyiciniz GCC ise, aşağıdaki sözdizimini de kullanabilirsiniz:

int array[256] = {[0 ... 255] = 0};

Lütfen http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html#Designated-Inits adresine bakın ve bunun derleyiciye özgü bir özellik olduğunu unutmayın .


Hoşgeldiniz! daha fazla püf noktası arıyorum, ben vermişti
çünkü

1
İsterseniz bunu kesinlikle yapabilirsiniz, ancak bunun gibi derleyiciye özgü uzantılara güvenmenin bariz dezavantajları vardır.
Dan Olson

@Dan Olson sorusunun kendisi derleyiciye özel bir şey soruyor ve bu nedenle bunu gönderdi. Eğer işe yaramaz olduğunu düşünüyorsanız, silerim.
lakshmanaraj

5
İşe yaramaz değil, ilginç. Uyarı sadece not edilmeyi hak ediyor.
Dan Olson

2
Bunun gibi şeyler beni SO geri geliyor ve en iyi birkaç cevap daha fazla okuma tutar ...
timday

19

Bu başlatmayı nereye koyacağınıza bağlıdır.

Dizi olduğu gibi statik ise

char array[100] = {0};

int main(void)
{
...
}

o zaman programın veri segmentinde 100 0 bayt ayıran derleyicidir. Bu durumda başlatıcıyı atlamış olabilirsiniz.

Diziniz otomatikse, başka bir hikaye.

int foo(void)
{
char array[100] = {0};
...
}

Bu durumda foo işlevinin her çağrısında gizli bir memsetiniz olacaktır.

Yukarıdaki kod şuna eşdeğerdir:

int foo(void)
{ 
char array[100];

memset(array, 0, sizeof(array));
....
}

ve başlatıcıyı atlarsanız diziniz rastgele veriler (yığının verileri) içerir.

Yerel diziniz aşağıdaki gibi statik olarak bildirilmişse

int foo(void)
{ 
static char array[100] = {0};
...
}

teknik olarak birincisi ile aynı durumdur.

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.