Standart C Programlama Dili


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.