C Programlama

Ek Bilgiler

C'de Diziler

► Detaylı anlatım

Diziler aynı veri çeşidinden olan değişkenlerin aynı isim altında tanımlanması olarak ifade edilebilir. Diziler kullanılarak, aynı isimle birden fazla değişkene erişilebilir ve işlem yapılabilir.

Diziler tek ya da çok boyutlu olarak tanımlanabilir ve dizi boyutu ihtiyaca göre ayarlanabilir.

int, char, float ve double olarak tanımlanabilen dizilerde sadece aynı veri türünden değişken değerleri yer alabilir.

Tek ve çok boyutlu dizilerin bildirimi için kullanılan genel yapı aşağıda gösterilmektedir:

veri-çeşidi dizi-adı [boyut]; /* Tek boyutlu dizi bildirimi */

veri-çeşidi dizi-adı [boyut1][boyut2]...[boyutn]; /* Çok boyutlu dizi bildirimi */

/* Tek boyutlu eleman sayısı tanımsız dizi bildirimi 
(Atanan eleman sayısı dizi boyut kapasitesini belirler) */
veri-çeşidi dizi-adı [] = { ele1, ele2, ..., elen }; 

Bir dizi bildirimi 3 temel elemandan oluşur. Yukarıdaki satırda yer alan veri-çeşidi ifadesi dizinin içerdiği değişkenlerin veri çeşidini dizi-adı ifadesi dizinin adını, [boyut] ifadesi ise dizideki değişken sayısını yani dizi boyutunu göstermektedir.

int idizi[10];      /* Tek boyutlu 10 elemanlı int dizi bildirimi */
char cdizi[10];     /* Tek boyutlu 10 elemanlı char dizi bildirimi */

int idizi[3][4];    /* İki boyutlu 12 elemanlı int dizi bildirimi */
char cdizi[3][21];  /* İki boyutlu char dizi bildirimi */

/* Eleman sayısı tanımsız 5 elemanlı int dizi bildirimi */
int idizi[] = { 1, 2, 3, 4, 5 };

/* Eleman sayısı tanımsız 6 elemanlı char dizi bildirimi (2 farklı yöntem) */  
char cdizi[] = { 'R', 'a', 'k', 'a', 'm', '\0' };
char cdizi[] = "Rakam";

/* Eleman sayısı tanımsız çok boyutlu char dizi bildirimi */
char cdizi[][20] = { "Çoklu", "Karakter", "Dizileri" };

C'de bir dizinin ilk elemanına 0 değeri ile erişim sağlanır.

int idizi[10];   /* 10 elemanlı dizi adlı bir dizi oluşturur. */
dizi[0] = 38;    /* Dizinin ilk elemanına 38 değerini atar. */
dizi[7] = 174;   /* Dizinin 8 nci elemanına 174 değerini atar. */

Yukarıdaki ilk işlem satırında dizi adlı ve 10 elemanlı int bir dizi oluşturulur. Böylece, bilgisayar belleğinde 10 int değişkeni için yer ayrılmış olur. İkinci işlem satırı, dizinin ilk elemanına 38 sayısını ve üçüncü işlem satırı, dizinin sekizinci elemanına 174 sayısını atar. Burada, dizi[0] ifadesinin dizinin ilk elemanını gösterdiğine dikkat ediniz.

C'de, dizi elemanlarının sayısını sınırlayıcı bir kural yoktur. Yani, daha önce boyutunu tanımlanan bir dizinin eleman sayısından daha fazla eleman diziye atanabilir. Böyle bir durumda karşılaştığında, derleyici yazılan programı herhangi bir hata vermeden derler ve .EXE uzantılı bir dosya oluşturur. Ancak, derlenen dosya çalıştırıldığında, beklenmeyen sonuçlarla karşılaşılabilir. Dizilere tanımlanan boyuttan daha fazla eleman atamanın olumsuz sonuçlarını engellemek için, dizi boyutlarını tanımlarken, sınırlar ihtiyaca göre belirlenmelidir.

Karakter Dizileri

* C'de karakter dizisi olarak tanımlanan bir veri çeşidi yoktur.

* Karakter dizisi veri desteğini sağlamak için tek boyutlu char diziler kullanılır.

* Karakter dizisi NULL(0) değer ile sona eren bir char dizidir.

Siz bir karakter dizisi sabiti tanımladığınızda derleyici otomatik olarak sabitin sonuna 0 değeri ekler.

Bu nedenle, bir karakter dizisi içerecek bir karakter dizisi tanımlarken, dizi boyutunu karakter dizisinden bir byte yani bir karakter fazla olacak şekilde daha uzun tanımlamak gerekir. Derleyici 0 değerini diziye eklemek için ayrılan bir byte'lık boş alanı kullanacaktır.

char dizilere değer atarken ve ekrana yazdırırken karakterlere tek tek işlem yapılacağı zaman dizinin en sonunda dizi sonu tanımlayan '\0' karakteri için yer ayırmaya gerek yoktur. Ancak, diziye tek seferde işlem yapılacağı zaman dizi sonunda '\0' karakteri mutlaka tanımlanmalıdır.

Karakter dizilerine ilk değer atama işlemi ise 2 farklı şekilde yapılabilir:

Eğer karakter dizisinin her elemanına ayrı ayrı değer atanacaksa, diziye atanacak karakter sayısının bir fazlası kadar dizi boyutu tanımlamak ve en son elemana '\0' karakteri atamak gerekir.

Karakter olarak : cdizi[8] = { 'D', 'i', 'z', 'i', 'l', 'e', 'r', '\0' };

Eğer bir karakter dizisine toplu değer ataması yapılacaksa, karakter dizisi (" ") işaretleri arasında tanımlanmalıdır. Bu durumda dizi boyutu karakter dizisinde yer alan karakter sayısından bir fazla tanımlanır ve karakter dizisinin sonuna derleyici tarafından otomatik olarak '\0' karakteri eklenir.

Karakter dizisi olarak : cdizi[8] = "Diziler";

Dikkat ederseniz, yukarıda incelediğimiz her iki işlem satırı da aynı sayıda karakteri dizilere atar. Ancak, ikinci işlem satırındaki dizinin son elemanı derleyici tarafından eklenecek olan 0 değeri için ayrılmıştır.

Karakter dizilerine ilk değer atama yöntemini kullanırken, atanan değerler ile tanımlanan dizi boyutu birbirine uygun olmalıdır. Aksi takdirde, derleyici programını derlerken hata verir.

strcpy(), strcat(), strcmp() ve strlen() Fonksiyonları

Şimdi, C'de karakter dizileri ile ilgili işlemlerde en yaygın şekilde kullanılan aşağıdaki 4 standart kütüphane fonksiyonunu sıra ile incelemeye çalışalım. Bu fonksiyonların tamamı string.h başlık dosyasını kullanmaktadır:

strcpy() fonksiyonunun genel yapısı aşağıdaki şekildedir:

char *strcpy (char *cdizihedef, const char *cdizikaynak);

strcpy() fonksiyonu cdizikaynak ile gösterilen karakter dizisini cdizihedef ile gösterilen karakter dizisine kopyalar. Eğer cdizihedef dizisi içinde mevcut bir karakter dizisi varsa üzerine yazılır. Yani, cdizihedef dizininde yer alan önceki karakter dizisi silinir. Fonksiyon cdizihedef karakter dizininin bellek adresini geri verir.

char *strcat (char *cdizihedef, const char *cdizikaynak);

strcat() fonksiyonu cdizikaynak ile gösterilen karakter dizisini cdizihedef adlı karakter dizisinin sonuna ekler. strcat() fonksiyonu kullandığı dizi ile ilgili sınır kontrolü yapmadığından, dizi boyutunu tanımlarken, diziye eklenecek karakter dizilerinin boyutları dahil olmak üzere, karakter dizisinin azami boyutunun dikkate alınması gerekir. strcat() fonksiyonu cdizihedef karakter dizisinin bellek adresini geri verir.

int strcmp (const char *cdizi1, const char *cdizi2);

Eğer karşılaştırılan karakter dizileri birbirine eşitse, strcmp() fonksiyonu 0 değerini geri verir. Eğer cdizi1 karakter dizisi cdizi2 karakter dizisinden küçük ise 0'dan küçük bir değer, büyük ise 0'dan büyük bir değer geri verir.

strcmp() fonksiyonu karakter dizilerine işlem yaparken, sözlük sırasına göre karşılaştırır. Bu karşılaştırmada, karakter dizilerinin uzunlukları dikkate alınmaz. Örneğin, aşağıdaki satırda yer alan karakter dizilerinden sol taraftaki daha küçüktür. Çünkü, sol taraftaki karakter dizisinin üçüncü harfi, sağ taraftaki karakter dizisinin üçüncü harfinden daha küçüktür:

"kalem" "kapı"

Bu fonksiyon ile yapılan karşılaştırma büyük ve küçük harf özelliğini de dikkate alır. Küçük harfler büyük harflerden daha büyük değer taşırlar.

strlen() fonksiyonu bir karakter dizisinin karakter olarak uzunluğunu geri verir. Genel yapısı aşağıdaki şekildedir:

size_t strlen (const char *cdizi);

Karakter dizisinin uzunluğunu hesaplarken dizinin sonunda yer alan 0 değerini dikkate almaz.

#include <string.h>
#include <stdio.h>

main()
{
  char cdizi1[50], cdizi2[20];

  printf("Bir karakter dizisi giriniz (20 karakterden az): ");
  gets(cdizi1);
  printf("Bir karakter dizisi giriniz (20 karakterden az): ");
  gets(cdizi2);

  printf("\n%s\n%s\n", cdizi1, cdizi2);
  
  printf("Karakter dizilerinin uzunlukları : %d %d\n", strlen(cdizi1), strlen(cdizi2));

  if (!strcmp(cdizi1, cdizi2)) printf("Karakter dizileri birbirine eşittir!");
  else printf("Karakter dizileri birbirine eşit değildir!");
  
  strcat(cdizi1, cdizi2);
  printf("\n%s\n", cdizi1);

  strcpy(cdizi1, cdizi2);
  printf("%s\n", cdizi1);
}

Yukarıdaki örnekte, program cdizi1 ve cdizi2 adlı 2 adet karakter dizisi oluşturur. Girilen karakter dizilerini bu dizilere atar. Dizileri ve karakter uzunluklarını ekrana yazar. Sonra, 2 karakter dizisini karşılaştırarak sonucu ekrana yazar. Son aşamada, İkinci diziyi ilk diziye ekleyerek sonra da kopyalayarak ekrana yazar.

#include <stdio.h>

main()
{
  /* Karakter olarak atama */ 
  char cdizi1[9] = { 'K', 'a', 'r', 'a', 'k', 't', 'e', 'r', '\0' };
  char cdizi2[9] = "Karakter"; /* Kelime olarak atama */ 
  char cdizi3[2][21]; /* Çok boyutlu char dizi bildirimi */ 
  char cdizi4[ ] = "Diziler"; /* Boyutsuz char dizi bildirimi */ 

  int idizi1[10]; /* Tek boyutlu int dizi bildirimi */ 
  int idizi2[2][3][4]; /* Çok boyutlu int dizi bildirimi */ 
  int idizi3[ ] = { 1, 2, 3, 4, 5 }; /* Boyutsuz int dizi bildirimi */ 
  
  int id1, id2, id3;

  /* idizi1 int dizisine değer verilmesi ve ekrana yazılması */ 
  for (id1=0; id1<10; id1++) {
      idizi1[id1]=id1;
      printf("%d ", idizi1[id1]);
  } 

  /* cdizi1 ve cdizi2 char dizilerinin ekrana yazılması */ 
  printf("\n%s %s\n", cdizi1, cdizi2);

  /* Çok boyutlu idizi2 int dizisine değer atanması ve ekrana yazılması */ 
  for (id1=0; id1<2; id1++) {
       for (id2=0; id2<3; id2++) {
            for (id3=0; id3<4; id3++) {
                 idizi2[id1][id2][id3] = 1;
                 printf("%d ", idizi2[id1][id2][id3]);
            }	 
       }
  }

  /* Çok boyutlu cdizi3 char dizisine değer atanması ve ekrana yazılması */ 
  strcpy (cdizi3[0], "Karakter dizileri");         /* Kopyalama yoluyla */ 
  for (id1=0; id1<21; id1++) cdizi3[1][id1] = 'A'; /* Birer birer karakter atayarak */ 
  cdizi3[1][id1] = '\0';
  printf("\n%s\n%s\n", cdizi3[0], cdizi3[1]);      /* Ekrana yazılması */     

  /* Boyutsuz idizi3 int dizisinin ekrana yazılması */   
  for (id1=0; id1<5; id1++) printf("%d ", idizi3[id1]);

  /* Boyutsuz cdizi4 char dizisinin ekrana yazılması */ 
  printf("\n%s\n", cdizi4);	 /* Tek komutla */   
  for (id1=0; cdizi4[id1]; id1++) printf("%c", cdizi4[id1]); /* Birer birer */ 
}

Yukarıdaki örnekte, program aşağıdaki satırları ekrana yazar:

0 1 2 3 4 5 6 7 8 9
Karakter Karakter
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Karakter dizileri
AAAAAAAAAAAAAAAAAAAA
1 2 3 4 5
Diziler
Diziler