5.8.1. Dizi Dizileri
Bir dizi benzer elemanlardan oluşan bir topluluktur. Eleman sayısı derleme sırasında belirlenir, böylece C dilinde devingen dizilere izin verilmez. Bir dizinin elemanları (alan veya fonksiyon dışında) herşey olabilir; ayrıca dizi de olabilir, böylece çok-boyutlu diziler tanımlanabilir. Bir dizinin elemanlarına ulaşmak için indisler kullanılır. İndisler tamsayı ifadelerdir ve, dizinin n tane elemanı varsa, değerleri 0 ile n-1 arasında değişebilir.
Tek-boyutlu dizileri nasıl kullanacağımızı biliyoruz. Şimdi çok boyutlu bir dizi tanımına bakalım:
int a[3][4] = { { 1, 2, 3, 2+2 }, { 5, 6, 7, 1<<3 }, { 3*3, 10, 11, 0xF&~03 } };
Burada çok-boyutlu bir dizinin (bir dizi dizisinin)
tanımının bütün boyutlarda boyların ayrı ayrı köşeli parantezler içine
alınarak verildiği görüyoruz. Yukarıdaki tanımda dizinin, her biri 4
elemanlı 3 vektör
şeklinde düzenlenmiş 12 elemanı vardır.
Diğer bir deyişle, diziler satır şeklinde saklanırlar, yani son indis en
hızlı değişendir. İlkleme beklendiği gibi yapılır, dizinin her elemanı
için üç madde bulunmaktadır, bunlar da virgülle ayrılmış vektörlerdir.
Bu maddelerin her biri birbirinden virgülle ayrılıp çengelli parantezler
içine alınmış 4 ifadeden oluşurlar. Eğer dizi tanımı ve ilkleme işlemi
bir fonksiyon dışında yapılıyorsa, bu ifadelerin değişmez olması gerekir.
Fonksiyon içinde yapılan tanımlarda ise, ilkleme program yürütülürken
yapıldığından, o aşamaya gelindiğinde hesaplanabilen herhangi bir ifade
olabilir. Bütün (12) değerleri de belirtmemize gerek yoktur. Örneğin,
int b[3][4] = { { 1, 2, 3 }, { 5, 6 } };
ile
int b[3][4] = { { 1, 2, 3, 0 }, { 5, 6, 0, 0 }, { 0, 0, 0, 0 } };
aynıdır. Eğer bütün değerleri belirtirsek içteki çengelli parantezlere gerek yoktur:
int a[3][4] = { 1, 2, 3, 2+2, 5, 6, 7, 1<<3, 3*3, 10, 11, 0xF&~03 };
Eğer derleyici dizinin boyunu ilkleyenden çıkarabilirse, o zaman boyu belirtmeye gerek yoktur. Örneğin,
int a[][4] = { { 1, 2, 3, 2+2 }, { 5, 6, 7, 1<<3 }, {3*3, 10, 11, 0xF&~03 } };
a
için ilk verilen tanıma eşdeğerdir.
Bildirimdeki ilk (yani belirtilmeyebilen) indisin sadece dizi tarafından
gerek duyulan bellek miktarını belirlemede kullanıldığına dikkat edin;
indis hesaplamalarında kullanılmamaktadır.
Bir dizi elemanına ulaşmak için
işlecini
kullanırız. Eğer n-boyutlu bir dizimiz varsa, n tane böyle
işleç kullanılmalıdır. Örneğin, []
a[1][2]
değeri 7
olan dizi elemanını göstermektedir. Pascal programlama dilinden farklı
olarak a[1,2]
—veya
a[(1,2)]
—a[2]
’ye eşdeğerdir ve bir
int
’in beklendiği bir yerde kullanılamaz.
Bu altkısmın başında C’de devingen dizilere izin verilmediğinden bahsedilmişti. Programda tanımlanmış bir dizinin boyunun dizi oluşturulduktan sonra değişmesi mümkün değildir. Yeni C Standardında, sadece otomatik diziler için, dizi tanımının yapıldığı aşamada (yani program çalışırken), değişmez olmayan, ancak değeri hesaplanan boyutlar vermek olasıdır.
#include <stdio.h> int b1=10; int d1[b1]; /* hatalı tanım! */ int fonk (int b2) { int b3 = b2*3; char d2[b1][b2][b3*2]; printf ("%zu\n", sizeof(d2)); return 3; } /* fonk */ int main (void) { int b4 = fonk (6); int b5 = 10; char d3[b4][b5*2][b1]; fonk (5); printf ("%zu\n", sizeof(d3)); } /* main */
Yukarıdaki programda dördüncü satırdaki d1
dizisinin tanımı hata alacaktır; çünkü otomatik bir değişken değildir,
kalıcı bir değişkendir ve derleme sırasında boyunun bilinmesi gerekir.
Diğer yandan fonk
içindeki d2
dizisi, ilk çağrıda
10×6×(6×3×2)=2160 karakterlik bir dizidir, ikinci çağrıda ise
10×5×(5×3×2)=1500 karakterlik bir dizidir.
Aynı şekilde, main
içindeki d3
dizisi de otomatik bir
dizidir ve oluşturulma sırasındaki değişkenlerin değerlerine uygun olarak
3×(10×2)×10=600 karakterlik bir dizi olacaktır.
Diğer otomatik değişkenler gibi, program akışı bir dizi tanımını
içeren bloğa her girdiğinde değişken uzunluklu bir dizi yeniden oluşturulur.
Sonuç olarak, bir dizi her oluşumda farklı bir uzunluğa sahip olabilir.
Bununla birlikte, bir kez oluşturulduktan sonra, değişken uzunluktaki bir dizi
bile, depolama süresi boyunca uzunluğunu değiştiremez. Otomatik nesneler
yığıtta oluşturulur ve program akışı bloktan ayrıldığında serbest bırakılırlar.
Bu nedenle, değişken uzunluklu dizi tanımları yalnızca küçük, geçici diziler
için kullanışlıdır. Daha büyük dizi ihtiyaçları için
Kısım 5.7’de gördüğümüz yöntemler kullanılabilir.
Yukarıda örnekleri verilen değişken uzunluklu dizilerin bir blok içinde
tanımlanmış olması, static
olmaması ve başka bir
yapı veya birliğin bir üyesi olmaması gerektiğine dikkat edin.