C Dili – 7. Konu

KELİME DİZİLERİ (STRING) NEDİR?

Bir “string” ya da “kelime katarı”, genellikle harflerden oluşan karakterler dizisidir. Çıktınızın güzel ve manalı görünmesi için, içinde isimler ve adresler olabilmesi için, programlarınızın string’ler kullanması şarttır. C dilinde string in tam tanımı, “char” tipi bilgilerin, NULL karakter (yani sıfır) ile sonlandırılması’dır.

C’de bir string’in karşılaştıracağı, kopyalayacağı yada ekrana yansıtacağı zaman, bunları gerçekleştiren fonksiyonlar, string’in sonundaki NULL bulunana dek bu işlemi yapmak üzere programlanmıştır.

ARRAY (dizi) NEDİR?


Dizi, ayni tip verilerin birbiri arkasına tanımlanmasıdır. String, bir cins dizidir.

CHRSTRG.C:
================================================================
main()
{
    char isim[7];         /* Bir karakter dizisi tanimlayalim */
    isim[0] = ‘T’;
    isim[1] = ‘u’;
    isim[2] = ‘r’;
    isim[3] = ‘g’;
    isim[4] = ‘u’;
    isim[5] = ‘t’;
    isim[6] = 0;             /* Boş karakter – stringin sonu */
    printf(“Isim %s dur. \n”,isim);
    printf(“Içinden bir karakter: %c\n”,isim[2]);
    printf(“Ismin bir parçası: %s \n”,&isim[3]);
}

================================================================

Bu programda, ilk önce, “char” tipi bir tanımlama görüyoruz.
Köşeli parantezler içinde, kaç hanelik bir dizi tanımlanacağını belirtiyoruz.
C dilinde bütün diziler sıfırdan başladığı için, bu tanımlama ile kullanabileceğimiz en yüksek index değeri 6 dır.

STRING NASIL KULLANILIR


Demek ki, “isim” değişkeni, içinde 7 tane karakter tutabilir. Fakat en son
karakterin sıfır olması zorunluluğu olduğu için, kullanılabilecek olan alan
6 karakterliktir. Bu stringin içine manalı bir şey yüklemek için, yedi tane
komut veriyoruz – her biri, stringe bir karakter atamaktadır. En sonunda da,
stringin sonunu belirten sıfır rakamını koyuyoruz. (Bir “#define” ile NULL
karakteri, programın başında sıfır olarak tanımlayabiliriz)

printf komutundaki %s işareti, printf’e “isim” isimli stringden, sıfıra
rastlayıncaya kadar ekrana yazmasını belirtir. Dikkat etmeniz gereken bir
nokta, “isim” değişkeninin indexinin yazılmasının gerekmediğidir

STRING’İN BİR KISMININ YAZILMASI

İkinci printf komutu ise %c ile, stringin içinden sadece bir karakter
(harf) yazılmasını gösterir istediğimiz karakterin index numarasını da,
“isim” değişkeninin yanına, köşeli parantezler arasında gösterebiliriz

Son printf komutunda ise, stringin 4. karakterinden itibaren yazmanın bir
örneğidir”isim” değişkeninin önündeki & (ampersand) işareti isim[3]’un
hafızada saklandığı adresin printf’e geçirilmesini belirtir. Adresleri 8.
konuda göreceğiz, fakat ufak bir örnek ile size bizleri nelerin
beklediğini göstermek istedim.

BAZI STRING FONKSIYONLARI

STRING.C
================================================================

main()
{
    char isim1[12],isim2[12],karisik[25];
    char baslik[20];

    strcpy(isim1,”Rosalinda”);
    strcpy(isim2,”Zeke”);
    strcpy(baslik,”Bu bir basliktir.”);

    printf(” %s\n\n” ,baslik);
    printf(“isim 1: %s \n”,isim1);
    printf(“isim 2: %s \n”,isim2);

    if(strcmp(isim1,isim2)>0) /* sayet isim1 > isim2 ise, 1 dondurur */
        strcpy(karisik,isim1);
    else
        strcpy(karisik,isim2);

    printf(“Alfabetik olarak en buyuk isim %s dir.\n”,karisik);

    strcpy(karisik,isim1);
    strcat(karisik,” “);
    strcat(karisik,isim2);
    printf(“Iki isim birden %s\n”,karisik);
}
================================================================
İlk önce 4 tane string tanımlıyoruz. Daha sonra, “strcpy” isimli çok pratik
bir fonksiyona geliyoruz. yaptığı is, bir stringi, bir diğerine, ta ki
sıfır bulunana kadar kopyalamak. Hangi string’in hangisine kopyalanacağını hatırlamak icin, bir atama komutunu dusunun (“x=23” gibi).
Veri, sağdakinden, soldakine kopyalanır. Bu komutun yapılmasından sonra, isim1 in içinde, “Rosalinda” olacaktır – çift tırnaksız olarak.
Çift tırnaklar, derleyicinin sizin bir string tanımladığınızı anlaması için gereklidir.

STRINGLERİN ALFABETIK OLARAK SIRAYA KONMASI

İlginizi çekebilecek diğer bir fonksiyonda, “strcmp” dur. Şayet kendisine
geçirilen birinci string ikinciden daha büyükse, 1 döndürür, ayni ise 0, ve
ikinci daha büyükse -1 döndürür. “Zeke” stringinin kazanması, sizi herhalde
şaşırtmaz. Burada stringin boyu önemli değildir, sadece içindeki
karakterler. Ayrıca harflerin buyuk yada küçük harf olması da fark ettirir.
C de bir stringin bütün harflerini küçük yada büyüğe çeviren fonksiyonlar da
vardır. Bunları daha ileri kullanacağız.

STRINGLERİ BİRBIRINE EKLEMEK

En son satırda, “strcat” isimli yeni bir fonksiyon göreceksiniz. Görevi,
bir string’in sonuna diğer stringi eklemektir. Bunu yaparken NULL karakterin
de yerli yerinde olmasını sağlar. Burada, “isim1”, “karışık” ‘a
kopyalanır, daha sonra “karısık” a iki boşluk ve “isim2” eklenir. Stringler
zor değildir, ve son derece faydalıdırlar. Onları kullanmayı iyice
öğrenmenizde fayda vardır.


BIR TAMSAYI DIZISI


INTDIZIN.C:
================================================================
main()
{
    int degerler[12];
    int index;
    for (index = 0;index < 12;index++)
        degerler[index] = 2 * (index + 4);
    for (index = 0;index < 12;index++)
        printf(“Index = %2d deki degeri %3d dir..\n”,index,degerler[index]);
}
================================================================

Bu programda, bir tamsayi dizisi tanımlıyoruz. gördüğünüz gibi, aynı string
tanımlama gibi.. Bu sayede, index değişkeni hariç on iki tane değişkenimiz
oluyor. Bu değişkenlerin isimleri “degerler[0]” , “degerler[1]” ,vs. dir.
İlk “for” döngüsünde, bunlara değer atıyoruz, ikincisi ise, index değişkeni
ve “degerler” dizisinin içindekileri ekrana yazıyor.

BIR KAYAR NOKTA DIZINI


BUYUKDIZ.C:
================================================================
char isim1[] = “Birinci Program basligi”;
main()
{
    int index;
    int ivir[12];
    float tuhaf[12];
    char isim2[] = “Ikinci Program Basligi”;

    for (index = 0;index < 12;index++)
    {
        ivir[index] = index + 10;
        tuhaf[index] = 12.0 * (index + 7);
    }
    printf(“%s\n”,isim1);
    printf(“%s\n\n”,isim2);
    for (index = 0;index < 12;index++)   
        printf(“%5d %5d %10.3f\n”,index,ivir[index],tuhaf[index]);
}
================================================================
Burada, “float” olarak tanımlı bir kayar nokta dizisi görüyorsunuz. Ayrıca
bu program, string’lere nasıl başlangıç değeri atanabileceğini gösteriyor.
köşeli parantezlerin içini boş bırakarak, derleyicinin o veriyi saklamak
için yeteri kadar yer ayarlamasını sağladık. Programın içinde, bir string
daha ilk değerini veriyoruz. Başka yeni bir şey yok bu programda. değişkenler
rastgele değerlere atanır, ve sonra da bu değerler ekrana yazdırılır.


BIR FONKSIYONDAN DEGER DONDURME


GERIDOND.C:
================================================================
main()
{
    int index;
    int matrix[20];
    for (index = 0;index < 20;index++) /* veriyi uretelim */
        matrix[index] = index + 1;

    for (index = 0;index < 5;index++) /* orjinal veriyi, ekrana. */
        printf(“Baslangic matrix[%d] = %d\n”,index,matrix[index]);

    yapbirsey(matrix); /* fonksiyona gidip, deger degistirme */

    for (index = 0;index < 5;index++) /* degismis matrix i yazalim */
        printf(“Geri donen matrix[%d] = %d\n”,index,matrix[index]);
}

yapbirsey(list) /* Veri donusunu gosterir */
int list[];
{
    int i;
    for (i = 0;i < 5;i++) /* orjinal halini goster */
    printf(“Onceki matrix[%d] = %d\n”,i,list[i]);

    for (i = 0;i < 20;i++) /* hepsine 10 ekle */
        list[i] += 10;

    for (i = 0;i < 5;i++) /* son halini yaz */
        printf(“Sonraki matrix[%d] = %d\n”,i,list[i]);
}
================================================================

Bir fonksiyondan değer döndürmenin bir yolu da, diziler kullanmaktır.
Burada 20 hanelik bir dizi tanımladıktan sonra, içine değerler atıyoruz,
bu değerlerin ilk beşini ekrana yazdıktan sonra, “yapbirsey” isimli
fonksiyona atlıyoruz. Burada göreceğiniz gibi, bu fonksiyon “matrix” isimli
diziye “list” demeyi tercih ediyor. Fonksiyona, ne cins bir dizi geçeceğini
bildirmek için, “int” olarak “list”i tanımlıyoruz. Fonksiyona kaç elemanlık
bir dizi geçeğini söylememize lüzum yok, fakat istenirse belirtilebilir. Bu
nedenle boş köşeli parantezler kullanıyoruz.

Bu fonksiyon da, kendisine geçen değerleri gösterdikten sonra, bu değerlere
10 ekliyor, ve yeni değerleri gösterip, ana programa geri donuyor. Ana
programda görüyoruz ki, fonksiyonun yaptığı değişiklikler,
“matrix” değerlerini de değiştirmiş.

Dizilerin, normal değişkenlerin aksine, fonksiyondaki değerleri değişince,
çağıran programdaki dizinin değerlerinin değişmesini garipseyebilirsiniz.
Pointerlar konusuna gelince bütün bunlar daha manalı olacaktır.

BIRDEN FAZLA BOYUTLU DIZILER


COKLUDIZ.C:
================================================================
main()
{
    int i,j;
    int buyuk[8][8],dev[25][12];
    for (i = 0;i < 8;i++)
        for (j = 0;j < 8;j++)
            buyuk[i][j] = i * j; /* Bu bir carpim tablosudur */

    for (i = 0;i < 25;i++)
        for (j = 0;j < 12;j++)
            dev[i][j] = i + j; /* Bu da bir toplama tablosudur */

    buyuk[2][6] = dev[24][10]*22;
    buyuk[2][2] = 5;
    buyuk[buyuk[2][2]][buyuk[2][2]] = 177; /* bu, buyuk[5][5] = 177; demek */

    for (i = 0;i < 8;i++) {
        for (j = 0;j < 8;j++)
            printf(“%5d “,buyuk[i][j]);
         printf(“\n”); /* Her i nin degeri artinca, bir RETURN */
     }
}
================================================================

Burada iki tane iki boyutlu dizi kullanıyoruz. “buyuk” adli 8 e 8 lik
dizinin elemanları [0][0] dan [7][7] ye kadar, toplam 64 tanedir. Diğer
tanımlı “dev” dizi ise, kare değildir, fakat dizinin kare olmasının şart
olmadığını gösteren bir örnektir.

İki dizi de biri çarpım tablosu, diğeri de toplama tablosu ile doldurulur.

Dizi elemanlarının tek tek değiştirilebileceğini göstermek için, önce
“buyuk” un elemanlarında birine, “dev” in bir elemanı ile, 22 ile
çarpıldıktan sonra atanır. İkinci atamada ise, “buyuk[2][2]” elemanı 5
değerine atanır. Herhangi bir işlemin index olarak kullanılabileceğini
gösteren üçüncü atama ise, aslında “buyuk[5][5] = 177;” dir.

DIZITOPLAMI.C:
================================================================
#define MAX_ELEMAN 100
int toplami(int a[], int n) {
 if (n < 1 || n > MAX_ELEMAN) {
          printf(“Hata: Sadece 1 ila %d arasındaki eleman sayısını toplayabilirim”,MAX_ELEMAN);
        exit(1); }
 else
        if (n == 1) return a[0];
    else return (a[n-1] + toplami(a,n-1));
}

================================================================
Burada da recursion ve dizileri beraber kullanıyoruz ve bir dizinin elemanlarını topluyoruz – kendi kendimizi çağırarak.


STRLEN.C:
================================================================
main()
{
    char isim[] = “Charles Bronson”;
    printf(“İsim:  %s dir, ve bu isim %d harften oluşmaktadır. \n”, isim, strlen(isim));
}
================================================================

Burada gördüğünüz strlen fonksiyonu, herhangi bir string’in boyunu sizlere döndürecektir – sonundaki sıfırı saymadan.

Ödevler

  1. Her biri yaklaşık 6 karakter uzunluğunda üç kısa string içine “strcpy” ile içlerine “bir”, “iki” ve “dört” kelimelerini kopyalayan bir program yazın. Daha sonra, bu stringi, daha buyuk bir stringin içine, üç kelimeyi yanyana getirerek yerleştirin. çıkan sonucu on kere ekrana yazdırın.

  2. 2. her biri 10 elemanlı olan “dizi1” ve “dizi2” isimli iki tamsayi dizisi tanımlayın, ve içlerine bir döngü ile, ıvır zıvır bilgi doldurun. Daha sonra her bir elemanını, ayni boydaki bir üçüncü diziye ekleyin. Bu çıkan sonucu da “diziler” isimli 3. bir diziye atayın. sonuçları ekrana yazdırın:
    1 2 + 10 = 12
    2 4 + 20 = 24
    3 6 + 30 = 36 gibi..

    İpucu: printf komutu söyle görünecek:
    printf(“%4d %4d + %4d = %4d\n”,index,dizi1[index],dizi2[index], diziler[index]);

  3. “int length(char s[])”   tanımıyla başlayan bir fonksiyon yazın. Bu fonksiyona bir string geçirildiğinde, size bu string’in kaç harften oluştuğunu döndürsün. Yani strlen() in yaptığını yapsın, ama tabi fonksiyonunuzda strlen kullanmayın, kendiniz saydırın.

  4. “void reverse(char s[])”  tanımında bir fonksiyon yazın. Bu fonksiyona bir string geçirildiğinde, fonksiyonunuz kendisine geçirilmiş harfleri tersine çevirsin.
    Yani,  fonksiyonu çağırmadan önce  string’in içinde  “merhaba dünya” varsa, fonksiyondan dönünce string’in içinde artık  “aynüd abahrem” olsun.

Bir Sonraki Konu