Dizi başlatılmasında garip değerler

C programında yeniyim ve anlamadığım bir şey buldum:

Verilen değerleri olmayan bir diziyi başlatırken, tüm elemanların sıfır olacağını düşündüm. Birkaç kod satırı yazdım ...

int main()                    
{     
    int obj[10][4];

    for (int a = 0; a < 10; a++)
    {
        print("%d\t%d\t%d\t%d\n", obj[a][0], obj[a][1], obj[a][2], obj[a][3]);
    }            
}

... ve çıktısı oldukça şaşırdı:

0       0       0       0
0       0       0       0
0       0       0       0
0       0       0       0
0       0       0       0
0       0       0       0
0       0       0       0
0       0       0       7661
7960    2697    2260    7960
1551630361      -2130960380     146780176       -2130960380

Bazı değerlerin neden sıfır olduğunu ve bazılarının neden olmadığını anlamıyorum. Daha fazla kod eklediğimde bu sayıların değişmesi beni daha da şaşırttı. Örneğin, önceki örneği değiştirdim ve başka bir print() ... ekledim.

int main()                    
{     
    int obj[10][4];

    print("start\tstop\tcenter\tdist\n\n");

    for (int a = 0; a < 10; a++)
    {
        print("%d\t%d\t%d\t%d\n", obj[a][0], obj[a][1], obj[a][2], obj[a][3]);
    }            
}

... bunu elde etmek:

start   stop    center  dist

0       0       0       0
0       0       0       0
0       0       0       0
0       0       0       0
0       0       0       0
0       0       0       0
0       0       0       0
0       0       0       7673
7972    2709    2272    7972
1551630361      -2130960380     146780176       -2130960380

Daha büyük bir dizi kullanarak, bu sayılar sadece sonunda bulunur. İlk birkaç değer her zaman sıfırdır, ancak sonra "bir şey" olur.

C kodu

2
Başlamadı, böylece başlatılmamış değerler elde ettiniz. Çoğunlukla sıfırlar, ama asla garanti edilmez.
katma yazar stefan, kaynak
Daha fazla geliştirme için bir ipucu: Gerçekten garip değerlerle beklenmedik davranış alırsanız, bir valgrind çalıştırmayı deneyin. Bu, hatanın nerede olduğuyla ilgili ipuçları verebilir (başlatılmamış değişkenler valgrind tarafından oldukça iyi algılanır).
katma yazar stefan, kaynak
Evet, bunun başlangıçta çok olduğunu biliyorum, güven bana, yeni başlayanları biliyorum ;-) Ama neye bakacağımı bilmek her zaman yardımcı olur. İki adım: Derleyici çağrınıza -g ekleyin (muhtemelen şu anda gcc -Wall -std = c99 my_file.c -o my_binary yazınız, böylece bu olur gcc -g -Wall -std = c99 my_file.c -o my_binary ). İkinci adım: Bunun gibi yürütmek yerine: ./ my_binary , valgrind ./my_binary . Ve bu kadar. "... başlatılmamış değer ..." varsa, orada listelenen dosya ve satır da var ve sorunun içine bakabilirsiniz. Sadece sorunuzun kodu ile deneyin!
katma yazar stefan, kaynak
Ah, anlıyorum. Bu benim görüşüme göre, biraz daha zor öğreniyor ;-) ;-)
katma yazar stefan, kaynak
@stefan: Bu bilgi için teşekkürler - ama şu anda biraz fazla. valgrind 'ı araştırdım ve C'yi biraz kullandıktan sonra anlayabileceğim bazı sitelere yer imi ekledim ;-)
katma yazar xph, kaynak
@stefan: Şey, şey şu ki ... "olağan" yolu kodlamıyorum. Tam olarak o küçük bilgisayar için oluşturulan IDE'yi kullanarak küçük bir Pervane kartı için C'ye yazıyorum. Normal bir derleyiciyi bile kullanmıyorum, tahtada en uygun şekilde bir kod almak için tümüyle yerleşik bir çözüm, yani "Bittiğinde bu düğmeyi tıklayın" . Eğer onunla dalga geçeceksem, daha derinden bakarım. Belki bu bilgisayarı programlamak için seçim araçlarını kullanabilirim ve bu çok kullanışlı olacak!
katma yazar xph, kaynak
Evet kabul edildi. C'nin “uygun” kullanımını öğretmeyecek, ama bu benim için gerçekten önemli bir nokta değil. Bu kart, robotik hakkında bilgi edinmek ve öğrenmek için tasarlandı ve ben esas olarak sensörlere, servolara ve benzerlerine odaklandım. Elbette, işlerin yapılması için kod gereklidir. Şimdiye kadar hep kaçındığım bir dil olan C ile "temasa geçmek" için en az bir sebep. Ama IDE ... gerçekten iyi değil. Yeni maceralar peşindeyim, ondan kurtulmaya çalışacağım.
katma yazar xph, kaynak

7 cevap

Simply put, you can not assume the array is initialized to 0 unless you explicitly made the initialization yourself. The C standard does not guarantee anything about the content of the array, just that you'll have memory allocated for it.
A great reference on initializing and arrays in C general can be found here:http://www.tutorialspoint.com/cprogramming/c_multi_dimensional_arrays.htm

4
katma
... bu yüzden yanlış anladım. Açıklama ve bağlantı için teşekkürler!
katma yazar xph, kaynak

Değişken beyanı var ama başlatma yok.

Dizinin sıfır olarak başlatılmasını istiyorsanız bunu basitçe belirtiniz:

int obj[10][4] = {0};
2
katma
Teşekkür ederim! Şimdi yaptığım yanılgıyı biliyorum - sadece bazı değerler tanımlanmışsa, geri kalanı sıfır olacaktır. Bunu yapacak!
katma yazar xph, kaynak

int obj [10] [4] depolama sınıfı türü auto şeklindedir ve yığınta depolanır. auto değişkenleri başlangıç ​​değerlerini alamazlar, yani çöp değerlerine sahip değiller. Sıfır ile başlatılacak diziyi istiyorsanız, bunu global yapın, örneğin main() işlevinin dışında bir dizi belirtin .

1
katma

Hiçbir şeyin başlangıç ​​değerleri tanımsızdır. Kodunuz sadece bir dizi tanımlar - içinde ne olduğuna hiçbir değer atar.

1
katma
@xph Evet, tam olarak yanlış olduğun yer burası. Başlatılmamış çöp değerleri demektir.
katma yazar stefan, kaynak
Evet - ama rastladığım örnekler “değer” in “sıfır” anlamına geldiğini ileri sürüyor. Yanlış anladım ve "değer yok" demek sadece "ne olursa olsun" ...?
katma yazar xph, kaynak
@stefan: Anladım! :-)
katma yazar xph, kaynak

yığın, program belirli değerleri yığınta tanımlanan değişkenlere yerleştirene kadar çöp içerir. Başlangıç ​​kodu yığın içeriğini başlatmaz.

Not: global boşluk/dosya genel uzayındaki değişkenler başlatma kodu tarafından başlatılır. Belirli bir başlatıcı belirtilmemişse, bellek 0x00 olarak ayarlanır.

0
katma

Başlangıçta, dizi bazı çöp değerlerine veya tahmin edilemeyen değerlere sahip olacaktır. Bu değerlerin ne olacağını veya dizide nerede bulunacaklarını söyleme yoktur.

C'de bir dizi bildirdiğinizde, kullanmadan önce onu başlatın. Yani, tüm dizi konumlarını sıfırlamak veya saklamak istediğiniz herhangi bir sayıya sıfırlamak için bir döngü çalıştırın. Bu şekilde, dizinin neleri içerdiğini ve daha sonra işleneceğini kesin olarak bileceksiniz, diziniz tanımlanmamış davranış göstermeyecektir.

0
katma

Bir uzman değil, deneyimden bir hipotez:

Bir diziyi static int myArray [1000] olarak başlatırsanız, C programın süresi boyunca 1000 sıfır ile doldurulmuş yeni belleği ayırır. int myArray [1000] ile başlatılınca, 1000 yazmaç bir kenara ayrılır, bunlardan bazıları, önceki bir kayıttan eski değerler içerebilir.

0
katma